Sim Greenbaum
12/31/2024, 4:33 PM/**
* @NApiVersion 2.1
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
define(["N/query"], function (query) {
let cachedLocations = null; // Global cache for active locations
function pageInit(scriptContext) {}
function getActiveLocations() {
if (!cachedLocations) {
let subSql = `SELECT
id,
name,
isinactive
FROM
location
WHERE
isinactive = 'F'`;
var mySuiteQLQuery = query.runSuiteQL(subSql);
cachedLocations = mySuiteQLQuery.asMappedResults();
/// an array of objects
}
return cachedLocations;
}
function getLocationNameById(idData) {
let id = parseInt(idData);
const locations = getActiveLocations();
const location = locations.find((loc) => loc.id === id); // Find by ID
return location ? location.name : null; // Return name or null
}
function clearCache() {
cachedLocations = null;
}
return {
pageInit: pageInit,
getActiveLocations: getActiveLocations,
getLocationNameById: getLocationNameById,
clearCache: clearCache,
};
});
erictgrubaugh
12/31/2024, 4:35 PMcachedLocations
is just a local variable. It will not persist across Scripts. You might look into N/cache
for thatSim Greenbaum
12/31/2024, 4:35 PMSim Greenbaum
12/31/2024, 4:37 PMlet locationArray =getActiveLocations()
getLocationNameById(idData, locationArray)
erictgrubaugh
12/31/2024, 4:38 PMgetActiveLocations()
outside an entry pointSim Greenbaum
12/31/2024, 4:39 PMerictgrubaugh
12/31/2024, 4:41 PMlocationArray
"at the top of the script" because it would try to run a query as soon as the module is loaded into memory, and you can't use NetSuite modules yet at that point of execution. I'm assuming "at the top of the script" here means "the first thing in the module", but perhaps you're saying it's "the first thing in the afterSubmit
function"erictgrubaugh
12/31/2024, 4:42 PMSim Greenbaum
12/31/2024, 4:44 PMSim Greenbaum
12/31/2024, 4:44 PMSim Greenbaum
12/31/2024, 4:44 PMerictgrubaugh
12/31/2024, 4:45 PMcachedLocations
should be much faster than re-running a query, especially re-running it 100 timeserictgrubaugh
12/31/2024, 4:47 PMN/cache
Anthony OConnor
12/31/2024, 4:48 PMerictgrubaugh
12/31/2024, 4:49 PMAnthony OConnor
12/31/2024, 4:49 PMSim Greenbaum
12/31/2024, 4:51 PMAnthony OConnor
12/31/2024, 4:51 PMAnthony OConnor
12/31/2024, 4:52 PMn/cache
will really shineAnthony OConnor
12/31/2024, 4:52 PMSim Greenbaum
12/31/2024, 4:55 PMfunction getActiveLocations() {
// Get cache instance
const locationCache = cache.getCache({
name: 'LocationCache',
scope: cache.Scope.PROTECTED, // Adjust scope if needed (PRIVATE, PROTECTED, PUBLIC)
});
// Attempt to retrieve cached locations
let cachedLocations = locationCache.get({ key: CACHE_KEY });
if (cachedLocations) {
// Parse cached JSON back into an object
return JSON.parse(cachedLocations);
}
// Query SuiteQL for active locations
const subSql = `SELECT
id,
name,
isinactive
FROM
location
WHERE
isinactive = 'F'`;
const mySuiteQLQuery = query.runSuiteQL(subSql);
const locations = mySuiteQLQuery.asMappedResults(); // Array of objects
// Cache the results as a JSON string
locationCache.put({
key: CACHE_KEY,
value: JSON.stringify(locations),
ttl: CACHE_DURATION,
});
return locations;
}
Anthony OConnor
12/31/2024, 4:56 PMn/modulename
modules
then you call the lib function to populate your variable once at the top of the script before you do your line loopAnthony OConnor
12/31/2024, 4:58 PMSim Greenbaum
12/31/2024, 4:58 PMlet locationtxt = locationData.getLocationNameById(item.location);
Anthony OConnor
12/31/2024, 5:00 PMlocationData[item.location]
just an object key to get the valueSim Greenbaum
12/31/2024, 5:01 PMAnthony OConnor
12/31/2024, 5:01 PMAnthony OConnor
12/31/2024, 5:02 PMAnthony OConnor
12/31/2024, 5:02 PMn/cache
is confusing the first few times you use itAnthony OConnor
12/31/2024, 5:02 PMerictgrubaugh
12/31/2024, 5:03 PMlocationCache.get()
call should also specify a loader
function, which is where you'll put the query codeerictgrubaugh
12/31/2024, 5:03 PMSim Greenbaum
12/31/2024, 5:05 PMAnthony OConnor
12/31/2024, 5:05 PM//accounting periods query function
const getAccountingPeriods = () => {
let myQuery = query.create({
type: query.Type.ACCOUNTING_PERIOD
});
myQuery.condition = myQuery.and(
myQuery.createCondition({fieldId: 'isyear', operator: 'IS', values: [false]}),
myQuery.createCondition({fieldId: 'isquarter', operator: 'IS', values: [false]})
);
myQuery.columns = [
myQuery.createColumn({fieldId: 'id', context: query.FieldContext.RAW}),
myQuery.createColumn({fieldId: 'periodname', context: query.FieldContext.RAW}),
myQuery.createColumn({fieldId: 'startdate', context: query.FieldContext.RAW}),
myQuery.createColumn({fieldId: 'enddate', context: query.FieldContext.RAW}),
myQuery.createColumn({fieldId: 'closed', alias:'isClosed', context: query.FieldContext.RAW})
];
myQuery.sort = [
myQuery.createSort({
column: myQuery.columns[2],
ascending: true
}),
];
let accountingPeriods = [];
let resultSet = myQuery.runPaged({pageSize:1000}); // gov cost 10
for (let i = 0; i < resultSet.pageRanges.length; i++) {
let thisPage = resultSet.fetch({ index: i });
accountingPeriods = accountingPeriods.concat(thisPage.data.asMappedResults());
}
return accountingPeriods;
}
Anthony OConnor
12/31/2024, 5:06 PM//cache function
const getPeriods2 = ({ start, end }) => {
let returnVal = [];
let crCache = cache.getCache({
name: CR_CACHE,
scope: cache.Scope.PUBLIC
});
let accountingPeriods = crCache.get({ // gov cost 1 or 2
key: CacheKeys.ACCOUNTING_PERIODS,
loader: getAccountingPeriods
});
if (typeof accountingPeriods === 'string') accountingPeriods = JSON.parse(accountingPeriods);
let first = 0
let last = 0;
for (let i = 0; i<accountingPeriods.length; i++){
const cacheStart = new Date(accountingPeriods[i].startdate);
const cacheEnd = new Date(accountingPeriods[i].enddate);
if ( cacheStart.valueOf() === start.valueOf() ){
first = i;
}
if ( cacheEnd.valueOf() === end.valueOf()){
last = i;
returnVal = accountingPeriods.slice(first,last+1);
}
}
return returnVal;
}
Anthony OConnor
12/31/2024, 5:08 PMconst CR_CACHE = 'Contract Renewals Cache';
const CacheKeys = {
ACCOUNTING_PERIODS: 'Accounting Periods',
};
Anthony OConnor
12/31/2024, 5:08 PMconst periods = getPeriods2({start, end});
Anthony OConnor
12/31/2024, 5:11 PMAnthony OConnor
12/31/2024, 5:11 PMfor (let i=0; i < periods.length; i++){
//Positive Revenue
const snapData = {
period: periods[i].id, ... <snip>
Anthony OConnor
12/31/2024, 5:14 PMSim Greenbaum
12/31/2024, 5:15 PMfunction getchacheLocation() {
const CACHE_KEY = 'active_locations';
const CACHE_DURATION = 3600; // Cache duration in seconds (e.g., 1 hour)
let locationCache = cache.getCache({
name: CACHE_DURATION,
scope: cache.Scope.PROTECTED
});
let cachedLocations = locationCache.get({ key: CACHE_KEY, loader: getActiveLocations });
return JSON.parse(cachedLocations);
}
Sim Greenbaum
12/31/2024, 5:16 PM/**
* @NApiVersion 2.1
* @NScriptType ClientScript
* @NModuleScope SameAccount
*/
define(["N/query", 'N/cache'], function (query, cache) {
let cachedLocations = null; // Global cache for active locations
function pageInit(scriptContext) { }
function getActiveLocations() {
let subSql = `SELECT
id,
name,
isinactive
FROM
location
WHERE
isinactive = 'F'`;
var mySuiteQLQuery = query.runSuiteQL(subSql);
cachedLocations = mySuiteQLQuery.asMappedResults();
/// an array of objects
return cachedLocations;
}
function getchacheLocation() {
const CACHE_KEY = 'active_locations';
const CACHE_DURATION = 3600; // Cache duration in seconds (e.g., 1 hour)
let locationCache = cache.getCache({
name: CACHE_DURATION,
scope: cache.Scope.PROTECTED
});
let cachedLocations = locationCache.get({ key: CACHE_KEY, loader: getActiveLocations });
return JSON.parse(cachedLocations);
}
function getLocationNameById(idData) {
let id = parseInt(idData);
const locations = getchacheLocation();
const location = locations.find((loc) => loc.id === id); // Find by ID
return location ? location.name : null; // Return name or null
}
return {
pageInit: pageInit,
getActiveLocations: getActiveLocations,
getLocationNameById: getLocationNameById,
clearCache: clearCache,
};
});
Anthony OConnor
12/31/2024, 5:19 PM.find
on your resultsAnthony OConnor
12/31/2024, 5:20 PMSim Greenbaum
12/31/2024, 5:20 PMAnthony OConnor
12/31/2024, 5:21 PM{
174: 'warehouseA',
175: 'warehouseB'
}
Sim Greenbaum
12/31/2024, 5:21 PMAnthony OConnor
12/31/2024, 5:21 PMAnthony OConnor
12/31/2024, 5:21 PMSim Greenbaum
12/31/2024, 5:22 PMAnthony OConnor
12/31/2024, 5:22 PMAnthony OConnor
12/31/2024, 5:23 PMAnthony OConnor
12/31/2024, 5:24 PMSim Greenbaum
12/31/2024, 5:26 PMAnthony OConnor
12/31/2024, 5:26 PM