Enhancing the management of billable expenses and items in project invoices, we’ve implemented key improvements in our billing system. This includes adding custom memo and original bill number fields to bill records, along with user event scripts for automation and editing restrictions.
Custom Fields for Clarity
Custom ‘memo’ and ‘original bill number’ fields have been added to the Expenses and Billable Items subtabs of bill records. These fields offer additional context and reference, aiding in better categorization and tracking of expenses and items.
Automated Data Population
A user event script, ‘JJ UE bill number original STERI-146,’ automatically populates these custom fields based on predefined rules. This reduces manual errors and enhances efficiency in data entry.
Editing Restrictions for Data Integrity
Another user event script, ‘JJ UE BILL RESTRICTION STERI 229,’ restricts editing of bill records once associated with an invoice. This ensures data integrity and consistency throughout the invoicing process, allowing editing only if the associated invoice is deleted.
Conclusion
These enhancements have significantly improved our ability to track and manage billable expenses and items in project invoices. The custom fields provide clarity, automation improves efficiency, and editing restrictions ensure data integrity, benefiting both our team and clients.
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/currentRecord', 'N/record', 'N/search'],
/**
* @param{currentRecord} currentRecord
* @param{record} record
* @param{search} search
*/
(currentRecord, record, search) => {
/**
* Defines the function definition that is executed before record is loaded.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord - New record
* @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
* @param {Form} scriptContext.form - Current form
* @param {ServletRequest} scriptContext.request - HTTP request information sent from the browser for a client action only.
* @since 2015.2
*/
const beforeLoad = (scriptContext) => {
if (scriptContext.type === scriptContext.UserEventType.EDIT) {
const billRecord = scriptContext.newRecord;
let subsidiary = billRecord.getValue({
fieldId: 'subsidiary'
});
log.debug("subsidiary: ",subsidiary);
if(subsidiary === "1" || subsidiary === "4" || subsidiary === "5" ){
var objSublist = billRecord.getSublistFields({
sublistId: 'reimbursements'
});
log.debug("sublist fields: ",objSublist);
let listLen =objSublist.length;
log.debug("listLen",listLen);
if(listLen != 0){
log.debug("Reimbursements has been created! LOCK THE RECORD");
//Items on this line have been reimbursed. If you modify it: you will change this bill, the item will no longer appear as a billable item on your reimbursement, and your reimbursement will be inaccurate. Are you sure you want to modify it?
// Cancel the edit operation
throw 'Items of this bill have been reimbursed.</br>Editing this record is not allowed.';
}
else{
log.debug("no reimbursements created!");
}
}
else{
//pass
log.debug("not steritek subsidiaries");
}
}
else{
log.debug("not edit mode");
}
}
/**
* Defines the function definition that is executed before record is submitted.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord - New record
* @param {Record} scriptContext.oldRecord - Old record
* @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
* @since 2015.2
*/
const beforeSubmit = (scriptContext) => {
}
/**
* Defines the function definition that is executed after record is submitted.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord - New record
* @param {Record} scriptContext.oldRecord - Old record
* @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
* @since 2015.2
*/
const afterSubmit = (scriptContext) => {
}
return {beforeLoad, beforeSubmit, afterSubmit}
});