The following script can be used for the endpoint for displaying the customer statement PDF from externally using the encrypted parameters. The parameters are encrypted using the XOR algorithm.
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/render', 'N/search'],
/**
* @param{record} record
* @param{render} render
* @param{format} format
* @param{search} search
*/
(render, search) => {
"use strict";
/**
* Function to check whether the field has an empty value or not.
* @param {parameter} parameter - fieldValue
* @returns {boolean} true - if the value is not empty
* @returns {boolean} false - if the value is empty
*/
function checkForParameter(parameter) {
try {
if (parameter != "" && parameter != null && parameter != undefined && parameter != "null" && parameter != "undefined" && parameter != " " && parameter != false && parameter != {}) {
return true;
} else {
return false;
}
} catch (e) {
log.error({
title: "Error @ empty check Function: ",
details: e.name + ' : ' + e.message
})
return false;
}
}
/**
* Function to format the date using saved search
* @param {*} customerId customer id
* @param {*} startDate start date
* @param {*} statementDate statement date
* @returns
*/
function formatDate(customerId, startDate, statementDate) {
try {
let dateObject = {};
let customerSearchObj = search.create({
type: "customer",
filters:
[
["stage", "anyof", "CUSTOMER"],
"AND",
["internalid", "anyof", customerId]
],
columns:
[
search.createColumn({
name: "formuladate",
formula: "to_date('" + startDate + "', 'dd-mm-yyyy')",
label: "start_Date"
}),
search.createColumn({
name: "formuladate",
formula: "to_date('" + statementDate + "', 'dd-mm-yyyy')",
label: "statement_date"
}),
]
});
customerSearchObj.run().each(function (result) {
dateObject.startDate = result.getValue(customerSearchObj.columns[0]);
dateObject.statementDate = result.getValue(customerSearchObj.columns[1])
return false;
});
log.debug("formattedStartDate", dateObject.startDate);
log.debug("formattedStatementDate", dateObject.statementDate);
return dateObject;
} catch (e) {
log.error('error @ formatDate', e);
return {};
}
}
/**
* Defines the Suitelet script trigger point.
* @param {Object} scriptContext
* @param {ServerRequest} scriptContext.request - Incoming request
* @param {ServerResponse} scriptContext.response - Suitelet response
* @since 2015.2
*/
const onRequest = (scriptContext) => {
try {
const XORCipher = {
encode: function encode(key, data) {
data = this.xor_encrypt(key, data);
return this.b64_encode(data);
},
decode: function decode(key, data) {
data = this.b64_decode(data);
return this.xor_decrypt(key, data);
},
b64_table: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
b64_encode: function b64_encode(data) {
let o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
r,
i = 0,
enc = "";
if (!data) {
return data;
}
do {
o1 = data[i++];
o2 = data[i++];
o3 = data[i++];
bits = o1 << 16 | o2 << 8 | o3;
h1 = bits >> 18 & 0x3f;
h2 = bits >> 12 & 0x3f;
h3 = bits >> 6 & 0x3f;
h4 = bits & 0x3f;
enc += this.b64_table.charAt(h1) + this.b64_table.charAt(h2) + this.b64_table.charAt(h3) + this.b64_table.charAt(h4);
} while (i < data.length);
r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + "===".slice(r || 3);
},
b64_decode: function b64_decode(data) {
let o1,
o2,
o3,
h1,
h2,
h3,
h4,
bits,
i = 0,
result = [];
if (!data) {
return data;
}
data += "";
do {
h1 = this.b64_table.indexOf(data.charAt(i++));
h2 = this.b64_table.indexOf(data.charAt(i++));
h3 = this.b64_table.indexOf(data.charAt(i++));
h4 = this.b64_table.indexOf(data.charAt(i++));
bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
o1 = bits >> 16 & 0xff;
o2 = bits >> 8 & 0xff;
o3 = bits & 0xff;
result.push(o1);
if (h3 !== 64) {
result.push(o2);
if (h4 !== 64) {
result.push(o3);
}
}
} while (i < data.length);
return result;
},
keyCharAt: function keyCharAt(key, i) {
return key.charCodeAt(Math.floor(i % key.length));
},
xor_encrypt: function xor_encrypt(key, data) {
let rta = [];
for (let i = 0; i < data.length; i++) {
let c = data[i];
rta.push(c.charCodeAt(0) ^ this.keyCharAt(key, i));
}
return rta;
},
xor_decrypt: function xor_decrypt(key, data) {
let rta = [];
for (let i = 0; i < data.length; i++) {
let c = data[i];
rta.push(String.fromCharCode(c ^ this.keyCharAt(key, i)));
}
return rta.join("");
}
};
let parameterValue = scriptContext.request.parameters;
log.debug('parameterValue', parameterValue);
let customerId = parameterValue.custId;
let startDate = parameterValue.startDate;
let statementDate = parameterValue.statementDate;
let openTransactionsOnly = parameterValue.openTransactionsOnly == 1 ? true : false;
let timeStamp = Date.parse(new Date()).toString();
let customerIdDecrypted = Number(XORCipher.decode(timeStamp, customerId));
log.debug('customerIdDecrypted', customerIdDecrypted);
let dateObject = formatDate(customerIdDecrypted, startDate, statementDate);
log.debug('dateObject', dateObject);
if (checkForParameter(customerIdDecrypted) && checkForParameter(dateObject.startDate) && checkForParameter(dateObject.statementDate)) {
log.debug("inside");
log.debug("startDate", startDate);
log.debug("statementDate", statementDate);
let transactionFile = render.statement({
entityId: customerIdDecrypted,
printMode: render.PrintMode.PDF,
inCustLocale: true,
startDate: dateObject.startDate,
statementDate: dateObject.statementDate,
openTransactionsOnly: openTransactionsOnly
});
log.debug("TransactionFile", transactionFile);
scriptContext.response.writeFile(transactionFile, true);
}
} catch (e) {
log.error('error @ onRequest', e);
}
}
return { onRequest }
});