Previous Balance on Invoice
Since this uses the same trick, I’m posting a code example here. As a warning, you have to know what you are doing if you use something outside the system recommendations.
Its not perfect, it just work for reference.
Change the Access Token/apikey, and FieldGuid with Text Custom Field UUID according to the Text Custom Field you are using.
<script>
document.addEventListener('DOMContentLoaded', () => {
const FieldGuid = "8ccdffdb-7181-4bd4-966e-782732904be2";
const apiKey = 'Cg5NYWlsamV0X1RoZW1lcxISCR1IANtvy3hOEZ2Icxvn5PoUGhIJw4GdNlGfBkQRqX1zeOUZesU=';
function updateCustomField(value) {
if (typeof app !== 'undefined' && app.CustomFields2 && app.CustomFields2.Strings) {
app.CustomFields2.Strings[FieldGuid] = value;
app.$forceUpdate();
}
}
function handleCustomerNameChange(newName) {
updateCustomField(null);
if (newName && newName.trim() !== '') {
const baseUrl = window.location.origin;
const apiUrl = `${baseUrl}/api2/customers?term=${encodeURIComponent(newName)}&fields=AccountsReceivable`;
fetch(apiUrl, {
headers: {
'accept': 'application/json',
'X-API-KEY': apiKey
}
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch data from the API.');
}
return response.json();
})
.then(apiData => {
if (apiData.customers && apiData.customers.length > 0) {
const customer = apiData.customers[0];
const accountsReceivable = customer.accountsReceivable;
if (accountsReceivable) {
const value = accountsReceivable.value;
const currencyCode = accountsReceivable.currency;
const formattedValue = formatCurrency(value, currencyCode);
if (value !== null && value !== 0) {
updateCustomField(formattedValue);
}
}
}
})
.catch(error => {
console.error('Error fetching or parsing API data:', error.message);
});
}
}
function formatCurrency(value, currencyCode) {
if (currencyCode) {
const formatter = new Intl.NumberFormat(undefined, {
style: 'currency',
currency: currencyCode,
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
return formatter.format(value);
} else {
const formatter = new Intl.NumberFormat(undefined, {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
return formatter.format(value);
}
}
const createButton = document.querySelector('button.btn.btn-primary[onclick="ajaxPost(true)"]');
if (createButton) {
const customerElement = document.getElementById('select2-chosen-2');
if (customerElement) {
handleCustomerNameChange(customerElement.textContent.trim());
};
const observer = new MutationObserver(mutationsList => {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
const newTextContent = mutation.target.textContent.trim();
handleCustomerNameChange(newTextContent);
}
}
});
const config = { childList: true, subtree: true };
observer.observe(customerElement, config);
}
});
</script>

