Added Created Date, Created By & Prev Balance to Transaction

I got the idea from this thread, and I also need information on when Transactions are Created.
Possible to Add TIme stamp on Sale quotes and Invoices? - Manager Forum

Maybe other members also need this, you can try like I did.

The first step is to create a Text Custom Field, select Placement, Checklist Show custom field on printed documents, if you want to display it in Transaction View, and [Create]

Next, Edit the Custom Field, to get the Name and GUID, and modify the script according to the Name and Guid in your Custom Field.
Copy/paste Edited Script to Description field and [Update]

Activate Custom Field Column in Transaction Tabs. Try Create new Transaction and [Create]. you should get the Created Date created automatically.

<div id="DateCreated" style="display: none;">
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const FieldGuid = "82c3d843-2aaa-419e-8802-7a9b4870d676";
            const labelText = 'Date Created';

            const createButton = document.querySelector('button.btn.btn-primary[onclick="ajaxPost(true)"]');
            if (createButton) {
                if (typeof app !== 'undefined' && app.CustomFields2 && app.CustomFields2.Strings) {
                    //const customField = app.CustomFields2.Strings[FieldGuid];
                    //if (!customField || customField.trim() === '') {
                        const now = new Date();
                        const localDatetime = new Date(now.getTime() - (now.getTimezoneOffset() * 60000));
                        const currentDateTime = localDatetime.toISOString().slice(0, 19).replace('T', ' ');
                        app.CustomFields2.Strings[FieldGuid] = currentDateTime;
                    //}
                }
            }

			const vModelForm = document.getElementById('v-model-form');
			if (vModelForm) {
				const labels = vModelForm.querySelectorAll('label');
				labels.forEach(label => {
					if (label.textContent.trim() === labelText) {
						const formGroup = label.closest('.form-group');
						if (formGroup) {
							formGroup.style.display = 'none';
						}
					}
				});
			}
			
            const selfDeletingContainer = document.getElementById('DateCreated');
            if (selfDeletingContainer) {
                selfDeletingContainer.remove();
            }
        });
    </script>
</div>

</script>
6 Likes

Add user information to it that can help some people too. Date – User

Great idea, we will need this on Printed Invoice.
but it would be better if we created a separate CustomField from the Date.

In the same way as the previous script, this script runs well.

<div id="CreatedBy" style="display: none;">
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const FieldGuid = "e5992a93-808e-4d3b-a7ab-fd93f6f17185";
            const labelText = 'Created By';

            const createButton = document.querySelector('button.btn.btn-primary[onclick="ajaxPost(true)"]');
            if (createButton) {
                const userLink = document.querySelector('a[href="/change-password-form"]');
                let createdBy = 'Administrator';
                if (userLink) {
                    const userName = userLink.textContent.trim();
                    const startIndex = userName.indexOf(' ') + 1;
                    createdBy = userName.substring(startIndex);
                }

                if (typeof app !== 'undefined' && app.CustomFields2 && app.CustomFields2.Strings) {
                    //const customField = app.CustomFields2.Strings[FieldGuid];
                    //if (!customField || customField.trim() === '') {
                        app.CustomFields2.Strings[FieldGuid] = createdBy;
                    //}
                }
            }
			
			const vModelForm = document.getElementById('v-model-form');
			if (vModelForm) {
				const labels = vModelForm.querySelectorAll('label');
				labels.forEach(label => {
					if (label.textContent.trim() === labelText) {
						const formGroup = label.closest('.form-group');
						if (formGroup) {
							formGroup.style.display = 'none';
							formGroup.style.readonly = true;
						}
					}
				});
			}

            const CreatedByDiv = document.getElementById('CreatedBy');
            if (CreatedByDiv) {
                CreatedByDiv.remove();
            }
        });
    </script>
</div>

5 Likes

hello guys,
kindly help me this scrip - I tried to do it myself but it did not work for me. I can’t see the user name who created the transaction. I strictly followed the instructions of @Mabaega.

Which one are you referring to? Created by wont work on Desktop edition.

Am reffering to the Cloud Edition

Should work on Cloud and Server edition. Maybe you missed something.

1 Like

You can add the Default Name you want to this line

let createdBy = 'DEFAULT_NAME';

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>

3 Likes

The first two scripts you provided seem to be working fine for me. However, I made some changes to the third one, as follows:

const FieldGuid = "";
const apiKey = '';

After these adjustments, the CustomField still appeared in the invoice as expected.

It seems like the changes didn’t affect the functionality of the script, and the CustomField is still being displayed properly in the invoice.

This script only work for new Invoice. Api will called when we select Customer.

1 Like

Yes, I have created a new invoice.
image

image

@Mabaega , I added this to my script and still it didn’t work. What do you think is wrong with me.
Respect.

Copy your script here in full.

1 Like

Removed (319.2 KB)

@eko, i was unable to past the script here, rather I uploaded a pdf.
Moreover, I am not a professional programmer; merely i copied @Mabaega script and only included this line: let createdBy = ‘DEFAULT_NAME’; to the old script and nothing works.
Respect.

Please PDF files are not allowed. It is easy to paste the code. Just select all the code you used and paste it in the post. mark it all and click on </> button above.

The script works fine on Desktop and Server (I do not have Cloud) so it is essential to show the code you used and also screenshots about what you did and where do you think it goes wrong. This has nothing to do with being a professional programmer or not. For those that try to assist you it is essential that you provide all the essential information so that it can be analyzed and resolved.

const FieldGuid = "e4a76786-99a0-4d13-8e22-e42b5e336cb7
";

should be

const FieldGuid = "e4a76786-99a0-4d13-8e22-e42b5e336cb7";

this is double, remove 1 line

let createdBy = 'DEFAULT_NAME';
 let createdBy = '';

Or you can ask ChatGPT to check what wrong with your code/script and to explain what code/script do.
all my code/script is from ChatGPT.

@Burhania, I have removed the pdf file since those can possibly run malicious code and the forum cannot take resposibility for ensuring their safety.

Please take the time to copy and paste the script text and paste it in between these:

```

Place your code here

```

1 Like