Adding invoice download link in suitelet

Requirement

We need to add a download link for each invoices or credit memo displayed in the suitlet page. When clicked on the invoice download link, user should be able to navigate to the page from which invoice or credit memo can be downloaded or printed.

Solution

The download url can be provided as the value in sublist field of type URL with the dynamic id of the invoice or credit memo. So by clicking on the link, will open up into a page from which it can be downloaded.

/** 
* @NApiVersion 2.1 
* @NScriptType Suitelet 
*/ 
define(['N/currentRecord', 'N/record', 'N/redirect', 'N/render', 'N/runtime', 'N/search', 'N/task', 'N/url', 'N/ui/serverWidget', 'N/file'], 
/** 
* @param{currentRecord} currentRecord 
* @param{record} record 
* @param{redirect} redirect 
* @param{render} render 
* @param{runtime} runtime 
* @param{search} search 
* @param{task} task 
* @param{url} url 
* @param{serverWidget} serverWidget, 
* @param{file} file 
*/ 
(currentRecord, record, redirect, render, runtime, search, task, url, serverWidget, file) => { 
/** 
* Defines the Suitelet script trigger point. 
* @param {Object} scriptContext 
* @param {ServerRequest} scriptContext.request - Incoming request 
* @param {ServerResponse} scriptContext.response - Suitelet response 
* @since 2015.2 
*/ 

//Customer search created with criteria considering top level parent also to get details of transactions 
function invoiceCreditMemoSearch(parms) { 
var transactionSearchObj = search.create({ 
type: "customer", 
filters: 
[ 
[["toplevelparent.internalid", "anyof", parms], "OR", ["internalid", "anyof", parms]], 
"AND", 
["transaction.type", "anyof", "CustInvc", "CustCred"], 
"AND", 
["transaction.status", "anyof", "CustCred:A", "CustInvc:A"], 
"AND", 
["transaction.mainline", "is", "T"] 
], 
columns: 
[ 
search.createColumn({name: "internalid", label: "Internal ID"}), 
search.createColumn({name: "altname", label: "Name"}), 
search.createColumn({ 
name: "tranid", 
join: "transaction", 
label: "Document Number" 
}), 
search.createColumn({ 
name: "trandate", 
join: "transaction", 
label: "Date" 
}), 
search.createColumn({ 
name: "subsidiary", 
join: "transaction", 
label: "Subsidiary" 
}), 
search.createColumn({ 
name: "duedate", 
join: "transaction", 
label: "Due Date/Receive By" 
}), 
search.createColumn({ 
name: "daysoverdue", 
join: "transaction", 
label: "Days Overdue" 
}), 
search.createColumn({ 
name: "amount", 
join: "transaction", 
label: "Amount" 
}), 
search.createColumn({ 
name: "amountremaining", 
join: "transaction", 
label: "Amount Remaining" 
}), 
search.createColumn({ 
name: "internalid", 
join: "transaction", 
label: "Internal ID" 
}), 
search.createColumn({ 
name: "type", 
join: "transaction", 
label: "Type" 
}) 
] 
}); 
var searchResultCount = transactionSearchObj.runPaged().count; 
var searchResult = transactionSearchObj.run().getRange({ 
start: 0, 
end: 1000 
}); 


log.debug('SearchCount', searchResultCount) 
log.debug('SearchResuLT Data', searchResult) 

return searchResult; 

} 

const onRequest = (scriptContext) => { 

try { 

//Get Method 
if (scriptContext.request.method === 'GET') { 
var form = serverWidget.createForm({title: 'INVOICE DETAILS'}); 



var parms = scriptContext.request.parameters.custscriptcust_id; 


log.debug('Invoice id from url', parms) 

//Sublist is added to the form 
var sublistDet = form.addSublist({ 
id: 'custpage_det', 
type: serverWidget.SublistType.LIST, 
label: 'Invoice Details' 
}); 


//Adding the body fields to the suitelet 

var date = sublistDet.addField({ 
id: 'custpage_date', 
label: 'DATE', 
type: serverWidget.FieldType.TEXT, 
align: serverWidget.LayoutJustification.RIGHT 
}); 
var docnum = sublistDet.addField({ 
id: 'custpage_docnumber', 
label: 'DOCUMENT NUMBER', 
type: serverWidget.FieldType.TEXT, 
align: serverWidget.LayoutJustification.RIGHT 
}); 
var name = sublistDet.addField({ 
id: 'custpage_name', 
label: 'CUSTOMER NAME', 
type: serverWidget.FieldType.TEXT, 
align: serverWidget.LayoutJustification.RIGHT 
}); 


var duedate = sublistDet.addField({ 
id: 'custpage_duedate', 
label: 'DUE DATE', 
type: serverWidget.FieldType.TEXT, 
align: serverWidget.LayoutJustification.RIGHT 
}); 

var amount = sublistDet.addField({ 
id: 'custpage_amount', 
label: 'AMOUNT', 
type: serverWidget.FieldType.TEXT, 
align: serverWidget.LayoutJustification.RIGHT 
}); 

//Adding the download option for each invoices 
var downlink = sublistDet.addField({ 
id: 'custpage_down', 
type: serverWidget.FieldType.URL, 
label: ' ' 
}).linkText = 'Download' 

//Invoking the customer search created inside a function and passing the customer id as a parameter to it. 
var searchResult = invoiceCreditMemoSearch(parms); 


//Iterating through the search result. 
for (var i = 0; i < searchResult.length; i++) { 

//If the type of transaction is Invoice then following URl is taken 
if ((searchResult[i].getValue({ 
name: "type", 
join: "transaction", 
label: "Type" 
})) === 'CustInvc') { 
var urlVal = "https://6687177-sb1.app.netsuite.com/app/accounting/print/hotprint.nl?regular=T&sethotprinter=T&formnumber=148&trantype=custinvc&&id=" + searchResult[i].getValue({ 
name: "internalid", 
join: "transaction", 
label: "Internal ID" 
}) + "&label=Invoice&printtype=transaction" 
} 
//If the transaction type is a credit memo, then the following URL is taken 
else { 
var urlVal = "https://6687177-sb1.app.netsuite.com/app/accounting/print/hotprint.nl?regular=T&sethotprinter=T&formnumber=139&trantype=custcred&&id=" + searchResult[i].getValue({ 
name: "internalid", 
join: "transaction", 
label: "Internal ID" 
}) + "&label=Credit+Memo&printtype=transaction&whence=" 

} 

//Setting the URL value to the download link 
sublistDet.setSublistValue({ 
id: 'custpage_down', 
line: i, 
value: urlVal 
}); 

//Setting the Name 
sublistDet.setSublistValue({ 
id: 'custpage_name', 
line: i, 
value: (searchResult[i].getValue({name: "altname", label: "Name"} 
)) || " " 
}); 

//Setting the date 
sublistDet.setSublistValue({ 
id: 'custpage_date', 
line: i, 
value: (searchResult[i].getValue({ 
name: "trandate", 
join: "transaction", 
label: "Date" 
} 
)) || " " 
}); 

//Setting the document number 
sublistDet.setSublistValue({ 
id: 'custpage_docnumber', 
line: i, 
value: (searchResult[i].getValue({ 
name: "tranid", 
join: "transaction", 
label: "Document Number" 
} 
)) || " " 
}); 

//Setting the Amount 
sublistDet.setSublistValue({ 
id: 'custpage_amount', 
line: i, 
value: (searchResult[i].getValue({ 
name: "amount", 
join: "transaction", 
label: "Amount" 
} 
)) || " " 
}); 

//Setting the due date 
sublistDet.setSublistValue({ 
id: 'custpage_duedate', 
line: i, 
value: (searchResult[i].getValue({ 
name: "duedate", 
join: "transaction", 
label: "Due Date/Receive By" 
} 
)) || " " 
}); 

//Setting the amount remaining value 
sublistDet.setSublistValue({ 
id: 'custpage_amountf', 
line: i, 
value: (searchResult[i].getValue({ 
name: "amountremaining", 
join: "transaction", 
label: "Amount Remaining" 
} 
)) || " " 
}); 

//Setting the subsidiary 
sublistDet.setSublistValue({ 
id: 'custpage_subsidiary', 
line: i, 
value: (searchResult[i].getText({ 
name: "subsidiary", 
join: "transaction", 
label: "Subsidiary" 
} 
)) || " " 
}); 

//Setting the due days 
sublistDet.setSublistValue({ 
id: 'custpage_duedays', 
line: i, 
value: (searchResult[i].getValue({ 
name: "daysoverdue", 
join: "transaction", 
label: "Days Overdue" 
} 
)) || " " 
}); 

} 

scriptContext.response.writePage(form); 

} 

} catch (e) { 
log.debug('Error@On Request', e) 
} 

} 


return {onRequest} 

}); 

Leave a comment

Your email address will not be published. Required fields are marked *