From 267cb93ff3628cf2ede23331536bdba4d4f06ad7 Mon Sep 17 00:00:00 2001 From: K2 Date: Sun, 2 Feb 2025 12:37:32 -0800 Subject: [PATCH] Add additional confirmation to link price changes and airplane purchase for significant changes --- airline-web/public/javascripts/airline.js | 45 ++++++++++++++++++++-- airline-web/public/javascripts/airplane.js | 20 +++++++++- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/airline-web/public/javascripts/airline.js b/airline-web/public/javascripts/airline.js index 4b80e4e98..12fe63807 100644 --- a/airline-web/public/javascripts/airline.js +++ b/airline-web/public/javascripts/airline.js @@ -2590,6 +2590,13 @@ function updateAirlineBaseList(airlineId, table) { }); } +// A 'x' percent change in price is considered to be 'significant' and trigger additional confirmation. +var SIGNIFICANT_PRICE_THRESHOLD_PERCENT = 50; + +function calculatePercentChange(existingValue, newValue){ + return Math.abs(newValue - existingValue) / existingValue * 100; +} + var assignedDelegates = 0 var availableDelegates = 0 var negotiationOddsLookup @@ -2655,6 +2662,7 @@ function linkConfirmation() { var planInfo = getPlanLinkCapacity() var planFrequency = planInfo.future ? planInfo.future.frequency : planInfo.current.frequency + for (i = 0 ; i < planFrequency ; i ++) { var image = $("") image.attr("src", $(".frequencyBar").data("fillIcon")) @@ -2671,10 +2679,41 @@ function linkConfirmation() { $("#linkConfirmationModal div.updating.capacity").append(futureCapacitySpan) } + const futurePrices = { + economy: parseInt($("#planLinkEconomyPrice").val()), + business: parseInt($("#planLinkBusinessPrice").val()), + first: parseInt($("#planLinkFirstPrice").val()) + }; + + const fareClasses = ["economy", "business", "first"]; + var significantChanges = []; + + if (existingLink) { + fareClasses.forEach((fareClass) => { + const existingPrice = existingLink.price[fareClass]; + const futurePrice = futurePrices[fareClass]; + + const percentChange = calculatePercentChange(existingPrice, futurePrice); + if (percentChange >= SIGNIFICANT_PRICE_THRESHOLD_PERCENT) { + significantChanges.push(`${fareClass.charAt(0).toUpperCase() + fareClass.slice(1)}: $${existingPrice} -> $${futurePrice}`); + } + }); + } + + $('#linkConfirmationModal .confirmButton').off('click'); + if (significantChanges.length > 0) { + const confirmationPromptMessage = `≥${SIGNIFICANT_PRICE_THRESHOLD_PERCENT}% price change${significantChanges.length > 1 ? "s" : ""} detected:`; + $('#linkConfirmationModal .confirmButton').on('click', function() { + promptConfirm(confirmationPromptMessage, createLink); + closeModal($('#linkConfirmationModal')); + }); + } else { + $('#linkConfirmationModal .confirmButton').on('click', function() { + createLink() + }); + } - - $('#linkConfirmationModal div.updating.price').text('$' + $('#planLinkEconomyPrice').val() + " / $" + $('#planLinkBusinessPrice').val() + " / $" + $('#planLinkFirstPrice').val()) - + $('#linkConfirmationModal div.updating.price').text(toLinkClassValueString(futurePrices, '$')); $('#linkConfirmationModal').fadeIn(200) getLinkNegotiation() diff --git a/airline-web/public/javascripts/airplane.js b/airline-web/public/javascripts/airplane.js index 1256986de..907a0e461 100644 --- a/airline-web/public/javascripts/airplane.js +++ b/airline-web/public/javascripts/airplane.js @@ -267,6 +267,9 @@ function validateAirplaneQuantity() { return quantity } +// Threshold for determining if additional confirmation is required before completing an airplane purchase. +var SIGNIFICANT_AIRPLANE_PURCHASE_THRESHOLD = 0.5; + function promptBuyAirplane(modelId, condition, price, deliveryTime, explicitHomeAirportId, multipleAble, buyAirplaneFunction) { var model = loadedModelsById[modelId] if (model.imageUrl) { @@ -293,10 +296,11 @@ function promptBuyAirplane(modelId, condition, price, deliveryTime, explicitHome $('#buyAirplaneModal .price').text("$" + commaSeparateNumber(price)) $('#buyAirplaneModal .condition').text(condition + "%") + var quantity = 1; if (multipleAble) { $('#buyAirplaneModal .quantity .input').val(1) $('#buyAirplaneModal .quantity .input').on('input', function(e){ - var quantity = validateAirplaneQuantity() + quantity = validateAirplaneQuantity() updateAirplaneTotalPrice(quantity * price) }); $('#buyAirplaneModal .quantity').show() @@ -389,7 +393,19 @@ function promptBuyAirplane(modelId, condition, price, deliveryTime, explicitHome selectedConfigurationId = $($("#buyAirplaneModal .configuration-options").children()[selectedIndex]).data("configurationId") } - buyAirplaneFunction($('#buyAirplaneModal .quantity .input').val(), $("#buyAirplaneModal .homeOptions").find(":selected").val(), selectedConfigurationId) + var homeAirportId = $("#buyAirplaneModal .homeOptions").find(":selected").val(); + + const totalPrice = quantity * price; + var percentOfBalance = totalPrice / activeAirline.balance; + if (percentOfBalance >= SIGNIFICANT_AIRPLANE_PURCHASE_THRESHOLD) { + var confirmationMessage = `This purchase accounts for ${(percentOfBalance * 100).toFixed(1)}% of your airline's current balance. Are you sure you want to proceed?`; + + promptConfirm(confirmationMessage, function() { + buyAirplaneFunction(quantity, homeAirportId, selectedConfigurationId); + }); + } else { + buyAirplaneFunction(quantity, homeAirportId, selectedConfigurationId); + } }) $('#buyAirplaneModal').fadeIn(200) },