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}
});