adrianespidev / Vuelto en Shopify

// ==UserScript==
// @name         Vuelto en Shopify
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Calcula el vuelto en Shopify
// @author       Adrián Espinoza
// @match        https://lilo-beauty-ec.myshopify.com/admin*
// @exclude      https://lilo-beauty-ec.myshopify.com/admin/online-store*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        GM_addStyle
// @grant        window.onurlchange
// @license      GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// ==/UserScript==

const waitForElement = async (selector, timeout = 15000) => {
  const start = Date.now();
  while (Date.now() - start < timeout) {
    const el = document.querySelector(selector);
    if (el) {
      return el;
    }
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
  return null;
}

const decimalSeparator = '.';

let USDollar = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});

const realWindow = window;

(async function () {
  'use strict';
  GM_addStyle(`
       .custom-card {
             background: white;
             padding-top: 18px;
             border-top: 1px solid #dde0e4;
             margin: 0 -20px;
             padding-left: 20px;
             padding-right: 20px;
       }

       .custom-card h2 { font-weight: 600; }

       .custom-card .vuelto-line {
             display: flex;
             align-items: center;
             margin-top: 4px;
             justify-content: space-between;
       }

       #calcular-vuelto {
         border-radius: 4px;
         border: 1px solid #abb1ba;
         height: 32px;
         max-width: 60%;
         width: 100%;
         padding: 0 8px;
         outline: none !important;
         transition: all 0.2s ease-in;
       }

       #calcular-vuelto:active, #calcular-vuelto:focus {
         border-color: #000e24;
       }
    `);

  const perform = async () => {
    if (!!document.querySelector('#vuelto-total')) {
      return;
    }
    const selector = '#AppFrameMain > div > div > div:nth-child(2) > div > div > div:nth-child(1) > div.R72zb.ohDGk > div > div:nth-child(2)';

    const card = document.createElement('div');

    card.innerHTML = `
      <div class="custom-card">
        <h2>Calcular vuelto</h2>
        <div class="vuelto-line">
          <input id="calcular-vuelto" type="number" placeholder="Efectivo recibido"/>
          <div id="vuelto-total">-</div>
        </div>
      </div>
      `;

    const container = await waitForElement(selector);
    document.querySelector(selector).appendChild(card);

    const vueltoEl = document.querySelector('#vuelto-total');
    document.querySelector('#calcular-vuelto').addEventListener('keyup', (e) => {
      try {
        const vuelto = parseFloat(e.target.value);

        const totalSelector = '#AppFrameMain > div > div > div:nth-child(2) > div > div > div:nth-child(1) > div.R72zb.ohDGk > div > div:nth-child(2) > div:nth-child(5) > div.cMG3e > span';
        const totalStr = document.querySelector(totalSelector).innerText.replace('$', '').replace(',', decimalSeparator).replace('.', decimalSeparator);
        const total = parseFloat(totalStr);

        vueltoEl.innerText = `${USDollar.format(vuelto - total)}`;
      }
      catch (e) {

        console.error(e);
        vueltoEl.innerText = '-';
      }
    });
  }

  const setUrlChange = () => {
    if (window.onurlchange === null) {
      window.addEventListener('urlchange', async (info) => {
        if (info.url.includes("draft_orders/new")) {
          await perform();
        }
      });
    }
  }

  setUrlChange();
  if (window.location.pathname == '/admin/draft_orders/new') {
    await perform();
  }

})();