noahzark / Starpoints per Dollar

// ==UserScript==
// @name         Starpoints per Dollar
// @version      1.4
// @updateURL    https://openuserjs.org/meta/noahzark/Starpoints_per_Dollar.meta.js
// @description  calculates the value of starpoints when redeeming to free nights, yellow suggests to redeem and green suggests to use cash
// @author       Feliciano Long
// @match        *://www.starwoodhotels.com/preferredguest/search/results/detail.html*
// @match        *://www.marriott.com/search/*
// @match        *://www.marriott.com/reservation/*
// @match        *://www.marriott.com.cn/search/*
// @match        *://www.marriott.com.cn/reservation/*
// @run-at       document-end
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
  'use strict';

  var tax_and_fee = 1;

  var marriot_redemption_chart = [
    1, // Handles error
    7500, // Cat1
    12500, // Cat2
    17500, // Cat3
    25000, // Cat4
    35000, // Cat5
    50000, // Cat6
    60000, // Cat7
    85000 // Cat8
  ];

  const buy_points_rate = 437.5 * 100 / 50000;

  function isNull(A) {
    if (A === null || typeof A == 'undefined') {
      A = "";
    }
    return (A.length === 0);
  }

  function getRatio(price, points, currency) {
    var ratio = (price * tax_and_fee / currency / points * 100).toPrecision(5)
    console.log(price * tax_and_fee / currency + " : " + points + " = " + ratio);
    return ratio;
  }

  function getValueColor(ratio, scale) {
    var color = (ratio > buy_points_rate / scale) ? "orange" : "red";
    color = (ratio < 0.4 / scale) ? "green" : color;
    return color;
  }

  window.addEventListener('load', function () {
    var dollars;
    var ratio;
    var color;
    var i;
    var rewardpoints;

    console.log("Page loaded.");
    var brand = '';
    if (location.href.indexOf('/search/') > -1) {
      console.log("Analyzing Marriot Prices");
      var marriott_entries = $('.rate-block.with-points');
      console.log("found " + marriott_entries.length + " marriott entries");
      if (marriott_entries !== null) {
        // Load the nights of this stay
        var nights_html = $(".l-stay-dates")[0].getElementsByClassName("label")[0].innerHTML.replace(/\D/g, "");
        var nights = isNull(nights_html) ? 1 : parseInt(nights_html);

        for (i = 0; i < marriott_entries.length; i++) {
          var price = marriott_entries[i].getElementsByClassName("t-price")[0];
          var currencyExchange = marriott_entries[i].getElementsByClassName("t-font-weight-bold")[0].innerText;
          console.log("currency:" + currencyExchange);
          if (currencyExchange.indexOf('CNY') > -1) {
            currencyExchange = 6.7;
          }
          else if (currencyExchange.indexOf('HKD') > -1) {
            currencyExchange = 7.85;
          }
          else {
            currencyExchange = 1;
          }
          var rewardpoint = marriott_entries[i].getElementsByClassName("t-points")[0];

          // Load adjusted points
          rewardpoint = isNull(rewardpoint) ? marriott_entries[i].getElementsByClassName("l-rewards-points")[0] : rewardpoint;

          if (isNull(price) || isNull(rewardpoint)) {
            console.log("No." + i + " is not valid");
            continue;
          }

          console.log(price.innerHTML + " " + rewardpoint.innerHTML);

          ratio = getRatio(parseInt(price.innerHTML.replace(/,/g, '')), parseInt(rewardpoint.innerHTML.replace(/,/g, '')) * 1.0 / nights, currencyExchange);
          console.log(dollars + " : " + rewardpoints + " = " + ratio);

          color = getValueColor(ratio, 1);
          var node = document.createElement("span");
          node.style = "color:" + (color) + "; font-weight:bold\"";
          var textnode = document.createTextNode(ratio + " c/p");
          node.appendChild(textnode);
          marriott_entries[i].appendChild(node);
        }
      }
    }
    else if (location.href.indexOf('/reservation/') > -1) {
      var catLink = $("a.t-line-height-m.t-color-brand.t-font-s.t-color-brand")[1].href;
      const regex = /category=(\d)/gm;
      let m = regex.exec(catLink);
      var cat = parseInt(m[1]);
      if (cat > 0) {
        console.log("category: " + cat);

        rewardpoints = marriot_redemption_chart[cat];
        var calendar_etnries = $(".t-rate.l-s-text-align-right.l-l-text-align-center.t-color-black.l-margin-none.l-float-right.l-l-float-none");

        for (i = 0; i < calendar_etnries.length; i++) {
          dollars = calendar_etnries[i].getElementsByClassName("t-font-l")[0];
          if (isNull(dollars)) {
            console.log("No." + i + " is not valid");
            continue;
          }

          ratio = getRatio(parseInt(dollars.innerHTML.replace(/,/g, '')), rewardpoints, 1);

          color = getValueColor(ratio, 3);
          var appendHtml = "<a style=\"color:" + (color) + "; font-weight:bold\">" + ratio + " c/p</a>";
          calendar_etnries[i].innerHTML += appendHtml;
        }
      }
    }
  });
})();