ANS-1607 · SUITESCRIPT DEVELOPMENT
How to Retrieve Time Entry Details from NetSuite Invoices using SuiteScript 2.x
Learn how to programmatically access linked time entry records from an invoice in NetSuite, leveraging SuiteScript 2.x for detailed data extraction.
Short answer
To retrieve time entry values from an invoice in NetSuite, use SuiteScript 2.x to load the invoice record and iterate through its 'timeitem' sublist. Extract the internal ID of each linked time entry from the appropriate field on the sublist. Once these IDs are obtained, individual time entry records can be loaded or searched to access all required details.
Scenario
NetSuite users often need to programmatically access the detailed information of time entries that are linked to a specific invoice. While direct reporting through saved searches can be complex for this specific linkage, retrieving this data is crucial for custom reporting, integrations, or advanced business logic. The challenge lies in identifying the correct sublist and field IDs to extract the time entry references from the invoice record.
Solution
Accessing time entry values from an invoice record in NetSuite primarily involves using SuiteScript 2.x to interact with the record's sublists. While direct access via saved searches for this specific linkage may require advanced techniques like SuiteQL or specific configurations, the most robust method involves scripting.
Identify the Time Entry Sublist and Field:
The sublist on an invoice that contains linked time entries is typically
timeitem. The field ID within this sublist that holds the internal ID of the time entry record needs to be verified using the NetSuite Records Browser or by inspecting the page source. For SuiteScript 1.0, this was oftendoc, but it may vary in SuiteScript 2.x implementations or custom configurations.Retrieve Time Entry IDs from an Invoice:
The time entry IDs can be retrieved either by loading the invoice record or by directly accessing line item values in a server-side or client-side script.
- Using
record.getSublistValue()(e.g., in a client script or user event script):
- Using
javascript
/**
* @NApiVersion 2.x
* @NModuleScope SameAccount
*/
define(['N/record'], function(record) {
function exampleFunction() {
// Assuming 'currentRecord' is available in client scripts or loaded in user event scripts
// For a client script, use currentRecord.get()
// For a user event script, use scriptContext.newRecord
var invoiceRecord = currentRecord.get(); // Or record.load('invoice', invoiceId);
var lineCount = invoiceRecord.getLineCount({ sublistId: 'timeitem' });
var timeEntryIds = [];
for (var i = 0; i < lineCount; i++) {
var timeEntryId = invoiceRecord.getSublistValue({
sublistId: 'timeitem',
fieldId: 'linkedtimeentryid', // Placeholder: Verify actual field ID in Records Browser
line: i
});
if (timeEntryId) {
timeEntryIds.push(timeEntryId);
}
}
log.debug('Time Entry IDs', timeEntryIds);
}
return {
// Expose functions as needed
};
});- Loading the Invoice Record with
record.load():
javascript
/**
* @NApiVersion 2.x
* @NModuleScope SameAccount
*/
define(['N/record'], function(record) {
function loadInvoiceAndGetTimeEntries(invoiceId) {
var invoiceRecord = record.load({
type: record.Type.INVOICE,
id: invoiceId,
isDynamic: false
});
var lineCount = invoiceRecord.getLineCount({ sublistId: 'timeitem' });
var timeEntryIds = [];
for (var i = 0; i < lineCount; i++) {
var timeEntryId = invoiceRecord.getSublistValue({
sublistId: 'timeitem',
fieldId: 'linkedtimeentryid', // Placeholder: Verify actual field ID in Records Browser
line: i
});
if (timeEntryId) {
timeEntryIds.push(timeEntryId);
}
}
log.debug('Time Entry IDs for Invoice ' + invoiceId, timeEntryIds);
return timeEntryIds;
}
return {
// Expose functions as needed
};
});Access Time Entry Details:
Once the internal IDs of the time entries are obtained, you can either load each individual time entry record (record type
timebill) to access its specific fields, or perform a search on thetimebillrecord type using an array of these internal IDs to retrieve multiple values efficiently.
javascript
/**
* @NApiVersion 2.x
* @NModuleScope SameAccount
*/
define(['N/record', 'N/search'], function(record, search) {
function getTimeEntryDetails(timeEntryIds) {
if (!timeEntryIds || timeEntryIds.length === 0) {
return [];
}
var timeEntrySearch = search.create({
type: record.Type.TIME_BILL, // 'timebill'
filters: [
['internalid', 'anyof', timeEntryIds]
],
columns: [
'employee',
'item',
'hours',
'memo'
// Add other desired columns from the time entry record
]
});
var results = [];
timeEntrySearch.run().each(function(result) {
results.push({
id: result.id,
employee: result.getText('employee'),
item: result.getText('item'),
hours: result.getValue('hours'),
memo: result.getValue('memo')
});
return true;
});
log.debug('Time Entry Details', results);
return results;
}
return {
// Expose functions as needed
};
});Expert NetSuite Support
Need help with this NetSuite issue?
SuiteScript Development consulting and configuration support
