From 6b4a27907ad7eb9b55f0faf6cb5e4bfdf8012aa4 Mon Sep 17 00:00:00 2001 From: Aniket Chouhan Date: Fri, 5 Apr 2024 14:42:43 +0530 Subject: [PATCH 1/3] Implemented support for creating cash refunds in Netsuite. --- .../CashSale/HC_SC_CreateCashRefund.js | 253 ++++++++++++++++++ .../SFTP/HC_SC_CreateSFTPDirectory.js | 9 + .../customscript_hc_sc_createcashrefund.xml | 25 ++ src/deploy.xml | 35 +-- 4 files changed, 307 insertions(+), 15 deletions(-) create mode 100644 src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js create mode 100644 src/Objects/CashSale/customscript_hc_sc_createcashrefund.xml diff --git a/src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js b/src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js new file mode 100644 index 0000000..bcc3d2b --- /dev/null +++ b/src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js @@ -0,0 +1,253 @@ +/** + * @NApiVersion 2.1 + * @NScriptType ScheduledScript + */ + +define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, record, error, search, file) { + + function execute(context) { + try { + // Establish a connection to a remote FTP server + var customRecordSFTPSearch = search.create({ + type: 'customrecord_ns_sftp_configuration', + columns: [ + 'custrecord_ns_sftp_server', + 'custrecord_ns_sftp_userid', + 'custrecord_ns_sftp_port_no', + 'custrecord_ns_sftp_host_key', + 'custrecord_ns_sftp_guid', + 'custrecord_ns_sftp_default_file_dir' + ] + }); + var sftpSearchResults = customRecordSFTPSearch.run().getRange({ + start: 0, + end: 1 + }); + + var sftpSearchResult = sftpSearchResults[0]; + + var sftpUrl = sftpSearchResult.getValue({ + name: 'custrecord_ns_sftp_server' + }); + + var sftpUserName = sftpSearchResult.getValue({ + name: 'custrecord_ns_sftp_userid' + }); + + var sftpPort = sftpSearchResult.getValue({ + name: 'custrecord_ns_sftp_port_no' + }); + + var hostKey = sftpSearchResult.getValue({ + name: 'custrecord_ns_sftp_host_key' + }); + + var sftpKeyId = sftpSearchResult.getValue({ + name: 'custrecord_ns_sftp_guid' + }); + + var sftpDirectory = sftpSearchResult.getValue({ + name: 'custrecord_ns_sftp_default_file_dir' + }); + + sftpDirectory = sftpDirectory + 'cashsale/return'; + sftpPort = parseInt(sftpPort); + + var connection = sftp.createConnection({ + username: sftpUserName, + keyId: sftpKeyId, + url: sftpUrl, + port: sftpPort, + directory: sftpDirectory, + hostKey: hostKey + }); + + log.debug("Connection established successfully with SFTP server!"); + + var list = connection.list({ + path: '/' + }); + + for (var i = 0; i < list.length; i++) { + if (!list[i].directory) { + var fileName = list[i].name; + + // Download the file from the remote server + var downloadedFile = connection.download({ + directory: '/', + filename: fileName + }); + + if (downloadedFile.size > 0) { + log.debug("File downloaded successfully !" + fileName); + var contents = downloadedFile.getContents(); + + // Parse the Return Authorization JSON file + var cashRefundDataList = JSON.parse(contents); + + var errorList = []; + + for (var dataIndex = 0; dataIndex < cashRefundDataList.length; dataIndex++) { + var orderId = cashRefundDataList[dataIndex].order_id; + var itemList = cashRefundDataList[dataIndex].items; + + try { + if (orderId) { + + // Initialize Return Authorization from Sales Order + var cashRefundRecord = record.transform({ + fromType: record.Type.CASH_SALE, + fromId: orderId, + toType: record.Type.CASH_REFUND, + isDynamic: true + }); + + var lineCount = cashRefundRecord.getLineCount({ + sublistId: 'item' + }); + + var removeListline = []; + + for (var j = 0; j < lineCount; j++) { + var matchFound = false; + + var itemid = cashRefundRecord.getSublistValue({ + sublistId: 'item', + fieldId: 'item', + line: j + }); + + var externallineid = cashRefundRecord.getSublistValue({ + sublistId: 'item', + fieldId: 'custcol_hc_order_line_id', + line: j + }); + + for (var itemIndex = 0; itemIndex < itemList.length; itemIndex++) { + var productId = itemList[itemIndex].product_id; + var returnquantity = itemList[itemIndex].quantity; + var returnamount = itemList[itemIndex].amount; + var returnlineid = itemList[itemIndex].external_order_line_id; + var locationid = itemList[itemIndex].location_id; + + // If return item match with sales order item + if (productId === itemid && returnlineid === externallineid) { + matchFound = true; + + cashRefundRecord.selectLine({ + sublistId: 'item', + line: j + }); + + cashRefundRecord.setCurrentSublistValue({ + sublistId: 'item', + fieldId: 'quantity', + value: returnquantity + }); + + // Custom price level + cashRefundRecord.setCurrentSublistValue({ + sublistId: 'item', + fieldId: 'price', + value: "-1" + }); + + cashRefundRecord.setCurrentSublistValue({ + sublistId: 'item', + fieldId: 'amount', + value: returnamount + }); + + + cashRefundRecord.setCurrentSublistValue({ + sublistId: 'item', + fieldId: 'location', + value: locationid + }); + + + cashRefundRecord.commitLine({ + sublistId: 'item' + }); + + } + } + + if (!matchFound) { + removeListline.push(j); + } + } + + // Remove line item are not in return + if (removeListline.length > 0) { + for (var k = removeListline.length - 1; k >= 0; k--) { + var removeitem = removeListline[k] + cashRefundRecord.removeLine({ + sublistId: 'item', + line: removeitem + }); + + } + } + + // Save the Cash refund + var cashRefundId = cashRefundRecord.save(); + + log.debug("Cash refund created for Cash sale with ID: " + orderId + ", Cash refund ID: " + cashRefundId); + + } + } catch (e) { + log.error({ + title: 'Error in processing Cash sales order ' + orderId, + details: e + }); + var errorInfo = orderId + ',' + e.message + '\n'; + errorList.push(errorInfo); + } + } + + // // Archive the file + connection.move({ + from: '/' + fileName, + to: '/archive/' + fileName + }); + + log.debug('File moved! ' + fileName); + + if (errorList.length !== 0) { + var fileLines = 'orderId,errorMessage\n'; + fileLines = fileLines + errorList; + + var date = new Date(); + var errorFileName = date + '-ErrorCashSaleReturn.csv'; + var fileObj = file.create({ + name: errorFileName, + fileType: file.Type.CSV, + contents: fileLines + }); + + connection.upload({ + directory: '/error/', + file: fileObj + }); + } + + } + } + } + } catch (e) { + log.error({ + title: 'Error in creating Cash refund', + details: e + }); + throw error.create({ + name: "Error in creating Cash refund", + message: e + }); + } + } + + return { + execute: execute + }; +}); \ No newline at end of file diff --git a/src/FileCabinet/SuiteScripts/SFTP/HC_SC_CreateSFTPDirectory.js b/src/FileCabinet/SuiteScripts/SFTP/HC_SC_CreateSFTPDirectory.js index bbcd78c..539b964 100644 --- a/src/FileCabinet/SuiteScripts/SFTP/HC_SC_CreateSFTPDirectory.js +++ b/src/FileCabinet/SuiteScripts/SFTP/HC_SC_CreateSFTPDirectory.js @@ -266,6 +266,15 @@ define(['N/sftp', 'N/error', 'N/search'], function (sftp, error, search) { connection.makeDirectory({ path: 'cashsale/export/required_fields_missing' }); + connection.makeDirectory({ + path: 'cashsale/return' + }); + connection.makeDirectory({ + path: 'cashsale/return/archive' + }); + connection.makeDirectory({ + path: 'cashsale/return/error' + }); connection.makeDirectory({ path: 'fulfilledsalesorder' diff --git a/src/Objects/CashSale/customscript_hc_sc_createcashrefund.xml b/src/Objects/CashSale/customscript_hc_sc_createcashrefund.xml new file mode 100644 index 0000000..be93313 --- /dev/null +++ b/src/Objects/CashSale/customscript_hc_sc_createcashrefund.xml @@ -0,0 +1,25 @@ + + + F + HC_SC_CreateCashRefund + F + + T + [/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js] + + + T + DEBUG + SCHEDULED + HC_SC_CreateCashRefund + + + 1 + PT15M + 2023-08-22 + 05:00:00Z + + + + + \ No newline at end of file diff --git a/src/deploy.xml b/src/deploy.xml index 61d20b3..a0302d7 100644 --- a/src/deploy.xml +++ b/src/deploy.xml @@ -4,7 +4,7 @@ - ~/FileCabinet/SuiteScripts/CashSale/HC_MR_ExportedCashSaleCSV.js + + + ~/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js + - ~/Objects/CustomRecord/customrecord_hc_last_runtime_export.xml - ~/Objects/CustomRecord/customrecord_ns_sftp_configuration.xml + - ~/Objects/Customer/custtab_hc_entity_tab.xml - ~/Objects/SalesOrder/custtab_hc_tab.xml + - ~/Objects/InventoryAdjustment/custbody_hc_inventory_adj_number.xml + - ~/Objects/SalesOrder/custform_hc_sales_order_form.xml + - ~/Objects/CashSale/custimport_add_cashsale_hc.xml + - ~/Objects/CashSale/customscript_export_cashsale.xml + + + ~/Objects/CashSale/customscript_hc_sc_createcashrefund.xml - ~/Objects/CashSale/customsearch_hc_export_cashsales.xml + ~/Translations/* From f661bc7614cface167ae2f619b0244aa9ddd2a6e Mon Sep 17 00:00:00 2001 From: Aniket Chouhan Date: Fri, 5 Apr 2024 14:52:23 +0530 Subject: [PATCH 2/3] Uncommented deployment configurations in deploy.xml --- src/deploy.xml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/deploy.xml b/src/deploy.xml index a0302d7..8eb071b 100644 --- a/src/deploy.xml +++ b/src/deploy.xml @@ -4,7 +4,7 @@ - + ~/FileCabinet/SuiteScripts/TransferOrder/HC_MR_ExportedStoreTOFulfillmentCSV.js ~/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js - + ~/Objects/CustomRecord/customrecord_hc_last_runtime_export.xml + ~/Objects/CustomRecord/customrecord_ns_sftp_configuration.xml - + ~/Objects/Customer/custtab_hc_entity_tab.xml + ~/Objects/SalesOrder/custtab_hc_tab.xml - + ~/Objects/InventoryTransfer/custbody_hc_inventory_transfer_exp.xml - + ~/Objects/SalesOrder/custform_hc_sales_order_form.xml - + ~/Objects/InventoryTransfer/custimport_inventory_transfer_hc.xml - + ~/Objects/TransferOrder/customscript_exp_store_to_fulfillment.xml ~/Objects/CashSale/customscript_hc_sc_createcashrefund.xml - + ~/Objects/TransferOrder/customsearch_hc_exp_store_to_fulfillment.xml ~/Translations/* From e49a32dc75813a1432f8b63b62c22f25a083af26 Mon Sep 17 00:00:00 2001 From: Aniket Chouhan Date: Thu, 18 Apr 2024 14:37:58 +0530 Subject: [PATCH 3/3] code formatting --- .../CashSale/HC_SC_CreateCashRefund.js | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js b/src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js index bcc3d2b..1049999 100644 --- a/src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js +++ b/src/FileCabinet/SuiteScripts/CashSale/HC_SC_CreateCashRefund.js @@ -71,7 +71,6 @@ define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, for (var i = 0; i < list.length; i++) { if (!list[i].directory) { var fileName = list[i].name; - // Download the file from the remote server var downloadedFile = connection.download({ directory: '/', @@ -84,7 +83,6 @@ define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, // Parse the Return Authorization JSON file var cashRefundDataList = JSON.parse(contents); - var errorList = []; for (var dataIndex = 0; dataIndex < cashRefundDataList.length; dataIndex++) { @@ -93,7 +91,6 @@ define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, try { if (orderId) { - // Initialize Return Authorization from Sales Order var cashRefundRecord = record.transform({ fromType: record.Type.CASH_SALE, @@ -158,43 +155,35 @@ define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, value: returnamount }); - - cashRefundRecord.setCurrentSublistValue({ - sublistId: 'item', - fieldId: 'location', - value: locationid - }); - + cashRefundRecord.setCurrentSublistValue({ + sublistId: 'item', + fieldId: 'location', + value: locationid + }); cashRefundRecord.commitLine({ sublistId: 'item' }); - } } - if (!matchFound) { removeListline.push(j); } } - // Remove line item are not in return if (removeListline.length > 0) { for (var k = removeListline.length - 1; k >= 0; k--) { - var removeitem = removeListline[k] + var removeitem = removeListline[k] cashRefundRecord.removeLine({ sublistId: 'item', line: removeitem }); - } } - - // Save the Cash refund + // Save the Cash refund var cashRefundId = cashRefundRecord.save(); log.debug("Cash refund created for Cash sale with ID: " + orderId + ", Cash refund ID: " + cashRefundId); - } } catch (e) { log.error({ @@ -205,19 +194,18 @@ define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, errorList.push(errorInfo); } } - - // // Archive the file + // Archive the file connection.move({ from: '/' + fileName, to: '/archive/' + fileName }); - log.debug('File moved! ' + fileName); + log.debug('File moved!' + fileName); if (errorList.length !== 0) { var fileLines = 'orderId,errorMessage\n'; fileLines = fileLines + errorList; - + var date = new Date(); var errorFileName = date + '-ErrorCashSaleReturn.csv'; var fileObj = file.create({ @@ -231,7 +219,6 @@ define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, file: fileObj }); } - } } } @@ -246,7 +233,6 @@ define(['N/sftp', 'N/record', 'N/error', 'N/search', 'N/file'], function (sftp, }); } } - return { execute: execute };