SuiteScript to sum the weight based on ship-out location - javascript

I want to be able to calculate the total weights of the items on the sales order based on their ship-out locations and store the values in custom fields. I created a before submitting script on this. The custom field is set to decimal number type and the store value box is checked, but nothing shows up under the field on sales order page.
function calculateWeight(type){
var lines = nlapiGetLineItemCount('item');
var totalWeight2 = 0 ;
var totalWeight1 = 0 ;
if (lines >0){
for(var i = 1; i<= lines ; i++){
var location = nlapiGetLineItemValue('item','location', i);
var quantitycommitted = nlapiGetLineItemValue('item','quantitycommitted', i);
var weight = nlapiGetLineItemValue('item','custcol_individual_weight', i);
//var com_wgt = nlapiGetLineItemValue('item','custcol1',i);
if (location === '2'){
var total2 = weight * quantitycommitted;
totalWeight2 += total2 ;
}
if (location === '1'){
var total1 = weight * quantitycommitted;
totalWeight1 += total1 ;
}
}
nlapiSetFieldValue('custbody5', totalWeight1);
nlapiSetFieldValue('custbody4', totalWeight2);
}
}
I am still learning SuiteScript and I am not exactly sure where went wrong... Can somebody help?
Updated code, only worked for some of the orders...
function calculateWeight(type){
var lines = nlapiGetLineItemCount('item');
//nlapiLogExecution('DEBUG', 'Number of lines', lines);
var totalWeight2 = 0 ;
var totalWeight1 = 0 ;
if (lines >0){
for(var i = 1; i<= lines ; i++){
var location = nlapiGetLineItemValue('item','location', i);
//nlapiLogExecution('DEBUG', 'Locations', location);
var quantitycommitted = parseInt(nlapiGetLineItemValue('item','quantitycommitted', i),10) || 0;
//nlapiLogExecution('DEBUG', 'QtyCom', quantitycommitted);
var weight = parseFloat(nlapiGetLineItemValue('item','custcol_individual_weight', i)) ||0;
//nlapiLogExecution('DEBUG', 'Wgt', weight);
//var com_wgt = nlapiGetLineItemValue('item','custcol1',i);
if (location == '2'){
var total2 = weight * quantitycommitted;
totalWeight2 += total2 ;
nlapiLogExecution('DEBUG', 'Total2', totalWeight2);
}
if (location == '1'){
var total1 = weight * quantitycommitted;
totalWeight1 += total1 ;
nlapiLogExecution('DEBUG', 'Total1', totalWeight1);
}
}
nlapiSetFieldValue('custbody_ms_weight_ppt_page', totalWeight1);
nlapiSetFieldValue('custbody_wi_weight_ppt_page', totalWeight2);
}
}

You need to parse the line values:
var quantitycommitted = parseInt(nlapiGetLineItemValue('item','quantitycommitted', i),10) || 0;
var weight = parseFloat(nlapiGetLineItemValue('item','custcol_individual_weight', i)) ||0;
also in some contexts your location ids will not be strings so that may also be the issue. Relying on == instead of === works.

Related

multiple loops google app script

I am currently working in GAS to create and optimize a search function based on multiple criteria.
I have code that works, but it is inconsistent on whether or not the function call will time-out before the search is completed.
//Top level function to run the sub-level OD, ID, End Ring, Pusher, and Bushing Length functions
function toolSearch(od, id, mat) {
var od1 = parseFloat(od);
var id1 = parseFloat(id);
var inc = .25; //change to 0 when standardized bushings are implemented
var passOutput = [];
var failOutput = ["Tooling Unavailable", "Contact CPI Stafford Materials Engineer"];
if (od1 > 49 || id1 > 46)
return failOutput;
//If statement to determine amount of end rings required based on OD shell size and material
if (mat == "Hot Mold" && od < 10)
var qER = 4;
else
qER = 2;
//Initial tooling search
var od2 = toolSearchOD(od1);
var id2 = toolSearchID(id1);
var er = toolSearchER(od2, id2);
var ps = toolSearchPS(od2);
var wall = wallCall(od2, id2);
//return variables must be parsed from strings to integers and decimals
od2 = parseFloat(od2);
id2 = parseFloat(id2);
er = parseInt(er);
ps = parseInt(ps);
wall = parseFloat(wall);
//Remove comments when standardized bushings are implemented
/*if(id>10)
{inc = .5;}
else
{inc = .25;}*/
//If statement to check for pusher and end ring requirments before moving into for loop
if (er < qER || ps < 1) {
//For loop to find OD and ID shells, the required quantity of end rings, and the pusher
for (var i = 0; i < 50; i++) { //Loop is set at 75 in order to prevent 30 second function time out. May need to be adjusted.
od2 += inc;
od2 = toolSearchOD(od2);
od2 = parseFloat(od2);
wall = wallCall(od2, id2);
wall = parseFloat(wall);
er = toolSearchER(od2, id2);
er = parseInt(er);
ps = toolSearchPS(od2);
ps = parseInt(ps);
if (wall > 3) {
id2 -= inc
id2 = toolSearchID(id2);
id2 = parseFloat(id2);
od2 = od1 - inc;
od2 = parseFloat(od2);
er = toolSearchER(od2, id2);
er = parseInt(er);
}
if (er >= qER && ps >= 1)
break;
}
}
//A final check to make sure that the variable is parsed to an integer or decimal
od2 = parseFloat(od2);
id2 = parseFloat(id2);
er = parseInt(er);
ps = parseInt(ps);
wall = parseFloat(wall);
var blength = bLength(mat, od2, id2); //Bushing Length function input/output
//If statement to check if requirements have been met to return the proper information
if (er < qER || ps < 1 || wall > 3) {
return failOutput;
} else {
passOutput = [od2, id2, blength, er, ps, wall];
return passOutput;
}
}
//A final check to make sure that the variable is parsed to an integer or decimal
od2 = parseFloat(od2);
id2 = parseFloat(id2);
er = parseInt(er);
ps = parseInt(ps);
wall = parseFloat(wall);
var blength = bLength(mat,od2, id2); //Bushing Length function input/output
//If statement to check if requirements have been met to return the proper information
if(er < qER || ps < 1 || wall > 3){
Logger.log("FAILURE TO FIND SIZE " + passOutput);
return failOutput;}
else{
passOutput = [od2,id2, blength,er, ps, wall];
return passOutput;}
}
//****************************************************************************************
//Sub-function for searching the shell OD inventory, based on the updated OD from toolSearch
function toolSearchOD(od) {
var range = CacheService.getScriptCache().get('rangeSHOD');//Call to data in cache
range = Utilities.parseCsv(range);//All returns from cache need to be parsed from a CSV format to a horizontal array with a permanent row of zero
var size = lastRow("Shell Inventory");//Call to sub-function to determine index of last row of the sheet with data in it.
var found = 0;
od = parseFloat(od);//A built in check to make sure that the variable is parsed to a decimal
var inc = .25;//change to 0 when standardized bushings are implemented
//Remove comments when standardized bushings are implemented
/*if(od>10)
{var inc = .5;}
else
{inc = .25;}*/
while (found != 1){
for(var j=0;j<size;j++)
{
if(range[0][j] == od){
od = range[0][j];
found = 1;
}
}
if(found != 1)
od+=inc;
}
return od;
}
//****************************************************************************************
//Sub-function for searching the shell OD inventory, based on the updated ID from toolSearch
function toolSearchID(id) {
var range = CacheService.getScriptCache().get('rangeSHID');
range = Utilities.parseCsv(range);
var size = lastRow("Shell Inventory");
var found = 0;
id = parseFloat(id);
var inc = .25;//change to 0 when standardized bushings are implemented
//Remove comments when standardized bushings are implemented
/*if(id>10)
{var inc = .5;}
else
{inc = .25;}*/
while (found != 1){
for(var j=0;j<size;j++)
{
if(range[0][j] == id){
id = range[0][j];
found = 1;
}
}
if(found != 1)
id-=inc;
}
return id;
}
//****************************************************************************************
//Sub-function for searching the end ring inventory, based on the updated ID and OD values from toolSearchID and toolSearchOD.
function toolSearchER(od,id) {
var rangeOD = CacheService.getScriptCache().get('rangeEROD');
var rangeID = CacheService.getScriptCache().get('rangeERID');
var rangeQTY = CacheService.getScriptCache().get('rangeERQTY');
rangeOD = Utilities.parseCsv(rangeOD);
rangeID = Utilities.parseCsv(rangeID);
rangeQTY = Utilities.parseCsv(rangeQTY);
var size = lastRow("End Ring Inventory");
var erQTY = 0;
od = parseFloat(od);
id = parseFloat(id);
for(var j=0;j<size;j++)
{
if(rangeID[0][j] == id && rangeOD[0][j] == od){
erQTY += parseInt(rangeQTY[0][j]);
}
}
return erQTY;
}
//****************************************************************************************
//Sub-function for searching the end ring inventory, based on the updated ID and OD values from toolSearchID and toolSearchOD.
function toolSearchPS(od) {
var rangeQTY = CacheService.getScriptCache().get('rangePSQTY');
var rangeOD = CacheService.getScriptCache().get('rangePSOD');
rangeOD = Utilities.parseCsv(rangeOD);
rangeQTY = Utilities.parseCsv(rangeQTY);
var size = lastRow("Pusher Inventory");
var psQTY = 0;
od = parseFloat(od);
od -= .25;
for(var j=0;j<size;j++)
{
if(rangeOD[0][j] == od){
psQTY = rangeQTY[0][j];
}
}
return psQTY;
}
//****************************************************************************************
//Sub-function to calculate bushing wall size based on updated OD and ID inputs from toolSearch, toolSearchOD, and toolSearchID
function wallCall(od,id){
var wall;
wall = (od-id)/2;
return wall;
}
//****************************************************************************************
//Sub-function that puts all required data into a Google cache for more efficent processing. Cache time limit is 1 hour
function cache(){
var ss = SpreadsheetApp.getActive();
var sheetSH = ss.getSheetByName("Shell Inventory");
var sheetSHL = sheetSH.getRange("F2:F").getValues();
var sheetER = ss.getSheetByName("End Ring Inventory");
var sheetPS = ss.getSheetByName("Pusher Inventory");
var rangeSHOD = sheetSH.getRange("D2:D").getValues();
var rangeSHID = sheetSH.getRange("C2:C").getValues();
var rangeERQTY = sheetER.getRange("H2:H").getValues();
var rangeEROD = sheetER.getRange("C2:C").getValues();
var rangeERID = sheetER.getRange("D2:D").getValues();
var rangePSQTY = sheetPS.getRange("G2:G").getValues();
var rangePSOD = sheetPS.getRange("B2:B").getValues();
CacheService.getScriptCache().put('rangeSHOD',rangeSHOD,3600);
CacheService.getScriptCache().put('rangeSHID',rangeSHID,3600);
CacheService.getScriptCache().put('sheetSHL' ,sheetSHL,3600);
CacheService.getScriptCache().put('rangeERID',rangeERID,3600);
CacheService.getScriptCache().put('rangeEROD',rangeEROD,3600);
CacheService.getScriptCache().put('rangeERQTY',rangeERQTY,3600);
CacheService.getScriptCache().put('rangePSQTY',rangePSQTY,3600);
CacheService.getScriptCache().put('rangePSOD',rangePSOD,3600);
}
//****************************************************************************************
//Sub-function to calculate the index of last row of data for a sheet
function lastRow(sheetName){
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(sheetName);
var size=sheet.getLastRow();
return size;
}
//****************************************************************************************
//Sub-function to calculate bushing length based on OD and ID shell lengths and type of material
function bLength (mat,od, id){
var rangeID = CacheService.getScriptCache().get('rangeSHID');
var rangeOD = CacheService.getScriptCache().get('rangeSHOD');
var rangeL = CacheService.getScriptCache().get('sheetSHL');
rangeID = Utilities.parseCsv(rangeID);
rangeOD = Utilities.parseCsv(rangeOD);
rangeL = Utilities.parseCsv(rangeL);
var size = lastRow("Shell Inventory");
var lengthID = 0;
var lengthOD = 0;
var blength = 0;
id = parseFloat(id);
od = parseFloat(od);
//Find ID shell length
for(var j=0;j<size;j++)
{
if(rangeID[0][j] == id){
lengthID = rangeL[0][j];
}
}
found = 0;
//Find OD shell length
for(var j=0;j<size;j++)
{
if(rangeOD[0][j] == od){
lengthOD = rangeL[0][j];
}
if(lengthID == 18){
blength = "5 inches *Configuration not recommended*.";}
else if (lengthOD == 18)
blength = "5 inches";
else if(mat == "Hot Mold"){
blength = "6 inches";}
else
blength = "9 inches";
return blength;
}
}
function matType(mat){
var hot = 0;
var matType;
switch (mat){
case 620:
hot = 1;
break;
case 603:
hot = 1;
break;
case 604:
hot = 1;
break;
case 611:
hot = 1;
break;
case 605:
hot = 1;
break;
case 608:
hot = 1;
break;
case 580:
hot = 1;
break;
case 607:
hot = 1;
break;
default:
break;
}
if (hot == 1)
matType = "Hot Mold";
else
matType = "Cold Mold";
return matType;
}
Yes I know it's clunky. The "for" loop requirement is there to keep the script from timing out but it is far from effective and I know there is a better way.
The data is on 3 separate sheets and their is a function that caches all the relevant data to try and limit the amount of calls to the sheet, which helped, but not enough.
How can I make this code more efficient? I need to add more criteria which will require more looping to find the correct set of tooling for a job and I'm afraid this will cause the top level function to exceed the function call time very quickly.

Google Form Script Population

I am trying to populate a google form with questions scraped from a google sheet. Currently when I run my code I am getting the questions created, but only 25% or so actually have the string, the rest are simply blank. The questions that appear correctly change every time I run the script. It is seemingly random.
function formPopulation() {
var ss = SpreadsheetApp.openById("--");
var sheet = ss.getSheetByName('Tracker');
var auditTool = ss.getSheetByName('Audit Tool');
var validatorInfo = ss.getSheetByName('Validator Info');
//Sheet Info
var rows = auditTool.getLastRow(); //Number of Rows
var columns = auditTool.getLastColumn(); //Number of Columns
var startRow = 1;
var startColumn = 1;
var dataRange = auditTool.getRange(startRow, startColumn, rows, columns);
//getRange(first row of data, first column of data, last row of data, last column of data)
var data = dataRange.getValues();
//Sets working range of script
var form = FormApp.openById("--");
var item = form.addListItem();
var entityName = "";
var arrayOfEntities = [];
var newEntity = '';
for (var i = 4; i < columns; i++) {
//4 because that is where entity names begin
entityName = data[i][2];
Logger.log('entityName: ' + entityName);
newItem = item.createChoice(entityName);
arrayOfEntities.push(newItem);
};
item.setTitle("Select Entity").setChoices(arrayOfEntities);
var requirement = "";
var arrayOfRequirements = [];
var newRequirement = '';
for (var j = 5; j < rows; j++) {
//5 because that is where Requirements begin
if (data[0][j] != null) {
requirement = data[0][j];
if (requirement != "" || requirment != null){
requirement = "question #" + j;
Logger.log('requirement: ' + requirement);
form.addMultipleChoiceItem().setTitle(requirement).setChoiceValues(['Complete', 'Incomplete']);
};
};
};
};
The first question is supposed to be a multiple choice item where each 'entity' is an option. The remainder of the questions are supposed to be whether each 'requirement' is marked complete or incomplete.
Here is the spreadsheet I am working from
you have a typo:
if (requirement != "" || requirment != null){
should be 'requirement'
Here in last forloop
requirement = "question #" + j;
Please verify, is it ok ? or you should use
requirement = "question #" + j + ' ' +data[0][j];

Assigning a value to a global variable through input method

Good day. Have patience first of all since I am just a new enthusiast to Javascript and programming in general. The concern about my project is that I want to assign a value to a global variable through input method and run it through. I've tried, researched and nothing more work for me at this time. So I am asking anyone for ideas, how will it be possible. Your assistance will definitely help me in my learning process.
Initially, the code looks likes this: Here the global variable numItems is defined by 30. That variable numItems is also mentioned within two other functions below. What I want to do is change that number through input method. I've tried...
numItems = 30;
var xvalue = [];
var yvalue = [];
for (var i=0; i < numItems; i++) {
xvalue.push(i % 9); yvalue.push((i % 9)+1);
}
followed by several functions....
This is my try, but it seems this is not working... Any assistance will be greatly appreciated.
numItems = document.getElementById("numInput");
numItems.addEventListener("input", whatValue);
function whatValue() {
var num = parseFloat(numItems.value);
document.getElementById("numInput") = num;
}
var xvalue = [];
var yvalue = [];
for (var i=0; i < numItems; i++) {
xvalue.push(i % 9); yvalue.push((i % 9)+1);
}
followed by several functions....
Here is the whole code when I applied Michael's suggestions below: It works, but my concern now are the undefined variables in the output---> undefined + undefined or undefined - undefined
<body>
<input id="numInput">
<select id="processMath">
<option value="add">Addition</option>
<option value="sub">Subtraction</option>
</select>
<button onclick="newExercise()">New Exercise</button>
<button onclick="createExercise()">Create Exercise</button>
<div id="tableOne"></div>
</body>
<script type="text/javascript">
numItems = document.getElementById("numInput");
numItems.addEventListener("input", whatValue);
function whatValue() {
numItems = parseFloat(document.getElementById("numInput").value);
}
xvalue = [];
yvalue = [];
for (var i=0; i<numItems ; i++) {
xvalue.push(i % 9); yvalue.push((i % 9)+1);
}
function tableOne (operator) {
var valtp = '';
var spc = '<table border="1" width="80%"><tr>';
i = 0;
while (i < numItems ) {
a = xvalue[i];
b = yvalue[i];
spc += '<td align="right">'+a;
if (operator == 'add') { spc += '<br>+ '+b; valtp = a+b; }
if (operator == 'sub') { spc += '<br>- '+b; valtp = a-b; }
spc += '<br>_____';
i++;
if ((i % 5) == 0) { spc += '</tr><tr>'; }
}
spc += '</tr></table>';
return spc;
}
function createExercise() {
var a = 0; var b = 0; var spc = '';
var spc = '';
var sel = document.getElementById('processMath').value;
switch (sel) {
case 'add' : spc += tableOne(sel); break;
case 'sub' : spc += tableOne(sel); break;
}
document.getElementById('tableOne').innerHTML = spc;
}
function makeRandom() {
return (Math.round(Math.random())-0.5);
}
function newExercise() {
xvalue.sort(makeRandom);
yvalue.sort(makeRandom);
}
</script>
Unless I've misunderstood you, it looks like your whatValue() function is trying to change the input value, instead of changing the numItems variable, but it's failing on both counts.
function whatValue() {
var num = parseFloat(numItems.value);
document.getElementById("numInput") = num;
}
Should be:
function whatValue() {
numItems = parseFloat(document.getElementById("numInput").value);
}
Now, your numItems variable should change every time numInput changes.
But, even though numItems changes, it won't make the rest of your code run again. So your two arrays will still look like they did when numItems was 30.

Qualtrics Sum Matrix Table

I'm trying to recreate the matrix in Qualtrics from this image:
The Javascript I found uses text entry but I think profile multiple answer would be better suited for this question. I need a way to allow users to select multiple items and display their current total. My sincere thanks to anyone that can point me in the right direction.
Qualtrics.SurveyEngine.addOnload(function() {
var qid = this.questionId;
$(qid).select('td.c4').last().down().hide();
$(qid).select('td.c5').last().down().hide();
var totalInput = $(qid).select('td.c6').last().down();
totalInput.setAttribute("readonly", "readonly");
totalInput.style.fontWeight = "bold";
var c6 = $(qid).select('td.c6');
for(var i=0; i < (c6.length - 1); i++) {
c6[i].down().observe("keyup", function(event) {
sumCol();
});
}
sumCol();
function sumCol() {
var total = 0;
for(var i=0; i < (c6.length - 1); i++) {
var inputValue = parseInt(c6[i].down().value);
if(isNaN(inputValue)) inputValue = 0;
c6[i].down().value = inputValue;
total = total + inputValue;
}
totalInput.value = total;
if(total == 100) totalInput.style.color = "";
else totalInput.style.color = "red";
}
});

How do I bold one line in a Google Docs Script?

I'm writing a script to parse a Google Sheet and format the cells nicely on a Doc. I'd like the cell data from column 1 to always be bold and the cell data from column 6 to always be Italic. The problem is, after appending a paragraph to the document body, the attribute changes are applied to the entire document. Is there a way to bold/italicize the cell data before appending it to the doc body?
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var doc = DocumentApp.create("Smogon Formatted");
var docBody = doc.getBody();
for (var i = 2; i <= numRows; i++) {
for (var j = 1; j <= numCols; j++){
var cellData = rows.getCell(i, j).getValue()
// Format data based on column
if (j == 1) {
docBody.appendParagraph(cellData).editAsText().setBold(true);
} else if (j == 2 || j == 3) {
var imgFormula = rows.getCell(i, j).getFormula();
var imgUrl = getImageUrl(imgFormula);
docBody.appendParagraph("[img]" + imgUrl + "[/img]");
} else if (j == 6) {
docBody.appendParagraph(cellData).editAsText().setItalic(true);
} else {
docBody.appendParagraph(cellData);
}
}
}
};
EDIT: Try #2, using the setAttributes method
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var doc = DocumentApp.create("Smogon Formatted");
var docBody = doc.getBody();
for (var i = 2; i <= numRows; i++) {
for (var j = 1; j <= numCols; j++){
var cellData = rows.getCell(i, j).getValue()
// Format data based on column
if (j == 1) {
docBody.appendParagraph(cellData).setAttributes(style1);
} else if (j == 2 || j == 3) {
var imgFormula = rows.getCell(i, j).getFormula();
var imgUrl = getImageUrl(imgFormula);
docBody.appendParagraph("[img]" + imgUrl + "[/img]");
} else if (j == 6) {
docBody.appendParagraph(cellData).setAttributes(style2);
} else {
docBody.appendParagraph(cellData);
}
}
}
};
// Style definitions as global variables
var style1= {};
style1[DocumentApp.Attribute.BOLD] = true;
var style2= {};
style2[DocumentApp.Attribute.ITALIC] = true;
If you use style attributes you can assign a style to every paragraph very easily, you can actually do it for any document element...
Here is a basic example code to show how it works :
(doc here)
function exportToDoc(){
var doc = DocumentApp.openById('16i----L53WTDpzuLyhqQQ_E');// or create a new doc (but not while you test it :-)
var body = doc.getBody();
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getDataRange().getValues();
for (var i in values){
var rowData = values[i].join(' + ');
if (i == 1) {
body.appendParagraph(rowData).setAttributes(style2);
} else if (i == 2 ) {
body.appendParagraph(rowData).setAttributes(style1)
}
}
doc.saveAndClose();
}
// Style definitions as global variables
var style1 = {};// style example 1
style1[DocumentApp.Attribute.FONT_SIZE] = 10;
style1[DocumentApp.Attribute.FONT_FAMILY] = DocumentApp.FontFamily.CONSOLAS;
style1[DocumentApp.Attribute.FOREGROUND_COLOR] = "#444400";
var style2 = {};// style example 2
style2[DocumentApp.Attribute.FONT_SIZE] = 16;
style2[DocumentApp.Attribute.FONT_FAMILY] =DocumentApp.FontFamily.ARIAL_NARROW;
style2[DocumentApp.Attribute.FOREGROUND_COLOR] = "#005500";
//
example random data result :

Categories

Resources