NS: Set Project ARM Percent Complete Sublist
/**
* Use this script to update the Rev Rec Percent Complete Override
* entries based on a project header custom field. This allows the
* Project Manager, Finance Manager, or an integration to provide
* percent of completion updates without manually editing the
* sublist directly.
*
* Version Date Author Remarks
* 1.00 13 Jul 2015 cvandemore
* 1.01 13 Oct 2015 rmorrissey Clean up and add reset
*
*/
/**
* Attempts to update the project percent complete sublist
* using inputs from project header custom fields. This script
* is set to trigger beforeSubmit in any context.
* @param {string} type One of create, edit, delete, xedit.
*/
function setPrjPocSublistBeforeSubmit(type) {
try {
// Define project custom fields for script deployment
var FLD = {
// Project header custom fields
date : 'custentity_update_poc_date',
period : 'custentity_update_poc_period',
complete : 'custentity_update_poc_value',
// Project standard fields/sublists
override : 'percentcompleteoverride'
};
// Load project record and get field values
var recPrj = nlapiGetNewRecord(),
prjDate = recPrj.getFieldValue(FLD.date),
prjPeriod = recPrj.getFieldValue(FLD.period),
prjComplete = recPrj.getFieldValue(FLD.complete),
prjLines = recPrj.getLineItemCount(FLD.override),
updLine;
// If no POC value, skip update
if (!prjDate || prjDate === '' || !prjComplete || prjComplete === '') {
nlapiLogExecution('DEBUG', 'No update', '% complete update skipped!');
return;
}
// If no period specified, find one
if (!prjPeriod || prjPeriod === '') {
prjPeriod = getAccountingPeriodFromDate(prjDate);
}
// If no period was found, or if multiple were found, skip
if (prjPeriod === null) {
nlapiLogExecution('DEBUG', 'No update', 'Couldn\'t find period!');
return;
}
// Check for existing sublist entries
if (prjLines > 0) {
// Loop through existing sublist lines
var _i = 1;
for (_i; _i <= prjLines; _i++) {
var lnPeriod = recPrj.getLineItemValue(FLD.override, 'period', _i);
if (lnPeriod === prjPeriod) {
// Periods match - update this line and break
updLine = _i;
break;
}
// Period is new - create new line
updLine = prjLines + 1;
}
} else {
// No sublist lines exist - set the first line
updLine = 1;
recPrj.insertLineItem(FLD.override, updLine);
}
// Update project sublist and clear project header fields
recPrj.setLineItemValue(FLD.override, 'period', updLine, prjPeriod);
recPrj.setLineItemValue(FLD.override, 'percent', updLine, prjComplete);
recPrj.setLineItemValue(FLD.override, 'comments', updLine, 'Last updated: ' + prjDate);
recPrj.setFieldValue(FLD.date, null);
recPrj.setFieldValue(FLD.period, null);
recPrj.setFieldValue(FLD.complete, null);
return;
} catch (err) {
nlapiLogExecution('ERROR', 'Unexpected script error', err.message);
return;
}
}
/**
* Attempts to find the correct accounting period based on a date string.
* @param {string} accountingDate A date string.
* @return {number} The internal ID of a valid accounting period.
*/
function getAccountingPeriodFromDate(accountingDate) {
var _date = nlapiStringToDate(accountingDate),
periodID = null;
var sFilters = [];
sFilters.push(new nlobjSearchFilter('isinactive', null, 'is', 'F'));
sFilters.push(new nlobjSearchFilter('isadjust', null, 'is', 'F'));
sFilters.push(new nlobjSearchFilter('isyear', null, 'is', 'F'));
sFilters.push(new nlobjSearchFilter('isquarter', null, 'is', 'F'));
sFilters.push(new nlobjSearchFilter('startdate', null, 'onorbefore',_date));
sFilters.push(new nlobjSearchFilter('enddate', null, 'onorafter',_date));
var sColumns = [];
sColumns.push(new nlobjSearchColumn('internalid'));
sColumns.push(new nlobjSearchColumn('periodname'));
var sResults = nlapiSearchRecord('accountingperiod', null, sFilters, sColumns);
var numPeriods = sResults.length;
nlapiLogExecution('DEBUG', 'Num periods for date: ' + _date, numPeriods);
if (numPeriods === 1) {
periodID = sResults[0].getValue('internalid');
nlapiLogExecution('DEBUG', 'Period ID for date: ' + _date, periodID);
}
return periodID;
}
var ctx = nlapiGetContext(),
feature_arm = ctx.getFeature('advancedrevenuerecognition');
if (feature_arm) {
// run arm percent complete sublist code
} else {
// run override percent complete field code
}