/**
* @NApiVersion 2.1
* @NScriptType fiConnectivityPlugin
* @NModuleScope SameAccount
*/
define([‘N/search’, ‘N/runtime’, ‘SuiteScripts/Jobin & Jismi/Single View Integration INVER/Common Files/jj_cm_single_view_library_inver.js’],
function (search, runtime, singleViewLib) {
let osvLibrary = singleViewLib.library;
const SAVED_SEARCH = {
/**
* Function to search for the accounts in the custom record “Financial Institution Account Mapping”
* @returns {object} accountMappingArray
*/
fetchAccountMappings() {
try {
let accountMappingArray = [];
let accountMappingSearchObj = search.create({
type: “customrecord_jj_fin_connec_acc_map_inver”,
filters:
[
[“isinactive”, “is”, “F”],
],
columns:
[
search.createColumn({ name: “custrecord_jj_acc_mapping_key_inver”, label: “Account Mapping Key” }),
search.createColumn({ name: “custrecord_jj_display_name_inver”, label: “Display Name” }),
search.createColumn({ name: “custrecord_jj_account_type_inver”, label: “Account Type” }),
search.createColumn({ name: “custrecord_jj_currency_inver”, label: “Currency” }),
search.createColumn({ name: “custrecord_jj_group_name_inver”, label: “Group Name” })
]
});
let searchResultCount = accountMappingSearchObj.runPaged().count;
log.debug(” result count”, searchResultCount);
if (searchResultCount > 0) {
accountMappingSearchObj.run().each(function (result) {
let accountMappingObj = {};
accountMappingObj.mappingKey = result.getValue({ name: “custrecord_jj_acc_mapping_key_inver”, label: “Account Mapping Key” });
accountMappingObj.displayName = result.getValue({ name: “custrecord_jj_display_name_inver”, label: “Display Name” });
accountMappingObj.accountType = result.getValue({ name: “custrecord_jj_account_type_inver”, label: “Account Type” });
accountMappingObj.currency = result.getValue({ name: “custrecord_jj_currency_inver”, label: “Currency” });
accountMappingObj.groupName = result.getValue({ name: “custrecord_jj_group_name_inver”, label: “Group Name” });
accountMappingArray.push(accountMappingObj);
return true;
});
}
log.debug(“accountMappingArray”, accountMappingArray);
return accountMappingArray;
}
catch (e) {
log.error(“Error @ fetchAccountMappings”, e);
return [];
}
},
/**
* Function to fetch the internal id of the subsidiary using the account mapping key
* @param {number} accountInternalId – Internal id of the account
* @returns {object} subsidiaryObj – object containing internal id and name
*/
fetchBankAccountInfo(accountInternalId) {
try {
let accountObj = search.lookupFields({
type: search.Type.ACCOUNT,
id: accountInternalId,
columns: [‘name’, ‘subsidiary’, ‘custrecord_jj_osv_acc_number_inver’]
});
log.debug(“account Obj”, accountObj);
return accountObj;
}
catch (e) {
log.error(“Error @ fetchBankAccountInfo”, e);
return {};
}
},
/**
* Function to fetch the company credentials based on the subsidiary from Single View Company Credentials-NODE custom record
* @param {object} subsidiary – Internal id of subsidiary
* @returns {object} subsidiaryCredentialsObj – company credentials
*/
fetchNodeSubsidiaryCredentials(subsidiary) {
try {
let customRecordCompanyNodeSearchObj = search.create({
type: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_CREDENTIALS_REC,
filters:
[
[“isinactive”, “is”, “F”],
“AND”,
[osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_ID, “anyof”, subsidiary]
],
columns:
[
search.createColumn({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_CLIENT_ID, label: “Node Client Id” }),
search.createColumn({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_CLIENT_SECRET, label: “Node Client Secret” }),
search.createColumn({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_SIGNATURE, label: “Node Signature” }),
search.createColumn({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_USER_ID, label: “Node USer Name” }),
]
});
let searchResultCount = customRecordCompanyNodeSearchObj.runPaged().count;
let subsidiaryCredentialsObj = {};
if (searchResultCount > 0) {
customRecordCompanyNodeSearchObj.run().each(function (result) {
subsidiaryCredentialsObj.nodeClientId = result.getValue({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_CLIENT_ID, label: “Node Client Id” });
subsidiaryCredentialsObj.nodeClientSecret = result.getValue({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_CLIENT_SECRET, label: “Node Client Secret” });
subsidiaryCredentialsObj.nodeSignature = result.getValue({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_SIGNATURE, label: “Node Signature” });
subsidiaryCredentialsObj.nodeUserId = result.getValue({ name: osvLibrary.NODE_COMPANY_REC_FIELDS.NODE_COMPANY_USER_ID, label: “Node USer Name” });
});
}
return subsidiaryCredentialsObj;
}
catch (e) {
log.error(“Error @ fetchNodeSubsidiaryCredentials”, e);
return {};
}
},
}
const DATA_PROCESS = {
/**
* Checks if NODE credentials are available.
* @param {object} integrationCredentials – The integration credentials object.
* @returns {boolean} – True if NODE credentials are available, false otherwise.
*/
hasNodeCredentials(integrationCredentials) {
try {
if (
osvLibrary.checkForParameter(integrationCredentials.nodeBaseUrl) &&
osvLibrary.checkForParameter(integrationCredentials.nodeClientId) &&
osvLibrary.checkForParameter(integrationCredentials.nodeClientSecret) &&
osvLibrary.checkForParameter(integrationCredentials.nodeSignatureKey)
) {
return true;
}
}
catch (e) {
log.error(“Error @ hasNodeCredentials”, e);
return false;
}
},
/**
* Checks if MULE credentials are available.
* @param {object} integrationCredentials – The integration credentials object.
* @returns {boolean} – True if MULE credentials are available, false otherwise.
*/
hasMuleCredentials(integrationCredentials) {
try {
if (
osvLibrary.checkForParameter(integrationCredentials.muleBaseUrl) &&
osvLibrary.checkForParameter(integrationCredentials.muleClientId) &&
osvLibrary.checkForParameter(integrationCredentials.muleClientSecret) &&
osvLibrary.checkForParameter(integrationCredentials.muleAccessToken))
return true;
}
catch (e) {
log.error(“Error @ hasMuleCredentials”, e);
return false;
}
},
/**
* Function to create the request body for Node API request to be sent to the single view
* @param {object} accountObj – account record details
* @param {string} userName – user name from the node subsidiary based custom record
* @param {object} accountRequest
* @returns {object} paymentRequestBody – Payment JSON request for NODE
*/
setNodeStatementRequestBody(accountObj, userName, accountRequest) {
try {
let mappingKey = accountRequest.accountMappingKey;
if (mappingKey == “217”) {
mappingKey = accountObj.custrecord_jj_osv_acc_number_inver;
}
let stmtRequestBody = ‘{“svStmtServiceRQ”: {“groupCode”: “‘ + accountObj.parentName + ‘”, “company”: [{“companyCode”: “‘ + accountObj.subsidiaryName + ‘”, “userName”: “‘ + userName + ‘”, “statement”: [{“acERPcode”: “‘ + mappingKey + ‘”, “fromDate”: “‘ + accountRequest.dataStartTime + ‘”, “toDate”: “‘ + accountRequest.dataEndTime + ‘”}]}]}}’
return stmtRequestBody;
}
catch (e) {
log.error(“Error @ setNodeStatementRequestBody”, e);
return {};
}
},
/**
* Function to create the request body to be sent to the single view
* @param {object} accountRequest – account request object
* @param {object} accountObj – payment record details
* @param {string} signatureCode – signature
* @returns {object} stmtRequestBody – Payment JSON request for MULE
*/
setMuleStmtRequestBody(accountRequest, accountObj, signatureCode) {
try {
let stmtRequestBody = `{
“Message”: {
“OSVAccountStatementRequest”: {
“FromDate”: “2023-11-05T08:00:00”,
“ToDate”: “2023-11-07T12:00:00”,
“DateTimeStamp”: “2023-12-20T07:30:00”,
“TransactionType”: “940”,
“OSVPaymentInfoMessage”: [
{
“OSVPaymentInfoRequest”: {
“BankCode”: “RIYADH”,
“CompanyCode”: “SPRT001”,
“B2BIdentifier”: “”,
“B2BUserId”: “”,
“B2BUrn”: “”,
“B2BAggrId”: “”,
“AccountNumbers”: {
“AccountNumber”: [
{
“AccNumber”: “2453030309943”
}
]
}
}
}
]
}
},
“Signature”: “dbngDVCoBzSzCsSA4a77Nzrvx6ydnxU+ej6G/VhoZmy2JswgHNitgsV7jC86k/8tiOYi1zDgZegzqj3Na5N6Kct2ljRKuRknhw0UBwS3uswcZyrUyvlfw2WQVxZKFdEzCGiKizLI8mYUbagflep076xtaW1hTOiJuxR5nfFWfm2SL3ZkiNZ1QMwV7oiyR+VbM34kKuhiyuewa7i4j08vhTn+hh3YGVALpJPcBNJfp0ZpWPnIqyrMy+nHhoy2MVNd2KDKXpdDJyoi8TD5Py8ojbGmRwBVH33hsd0GGzVPojhLsZSvq047qcwO5o2ov6DJ9vdcIhQTiFyDfKdMv4p3kQ==”
}`
log.debug(“MULE Request”, stmtRequestBody);
return stmtRequestBody;
}
catch (e) {
log.error(“Error @ setMuleStmtRequestBody”, e);
return {};
}
},
/**
* Perform integration using the NODE API
* @param {object} accountRequest – account Request object.
* @param {object} integrationCredentialObj – The integration credentials object.
*/
performNodeStmtIntegration(accountRequest, integrationCredentialObj) {
try {
log.debug(“Inside”, “********* performNodeStmtIntegration **************”);
let accountObj = SAVED_SEARCH.fetchBankAccountInfo(accountRequest.accountMappingKey);
if (osvLibrary.checkForParameter(accountObj)) {
let subsidiaryCredentials = SAVED_SEARCH.fetchNodeSubsidiaryCredentials(accountObj.subsidiary[0].value);
log.debug(“subsidiaryNodeCredentials”, subsidiaryCredentials);
if (Object.entries(subsidiaryCredentials).length > 0) {
// Splitting the text by ‘:’ to separate parent and subsidiary names
let textParts = accountObj.subsidiary[0].text.split(‘:’);
// The last part will always be the subsidiary name
accountObj.subsidiaryName = textParts[textParts.length – 1].trim();
// The rest will be the parent name
accountObj.parentName = textParts.slice(0, –1).join(‘:’).trim();
log.debug(“Parent Name:”, accountObj);
let stmtRequestBody = DATA_PROCESS.setNodeStatementRequestBody(accountObj, subsidiaryCredentials.nodeUserId, accountRequest);
log.debug(‘Statement Request Body’, stmtRequestBody);
let signatureCode = osvLibrary.getSignatureCode(subsidiaryCredentials.nodeSignature, stmtRequestBody);
subsidiaryCredentials.signature = signatureCode.toLowerCase();
let nodeStmtUrl = osvLibrary.ONE_SINGLE_VIEW_API_REQUESTS.POST_STATEMENT;
subsidiaryCredentials.nodeBaseUrl = integrationCredentialObj.nodeBaseUrl;
let stmtApicall = osvLibrary.requestSingleView(nodeStmtUrl, “POST”, stmtRequestBody, subsidiaryCredentials);
if (stmtApicall != “Unauthorized”) {
log.debug(‘stmtApicall inside’, stmtApicall);
return stmtApicall;
}
else {
return {};
}
}
}
}
catch (e) {
log.error(‘Error @ performNodeIntegration’, e);
return {};
}
},
/**
* Perform integration using the NODE API
* @param {object} accountRequest – The payment object.
* @param {object} integrationCredentialObj – The integration credentials object.
*/
performMuleStmtIntegration(accountRequest, integrationCredentialObj) {
try {
log.debug(“Inside”, “********* performMuleStmtIntegration **************”);
let accountObj = SAVED_SEARCH.fetchBankAccountInfo(accountRequest.accountMappingKey);
if (accountObj) {
let textParts = accountObj.subsidiary[0].text.split(‘:’);
// subsidiary name
accountObj.subsidiaryName = textParts[textParts.length – 1].trim();
let signatureCode = “dbngDVCoBzSzCsSA4a77Nzrvx6ydnxU+ej6G/VhoZmy2JswgHNitgsV7jC86k/8tiOYi1zDgZegzqj3Na5N6Kct2ljRKuRknhw0UBwS3uswcZyrUyvlfw2WQVxZKFdEzCGiKizLI8mYUbagflep076xtaW1hTOiJuxR5nfFWfm2SL3ZkiNZ1QMwV7oiyR+VbM34kKuhiyuewa7i4j08vhTn+hh3YGVALpJPcBNJfp0ZpWPnIqyrMy+nHhoy2MVNd2KDKXpdDJyoi8TD5Py8ojbGmRwBVH33hsd0GGzVPojhLsZSvq047qcwO5o2ov6DJ9vdcIhQTiFyDfKdMv4p3kQ==”;
let stmtRequestBody = DATA_PROCESS.setMuleStmtRequestBody(accountRequest, accountObj, signatureCode);
let muleStmtUrl = osvLibrary.ONE_SINGLE_VIEW_API_REQUESTS.POST_MULE_STATEMENT;
let stmtApiResponse = osvLibrary.requestSingleView_Mule(muleStmtUrl, “POST”, stmtRequestBody, integrationCredentialObj);
log.debug(‘paymentApicall Response >>’, stmtApiResponse);
if (stmtApiResponse.errorMessage != “UNAUTHORIZED” && stmtApiResponse.errorMessage != “BAD_REQUEST”) {
return stmtApiResponse;
}
else {
return {};
}
}
}
catch (e) {
log.error(“Error @ performMuleStmtIntegration”, e);
return {};
}
}
}
function getAccounts(context) {
try {
let configurationId = context.pluginConfiguration.getConfigurationFieldValue({ fieldName: “configuration_id” });
log.audit(“Plugin executed with Config ID “ + configurationId, new Date());
let accountDetailArray = SAVED_SEARCH.fetchAccountMappings(configurationId);
if (accountDetailArray.length > 0) {
accountDetailArray.forEach(function (accountDetail) {
context.addAccount({
accountMappingKey: accountDetail.mappingKey,
displayName: accountDetail.displayName,
accountType: accountDetail.accountType,
currency: accountDetail.currency,
groupName: accountDetail.groupName,
});
});
}
}
catch (e) {
log.error(“Error @ getAccounts”, e);
}
}
function getTransactionData(context) {
try {
let accountRequests = JSON.parse(context.accountRequestsJSON);
log.debug(“accountRequests”, accountRequests);
if (accountRequests) {
let integrationCredentials = osvLibrary.apiConfigfileSearch();
log.debug(“integrationCredentials”, integrationCredentials);
let integrationType;
// Determine the integration type based on the available credentials
switch (true) {
case DATA_PROCESS.hasNodeCredentials(integrationCredentials) && DATA_PROCESS.hasMuleCredentials(integrationCredentials):
case DATA_PROCESS.hasNodeCredentials(integrationCredentials):
integrationType = “NODE”;
break;
case DATA_PROCESS.hasMuleCredentials(integrationCredentials):
integrationType = “MULE”;
break;
default:
return;
}
log.debug(“INTEGRATION TYPE >>”, integrationType);
let stmtResponseArray = [];
accountRequests.forEach(function (accountRequest) {
log.debug(“Processing Account”, “Account ID: “ + accountRequest.accountMappingKey);
let stmtResponse = {};
// Perform integration based on the determined type
switch (integrationType) {
case “NODE”:
stmtResponse = DATA_PROCESS.performNodeStmtIntegration(accountRequest, integrationCredentials);
log.debug(“Returned Respose NODE”, stmtResponse);
if (osvLibrary.checkForParameter(stmtResponse)) {
stmtResponseArray.push(stmtResponse);
}
break;
case “MULE”:
stmtResponse = DATA_PROCESS.performMuleStmtIntegration(accountRequest, integrationCredentials);
log.debug(“Returned Respose MULE “, stmtResponse);
if (osvLibrary.checkForParameter(stmtResponse)) {
stmtResponseArray.push(stmtResponse);
}
break;
default:
return;
}
});
context.addDataChunk({ dataChunk: JSON.stringify(stmtResponseArray) });
context.returnAccountRequestsJSON({ accountsJson: context.accountRequestsJSON });
log.debug(“<< Remaining Governance >>”, runtime.getCurrentScript().getRemainingUsage());
log.debug(“Transaction Data”, “Transaction data processing completed.”);
}
}
catch (e) {
log.error(“Error @ getTransactionData”, e);
}
}
return {
getAccounts: getAccounts,
getTransactionData: getTransactionData
};
});