Creating a Custom Plug-in Implementation for E-Document Custom Data Source
A custom plug-in implementation for custom data source will enable you to add custom data sources to an e-document template. With a custom data source plug-in specified in an e-document template, you can add to e-documents more field values from the transactions that the e-documents will be generated from.
Similarly, you can also use a custom plug-in implementation to add custom data sources to transaction response body. In case of transaction response, an extra parameter is added (E-Document Transaction Response) where you can add field values from transaction response record as well.
/**
* @NApiVersion 2.x
* @NScriptType plugintypeimpl
* @NModuleScope Public
*/
define(["N/render"], function (nsrender) {
/**
* inject - This function will provide the custom data source during the generation process
* @param {Object} params
* @param {String} params.transactionId
* @param {Object} params.transactionRecord
* @param {Object} params.transactionResponseRecId (only present if this data source is being used to create transaction response's response body)
*
* @returns {Object} result
* @returns {render.DataSource} result.alias
* @returns {string} result.format
* @returns {Object | Document | string} result.data
* @returns {Object} result
* @returns {Boolean} result.success
* @returns {string} result.eiAuditTrailMsg
*/
function inject(params) {
var txnRecord = params.transactionRecord;
var txnId = params.transactionId;
// var transResponseId = params.transactionResponseId;
var customObj = {};
log.debug("Custom Object", customObj);
return {
customDataSources: [
{
format: nsrender.DataSource.OBJECT,
alias: "custom",
data: customObj
}
],
result: {
success: true,
eiAuditTrailMsg: "Custom Data Source executed successfully"
}
};
}
return {
inject: inject
};
});
You must create a custom plug-in implementation for custom data source first and then implement it in NetSuite so that it will be available for selection on the e-document template record. Create a JavaScript file for the custom data source plug-in implementation. The JavaScript file must be compatible with SuiteScript 2.0.
This sample script uses the define
function, which is required for an entry point script (a script you attach to a script record and deploy). You must use the require
function if you want to copy the script into the SuiteScript Debugger and test it. For more information, see SuiteScript Debugger SuiteScript Debugger.
The following code is a sample custom plug-in implementation for e-document custom data source.
* @NApiVersion 2.x
* @NScriptType plugintypeimpl
* @NModuleScope Public
*/
define(["N/render"], function(nsrender) {
/**
* inject - This function will provide the custom data source during the generation process
* @param {Object} params
* @param {String} params.transactionId
* @param {Object} params.transactionRecord
* @param {Number} params.userId
*
* @returns {Object} result
* @returns {render.DataSource} result.alias
* @returns {string} result.format
* @returns {Object | Document | string} result.data
* @returns {Object} result
* @returns {Boolean} result.success
* @returns {string} result.eiAuditTrailMsg
*/
function inject(params) {
var txnRecord = params.transactionRecord;
var txnId = params.transactionId;
var userId = params.userId
var customObj = {};
log.debug("Custom Object", customObj);
return {
customDataSources: [
{
format: nsrender.DataSource.OBJECT,
alias: "custom",
data: customObj
}
],
result: { //Optional
success:true, // Mandatory. Datatype: Boolean (true/false)
eiAuditTrailMsg:"Custom Data Source executed successfully." //Optional. Datatype: String
}
};
}
return {
inject: inject
};
});
This script takes the input parameters from the JSON object. The parameters of this object are listed in the following table.
Parameter |
Type |
Description |
Remarks |
---|---|---|---|
transactionRecord.type |
String |
The type of transaction being validated. |
The id and type parameters provide information about thetransaction being validated. You can use themtogether to reference any field value of thetransaction using search.lookupFields(options) or record.load(options) |
transactionRecord.id |
Number |
The internal ID of the transaction being validated. |
|
transactionId |
String |
The internal ID of the transaction being validated. |
The id provide information about the transaction's internal ID. |
userId |
Number |
This field holds the internal ID of the current logged in user. |
This field value can be used wherever there is a requirement to refer to the current logged in user. For example, to update e-document audit trail by shared module API, userId can be used in owner property. |
The custom data source plug-in implementation script must have the @NSScriptType plugintypeimpl
.
After creating the script for plug-in implementation, upload it to Customization > Plug-ins > Plug-in Implementations > New. The type of the custom plug-in implementation must “Custom Data Source for E-Document”. For more information, see Custom Plug-in Creation, TemplateRenderer.addCustomDataSource(options) and Using Custom Data Sources for Advanced Printing.
The following are guidelines for custom data sources:
-
Naming convention - Element names must not begin with digits
-
Do not add a large amount of data to the data object in customDataSource. This may result in an Out of Memory error.
Setting E-Document Status to Generation Failed Through Custom Data Source
You can set Generation Failed status in the E-Document Status field of a transaction. The Generation Failed status is used to reduce the time taken to re-generate the e-document, if the e-document is not generated as expected. To do this, a custom data source plug-in implementation response is used which enables the logging of an audit trail message. The audit trail message informs the success or failure of the plug-in's implementation.
You can decide if the e-document generation fails or continues further by using a validation logic. The validation informs if the e-document is generated successfully or not with an audit trail message in the custom data source plug-in implementation.
If the validation is successful, the e-document is generated and the audit trail displays the corresponding e-document generation successful message.
If the validation fails, the e-document generation also fails and the audit trail displays the corresponding e-document generation failed message.
To do so, you can add the result property in the return object of inject function. This result property is optional, and the result property contains two properties (success and eiAuditTrailMsg).
The following table contains the details of the properties in the result property.
Property |
Description |
---|---|
success |
The property’s value is boolean (true or false). This property is required if the result property exists. If the value is false, the e-document generation will fail, and the E-Document Status field will be set to Generation Failed. If the value is true, the custom data source execution will be successful. |
eiAuditTrailMsg |
The property’s value is a string. This property is optional. If this property’s value is present in the result property with a non-empty string, the value will be added in the e-document audit trail. Else, a default message will be added in the e-document audit trail based on the success property value. Default message for success false in audit trail: Execution of custom data source plug-in implementation has failed. Default message for success true in audit trail: Execution of custom data source plug-in implementation has been successful. |
If the datasource provided by your implementation is in the following format:
return {
customDataSources: [
{
format: nsrender.DataSource.OBJECT,
alias: "custom",
data: {isOneWorldEnabled: true}
}
],
result: { //Optional
success: false, //Mandatory
eiAuditTrailMsg: "CDS Custom Error" //Optional
}
};
You can now include the following custom data in the e-document template by using the datasource format.
-
For XML e-document:
<xml> ${custom.isOneWorldEnabled} </xml>
-
For JSON e-document:
{ "key": "${custom.isOneWorldEnabled}" }
QR String Generation
The QR string generation logic can be implemented in Custom Data Source Plug-in Implementation. After successful implementation of the QR logic, generated string can be populated in custbody_psg_ei_qr_string. It is hidden and present in transaction record, using Custom Data Source as illustrated in Sample QR Code Plug-in Implementation(Custom Data Source). This populated field can be used in Advanced PDF/HTML Template to display QR code in generated e-document PDF.
QR Code Preview
To generate a preview of QR code in the transaction record under E-Document subtab, custbody_psg_ei_qr_code field (rich text) can be updated with img tag containing the source of data URL for the QR code value as illustrated in Sample QR Code Plug-in Implementation(Custom Data Source). The data URL for QR code value can be generated using any library which is capable of generating data URL from a string.
Sample QR Code Plug-in Implementation(Custom Data Source)
This is an example of QR Code Plug-in implementation (CDS). It shows example usage where SS2.0 can be used to:
-
Show QR code preview in Transaction form by generating data URL and using it to update custbody_psg_ei_qr_code field. This is a rich text field that can be used to display the QR code preview on transaction record.
-
Populate custbody_psg_ei_qr_string, a hidden field that can be used as a data source in any Advanced PDF/HTML Template to display QR Code in generated PDF.
/**
* @NApiVersion 2.x
* @NScriptType plugintypeimpl
* @NModuleScope Public
*/
// Give the relative path of qrcode-generator module responsible for generation of data URL from QR code value
define(["N/encode", "N/render", "N/record", "./qrcode-generator"], function (encode, nsrender, record, qrCodeGen) {
// Implement the logic to return QR string from the input QR data passed
function getQRCodeString(inputQRData) {
var qrString = '';
/*
* QR logic implementation goes here, with 'inputQRData' parameter object containing the required properties for generating QR string stored in qrString variable
*/
return qrString;
}
// Function returns the encoded base 64 value of the string passed
function getBase64(qrstring) {
return encode.convert({
string: qrstring,
inputEncoding: encode.Encoding.UTF_8,
outputEncoding: encode.Encoding.BASE_64_URL_SAFE
});
}
// Function returns img element which contains the QR Code preview image
function getQRCodePreview(qrBase64) {
var qrDataUrl = '';
/*
* Here 3rd party library can be used to convert the 'qrBase64' string to data url generation from QR code value, as 'qrCodeGen' is imported in this example
*/
if (qrDataUrl) {
return '<img alt="QR code" src="'+ qrDataUrl + '" style="display: inline-block; width: 80px; height: 80px;"></img>';
}
return '';
}
function inject(params) {
var tranType = params.transactionRecord.type;
var tranId = params.transactionRecord.id;
// Hidden QR string field in transaction record
var QR_CODE_FLD = "custbody_psg_ei_qr_string";
// QR preview field in transaction record
var QR_CODE_PREVIEW_FLD = "custbody_psg_ei_qr_code";
var updateQRFlds = {};
var qrCustomObj = {};
/*
* Read the fields of transaction required for QR value generation and pass them to getQRCodeString function as shown below where QR logic can be implemented
* Ex:
* var data = {
* sellerName: subsidiaryLegal,
* vatNumber: vatRegistrationNo.toString(),
* invoiceTimeStamp: transDate.toISOString(),
* invoiceTotal: totalAmount.toString(),
* invoiceVatTotal: totalTax.toString(),
* };
*/
//Pass the QR Code input data to return QR string
var qrString = getQRCodeString(data);
//Pass the QR string to get the encoded Base 64
var qrBase64 = getBase64(qrString);
if(qrBase64)
{
// qrCustomObj will be sent as part of inject function response which can be used in e-document template which is shown in the below example
qrCustomObj = {
qrCode : qrBase64
};
// Update QR hidden text field to display in generated e document PDF
updateQRFlds[QR_CODE_FLD] = qrBase64;
// Update QR preview field only to display QR code in transaction form under E-document subtab
updateQRFlds[QR_CODE_PREVIEW_FLD] = getQRCodePreview(qrBase64);
// Submitting the QR fields which needs to be updated
record.submitFields({
type: tranType,
id: tranId,
values: updateQRFlds
});
}
return {
customDataSources: [
{
format: nsrender.DataSource.OBJECT,
alias: "qrData",
data: qrCustomObj
}
],
};
}
return {
inject: inject
}
})
You can now include the following custom data of QR code in the e-document template by using the data source format with respect to the alias provided.
-
For XML e-document:
<xml> ${qrData.qrCode} </xml>
-
For JSON e-document:
{ "key": "${qrData.qrCode}" }
Related Topics
- Creating E-Document Templates
- XPath and Regex Examples for E-Document Templates
- PEPPOL Template
- Understanding Inbound E-Document Templates in JSON Format
- Understanding XSD in Inbound E-Document Templates
- Understanding XSD in Outbound E-Document Templates
- Creating a Digital Signature Plug-in Implementation for E-Documents
- Creating an Outbound Validation Plug-in Implementation for E-Documents