var submitted = false; var pricingdata = null; var _pricingIsLoading = false; function isPricingLoading() { return _pricingIsLoading; } function setPricingIsLoading(state) { _pricingIsLoading = !!state; var loader = document.getElementById("pricingloader"); if (loader) { loader.style = _pricingIsLoading ? "display: block;" : "display: none;" } } function loadPricingData() { var xmlhttp = new XMLHttpRequest(); var url = "/assets/calculator/pricing.json"; xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4) { setPricingIsLoading(false); if (xmlhttp.status == 200) { var spacedata = JSON.parse(xmlhttp.responseText); pricingdata = processData(spacedata); } } } setPricingIsLoading(true); xmlhttp.open("GET", url, true); xmlhttp.send(); } function validateForm(slotlength, week1, week2, week3, previewwanted) { var valid = true; var weekcount = week1 + week2 + week3; if (slotlength < 60) { valid = false; } if (weekcount == 0) { valid = false; setResultVisible(false); document.getElementById("frmweek1").classList.add("is-invalid") document.getElementById("frmweek2").classList.add("is-invalid") document.getElementById("frmweek3").classList.add("is-invalid") } else { document.getElementById("frmweek1").classList.remove("is-invalid") document.getElementById("frmweek2").classList.remove("is-invalid") document.getElementById("frmweek3").classList.remove("is-invalid") } if (previewwanted && !week1) { valid = false; } else { } return valid; } function slotFee(spacedata, slotstart, duration, week1, week2, week3) { var fee = 0.0; var minsleft = duration; fee = spacedata['prices'].reduce(function (acc, pricing) { console.log(acc, pricing); if (slotstart < pricing['end'] && minsleft) { console.log('Adding Stuff'); var pricinglen = pricing['end'] - pricing['start']; var startoffset = (pricing['start'] < slotstart) ? slotstart - pricing['start'] : 0; var minsrequired = (startoffset + minsleft > pricinglen) ? pricinglen - startoffset : minsleft; var hourlyrate = (week1 ? pricing['Week1'] : 0.0) + (week2 ? pricing['Week2'] : 0.0) + (week3 ? pricing['Week3'] : 0.0); console.log(slotstart, pricing['start'], pricinglen, startoffset, minsrequired, hourlyrate); acc = acc + (hourlyrate * minsrequired / 60); minsleft = minsleft - minsrequired; console.log(minsleft); } return acc; }, fee); return fee; } function estimateFee() { if (!pricingdata) { return false; } var perfspace = document.getElementById("frmspace").value; var performanceduration = parseInt(document.getElementById("frmperformanceduration").value, 10); // var getinduration = parseInt(document.getElementById("frmgetinduration").value, 10); // var getoutduration = parseInt(document.getElementById("frmgetoutduration").value, 10); // Take minimum in and out times from the space var getinduration = pricingdata[perfspace].min_getin var getoutduration = pricingdata[perfspace].min_getout var duration = performanceduration + getinduration + getoutduration; var showstartstr = document.getElementById("frmtime").value; var showstart = decodeTime(showstartstr); var slotstart = showstart - getinduration; var showend = showstart + performanceduration; var showendhrs = Math.floor(showend / 60); var showendmins = showend - (60 * showendhrs); // We do this now so that the minutes calculation is correct. if (showendhrs > 23) { showendhrs = showendhrs - 24; } var showendstr = (showendhrs < 10 ? '0' : '') + showendhrs + ':' + (showendmins < 10 ? '0' : '') + showendmins; var week1 = document.getElementById("frmweek1").checked; var week2 = document.getElementById("frmweek2").checked; var week3 = document.getElementById("frmweek3").checked; var weekcount = week1 + week2 + week3; var previewwanted = document.getElementById("frmpreview").checked; if (validateForm(duration, week1, week2, week3, previewwanted)) { var fee = slotFee(pricingdata[perfspace], slotstart, duration, week1, week2, week3); var discount = calculatediscount(weekcount); var previewfee = previewcost(perfspace, duration, previewwanted); displayFee(perfspace, week1, week2, week3, showstartstr, showendstr, getinduration, getoutduration, fee, discount, previewfee) return true; } else { return false; } } function displayFee(perfspace, week1, week2, week3, showstart, showend, getinduration, getoutduration, fee, discount, previewfee) { var weekcount = week1 + week2 + week3; //output performance space document.getElementById("performance-space3").innerHTML = perfspace; //output performance times (some hackery to pad hours/minutes with zeroes!) document.getElementById("performancestart").innerHTML = showstart; document.getElementById("performanceend").innerHTML = showend; //output get-in/-out durations document.getElementById("get-induration").innerHTML = getinduration; document.getElementById("get-outduration").innerHTML = getoutduration; //output details of weeks document.getElementById("weekcount").innerHTML = weekcount; document.getElementById("weeklist").innerHTML = weeklist(week1, week2, week3); //do some voodoo to ensure that plurals are consistent if (weekcount == 1) { document.getElementById("weekorweeks1").innerHTML = "week"; document.getElementById("weekorweeks2").innerHTML = "week"; } else { document.getElementById("weekorweeks1").innerHTML = "weeks"; document.getElementById("weekorweeks2").innerHTML = "weeks"; } if (previewfee > 0) //if we're having a preview, display it { document.getElementById("previewassumption").style.display = "list-item"; document.getElementById("previewassumption").innerHTML = "You will be staging a preview performance on the Friday before Week 1 begins." document.getElementById("previewfee").style.display = "list-item"; document.getElementById("previewamount").innerHTML = "£" + previewfee.toFixed(0); } else //if not, hide it { document.getElementById("previewassumption").style.display = "none" document.getElementById("previewassumption").innerHTML = "You will not be staging a preview performance on the Friday before Week 1 begins." document.getElementById("previewfee").style.display = "none"; document.getElementById("previewamount").innerHTML = "£0.00"; } //output the slotfee document.getElementById("slotamount").innerHTML = "£" + fee.toFixed(0); if (discount > 0) //if a discount applies, display it { document.getElementById("discountpercent").innerHTML = discount; var discountamount = discount / 100.0 * fee document.getElementById("discountamount").innerHTML = "-£" + discountamount.toFixed(0); document.getElementById("discount").style.display = "list-item" } else //if not, hide it. { document.getElementById("discountpercent").innerHTML = 0; document.getElementById("discountamount").innerHTML = 0.00; document.getElementById("discountamount").innerHTML = "-£0.00"; document.getElementById("discount").style.display = "none" } //output total fee var totalfee = fee - (discount / 100.0 * fee) + previewfee document.getElementById("totalamount").innerHTML = "£" + totalfee.toFixed(0); setResultVisible(true); } function setResultVisible(visible) { document.getElementById("fee").style.display = visible ? "block" : "none" document.getElementById("breakdown").style.display = visible ? "block" : "none" document.getElementById("getestimatebutton").style.display = visible ? "none" : "block" // If we're setting not visible (invalid) then undo the submit state submitted = visible } function weeklist(week1, week2, week3) { var weekarray = []; if (week1) weekarray.push("1"); if (week2) weekarray.push("2"); if (week3) weekarray.push("3"); if (weekarray.length == 1) return weekarray[0]; else if (weekarray.length == 2) return weekarray[0] + " & " + weekarray[1]; else return weekarray[0] + ", " + weekarray[1] + " & " + weekarray[2]; } function previewcost(perfspace, showduration, previewwanted) { // pricing data will be set by the time this is called. if (previewwanted && pricingdata[perfspace] && pricingdata[perfspace]['previews']) { console.log(perfspace, pricingdata[perfspace]['previews'], showduration, pricingdata[perfspace]['previews'] * showduration / 60); // Per hour return pricingdata[perfspace]['previews'] * showduration / 60; //2023: Previews are fixed cost and not per hour //return pricingdata[perfspace]['previews']; } return 0.0; //no preview or bad venue! } function calculatediscount(weekcount) { if (weekcount == 2) //5% discount for 2-week runs return 5; else if (weekcount == 3) //10% discount for 3-week runs return 10; else //no discount for 1-week run return 0; } function formchanged() { if (submitted) { if (pricingdata) { estimateFee(); } else if (!isPricingLoading()) { loadPricingData(); } // If the data is loading it will calculate when it completes because submitted is set. } } function submitclicked() { submitted = true; formchanged(); // var loc = window.location; // if (!loc.hash) { // loc.hash = 'estimate'; // window.location.replace(loc); // } } function setSelectedOption(el, value) { for (var i = 0; i < el.options.length; i++) { el.options[i].selected = (el.options[i].value == value); } } function decodeTime(timestr) { var parts = timestr.split(':'); var hours = parseInt(parts[0], 10); var mins = parseInt(parts[1], 10); // Handle entries set for :59 if (mins == 59) { mins = 0; hours = hours + 1; } // Handle fringe time if (hours < 6) { hours = hours + 24; } var offsetmins = (hours * 60) + mins; return offsetmins; } function processData(spacedata) { var processed = {}; for (var space in spacedata) { processed[space] = { 'previews': spacedata[space]['previews'], 'min_getin': spacedata[space]['min_getin'], 'min_getout': spacedata[space]['min_getout'], 'prices': [] } for (var index in spacedata[space]['prices']) { var priceinfo = spacedata[space]['prices'][index]; pricedata = {} for (var pricekey in priceinfo) { pricedata[pricekey] = priceinfo[pricekey]; } // Decoding the start and end to minutes past midnight makes checks easy pricedata['start'] = decodeTime(priceinfo['BlockStart']); pricedata['end'] = decodeTime(priceinfo['BlockEnd']); processed[space]['prices'].push(pricedata); } processed[space]['prices'].sort(function (a, b) { return a.start - b.start; }); // This resets the first entry to the start of the day processed[space]['prices'][0]['start'] = 0; // This resets the last entry to the end of the day processed[space]['prices'][processed[space]['prices'].length - 1]['end'] = (24 + 6) * 60; } return processed; } function checkPreviewState() { if (document.getElementById("frmweek1").checked == true) { // If week 1 is ticked, enable the preview option document.getElementById("frmpreview").disabled = false } else { // Otherwise disable and clear it document.getElementById("frmpreview").disabled = true document.getElementById("frmpreview").checked = false formchanged(); } } loadPricingData();