A tool to manage money transfers between a company and its locales in Popmundo.
// ==UserScript==
// @name Locale Money Manager
// @namespace Violentmonkey Scripts
// @match https://*.popmundo.com/World/Popmundo.aspx/Company/LocaleMoneyTransfer*
// @grant none
// @version 1.0
// @author drinkwater
// @description A tool to manage money transfers between a company and its locales in Popmundo.
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Aguarda o carregamento completo da página
jQuery(document).ready(function() {
// Variável global para armazenar os fundos disponíveis
let availableFunds = 0;
// Extrai os fundos disponíveis da div principal
const fundsText = jQuery("#ppm-content p:nth-of-type(2) strong").text();
if (fundsText) {
availableFunds = parseFloat(fundsText.replace(/[^\d,]/g, '').replace(',', '.'));
console.log("Fundos disponíveis:", availableFunds);
}
// Seleciona o elemento `tablelocales`
const tableLocales = jQuery("#tablelocales");
// Verifica se o elemento existe
if (tableLocales.length) {
// Cria a nova div com a classe `box`
const newDiv = jQuery("<div>").addClass("box");
// Adiciona a imagem no topo da nova div
// Adiciona o h2 dentro da nova div
const newH2 = jQuery("<h2>").text("Locale Money Manager");
newDiv.append(newH2);
const imageElement = jQuery("<p>").css("text-align", "center").html('<img src="https://i.imgur.com/bY04Hxo.png" width="100px" alt="Logo">');
newDiv.append(imageElement);
// Adiciona o parágrafo explicativo com melhorias
const hintParagraph = jQuery("<p>")
.html("<strong>Instruções:</strong> Utilize este campo para transferir dinheiro entre sua companhia e os locais controlados por ela. <br>"
+ "Digite um valor <strong>positivo</strong> para transferir dinheiro <strong>da companhia para os locais</strong>. <br>"
+ "Digite um valor <strong>negativo</strong> para transferir dinheiro <strong>dos locais para a companhia</strong>. <br>"
+ "Clique no botão <strong>Preencher</strong> para aplicar o valor a todos os locais listados abaixo. <br>"
+ "Caso o checkbox esteja marcado, o script ajustará automaticamente o valor máximo possível para os locais sem saldo suficiente.");
newDiv.append(hintParagraph);
// Adiciona o input number dentro da nova div com um atributo customizado
const inputNumber = jQuery("<input>")
.attr("type", "number")
.attr("min", "0")
.attr("placeholder", "Digite um valor inteiro")
.attr("class", "round width100px")
.attr("data-custom-input", "true"); // Atributo para diferenciá-lo
newDiv.append(inputNumber);
// Adiciona o botão de submit dentro da nova div
const inputSubmit = jQuery("<input>")
.attr("type", "button") // Altera para "button" para evitar envio de formulário
.attr("value", "Preencher")
.on("click", function(event) {
event.preventDefault();
const inputValue = parseFloat(inputNumber.val()) || 0;
// Validação de fundos totais
if (inputValue > 0 && availableFunds < inputValue * localeData.length) {
alert("Saldo insuficiente na companhia para esta operação.");
return;
}
// Validação de fundos individuais
if (inputValue < 0 && !jQuery("#removePartial").is(":checked")) {
const insufficientLocales = localeData.filter(locale => locale.moneyAvailable + inputValue < 0);
if (insufficientLocales.length > 0) {
alert("Os seguintes locais não possuem caixa suficiente para essa operação:\n" + insufficientLocales.map(locale => locale.localeName).join("\n"));
return;
}
}
// Preenche os valores nos inputs correspondentes
localeData.forEach(locale => {
if (jQuery("#removePartial").is(":checked") && inputValue < 0) {
const valueToFill = Math.min(Math.abs(inputValue), locale.moneyAvailable);
jQuery(`#${locale.inputId}`).val(-valueToFill);
} else {
jQuery(`#${locale.inputId}`).val(inputValue);
}
});
inputNumber.val(0);
});
newDiv.append(inputSubmit);
// Adiciona o checkbox com texto explicativo
const checkboxDiv = jQuery("<div>");
const inputCheckbox = jQuery("<input>")
.attr("type", "checkbox")
.attr("id", "removePartial");
const checkboxLabel = jQuery("<label>")
.attr("for", "removePartial")
.text(" Se não houver dinheiro suficiente no local, remover o disponível.");
checkboxDiv.append(inputCheckbox).append(checkboxLabel);
newDiv.append(checkboxDiv);
// Adiciona o parágrafo para exibir os fundos disponíveis e o saldo atualizado
const fundsParagraph = jQuery("<p>").html(`Projeção do caixa da CIA: <strong id="updatedFunds">${availableFunds.toLocaleString('pt-BR', { minimumFractionDigits: 2 })} M$</strong>`);
const warningMessage = jQuery("<span>")
.attr("id", "warningMessage")
.css({ color: "red", display: "none" })
.text(" - Você não terá dinheiro suficiente.");
fundsParagraph.append(warningMessage);
newDiv.append(fundsParagraph);
// Adiciona a lista para locais com caixa insuficiente
const insufficientFundsList = jQuery("<ul>").attr("id", "insufficientFundsList").css("color", "red");
newDiv.append(insufficientFundsList);
// Insere a nova div imediatamente acima do elemento `tablelocales`
tableLocales.before(newDiv);
// Extrai os dados da tabela
const localeData = [];
tableLocales.find("tbody tr").each(function() {
const row = jQuery(this);
const localeId = row.find("input[type='hidden']").val();
const localeName = row.find("td:first-child a").text();
const moneyAvailable = parseFloat(row.find("td:nth-child(2)").text().replace(/[^\d,]/g, '').replace(',', '.'));
const inputId = row.find("input[type='text']").attr("id");
localeData.push({
localeId: localeId,
localeName: localeName,
moneyAvailable: moneyAvailable,
inputId: inputId
});
});
console.log("Dados extraídos:", localeData);
// Atualiza os fundos disponíveis com base no valor digitado
inputNumber.on("input", function() {
const inputValue = parseFloat(inputNumber.val()) || 0;
const totalCost = inputValue * localeData.length;
const updatedFunds = availableFunds - totalCost;
const updatedFundsElement = jQuery("#updatedFunds");
const warningMessageElement = jQuery("#warningMessage");
const insufficientFundsListElement = jQuery("#insufficientFundsList");
updatedFundsElement.text(updatedFunds.toLocaleString('pt-BR', { minimumFractionDigits: 2 }) + " M$");
if (updatedFunds < 0) {
updatedFundsElement.css("color", "red");
warningMessageElement.show();
} else {
updatedFundsElement.css("color", "");
warningMessageElement.hide();
}
// Verifica os locais com caixa insuficiente
insufficientFundsListElement.empty();
if (inputValue < 0) {
localeData.forEach(locale => {
const projectedFunds = locale.moneyAvailable + inputValue;
if (projectedFunds < 0) {
insufficientFundsListElement.append(jQuery("<li>").text(`${locale.localeName} não terá caixa suficiente.`));
}
});
}
});
}
});
})();