devsli / ModulDengi Rate Helper

// ==UserScript==
// @name         ModulDengi Rate Helper
// @namespace    http://tampermonkey.net/
// @version      0.1.3
// @description  try to take over the world!
// @author       devsli
// @match        https://cabinet.moduldengi.ru/
// @grant        none
// @license      MIT
// @copyright    2018, devsli (https://openuserjs.org/users/devsli)
// @updateURL    https://openuserjs.org/meta/devsli/ModulDengi_Rate_Helper.meta.js
// ==/UserScript==

(function () {
  'use strict';

  // Source: https://raw.githubusercontent.com/werk85/fetch-intercept/develop/src/index.js
  // Uses Emscripten stategy for determining environment
  const ENVIRONMENT_IS_WEB = typeof window === 'object';
  const ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';

  if (ENVIRONMENT_IS_WORKER) {
    attach(self);
  }
  else if (ENVIRONMENT_IS_WEB) {
    attach(window);
  }
  else {
    throw new Error('Unsupported environment for fetch-intercept');
  }

  function attach(env) {
    // Make sure fetch is available in the given environment
    if (!env.fetch) {
      throw Error('No fetch available. Unable to register fetch-intercept');
    }
    env.fetch = (function (fetch) {
      return function (...args) {
        return interceptor(fetch, ...args);
      };
    })(env.fetch);
  }

  let interceptors = [];

  function interceptor(fetch, ...args) {
    const reversedInterceptors = interceptors.reduce((array, interceptor) => [interceptor].concat(array), []);
    let promise = Promise.resolve(args);

    // Register request interceptors
    reversedInterceptors.forEach(({
      request,
      requestError
    }) => {
      if (request || requestError) {
        promise = promise.then(args => request(...args), requestError);
      }
    });

    // Register fetch call
    promise = promise.then(args => fetch(...args));

    // Register response interceptors
    reversedInterceptors.forEach(({
      response,
      responseError
    }) => {
      if (response || responseError) {
        promise = promise.then(response, responseError);
      }
    });

    return promise;
  }

  const fetchIntercept = {
    register: function (interceptor) {
      interceptors.push(interceptor);
      return () => {
        const index = interceptors.indexOf(interceptor);
        if (index >= 0) {
          interceptors.splice(index, 1);
        }
      };
    },
    clear: function () {
      interceptors = [];
    }
  };
  // End of fetch-intercept

  const prc = (total, part) => (part * 100 / total).toFixed(0)

  const inspect = (response) => {
    const orig = response.clone();
    return response.json().then((project) => {
      if (Array.isArray(project)) {
        return orig;
      }

      const {
        contractAmount,
        loanRate,
        loanTerm,
        loanRaisedFunds,
        loanAmount,
        loanPublicUnderwriterComment,
      } = project;
      const thisRate = loanRate * loanTerm / 365; // Ignore the leap year
      const isActive = project.calcCommon.daysSpentNow > 0;
      const amount = (isActive) ? loanRaisedFunds : loanAmount;
      const returnAmount = amount * (1 + thisRate);
      const orgIncome = contractAmount - returnAmount;

      console.group(project.borrower.shortName + ' / ' + project.number);
      console.log('Сумма тендера   :', parseFloat(contractAmount).toFixed(2));
      console.log('Сумма к возврату:', returnAmount.toFixed(2), `(${prc(contractAmount, returnAmount)}%)`);
      console.log('Разница         :', orgIncome.toFixed(2), `(${prc(contractAmount, orgIncome)}%)`);
      console.groupEnd();

      project.loanPublicUnderwriterComment = loanPublicUnderwriterComment +
        ` (выгода: ${prc(contractAmount, orgIncome)}/${prc(contractAmount, returnAmount)}, ${orgIncome.toFixed(2)} руб)`;
      project.loanPrivateUnderwriterComment = project.loanPublicUnderwriterComment;
      return new Response(JSON.stringify(project), {
        type: orig.type,
        url: orig.url,
        headers: orig.headers
      });
    })
  }

  const unregister = fetchIntercept.register({
    response: function (response) {
      return (response.url.startsWith('https://cabinet.moduldengi.ru/api/projects/')) ? inspect(response) : response;
    },
  });
})();