Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.25 KB | None | 0 0
  1. /********************************************************************************
  2. Copyright 2016 Lexmark International, Inc. All Rights Reserved.
  3. Reproduction and distribution of the contents of this work are prohibited without express and prior
  4. written consent of Lexmark International. Use of this work without an active iScript license is prohibited.
  5.  
  6. Name: SendEmailWorkflow.js
  7. Author: Lexmark International, Inc
  8. Created: 02/12/2014-RG
  9. Last Updated: 02/15/2017-JJM
  10. For Version: 6.7+, 7.x
  11. Script Version: $Id$
  12. --------------------------------------------------------------------------------
  13. Summary:
  14. - This script is designed to be used in multiple workflow queues and send an email when a workflow object enters a queue.
  15. - Each queue is defined in a single JSON file.
  16. - The config file (SendEmailWorkflow_config.js) is designed to support the following:
  17. NOTE: each of the settings below are 'per queue' and can be different per queue
  18. ------------------------------------------------------------------------
  19. - HTML emails or ASCII text emails (true/false; not case sensitive)
  20. - Attachments or no attachment (true/false; not case sensitive)
  21. - email address can be a LITERAL, custom property value, or an ImageNow index value
  22. (LITERAL VALUES: field1, field2, field3, field4, field5)
  23. - emailFrom is a literal and can be unique per queue
  24. - Error queue workflow can be turned on or off (leave blank to turn off)
  25. - Success queue workflow can be turned on or off (leave blank to turn off)
  26. - emailSubject and emailBody can include parameters to be populated from a document
  27. or workflow property. See the emailTextToReplace configuration. Does not support
  28. composite custom properties.
  29. - emailBody
  30.  
  31. - The customer can use the same script in multiple queues or a single queue.
  32.  
  33. Mod Summary:
  34. 02/12/2014-RKG: First version.
  35. 10/22/2014-ADD: Added ATTACHMENT_PAGE_NUM to QUEUE.
  36. 11/21/2014-EDW: Added option to send to all users on a queue.
  37. 06/09/2015-KBO: Added ability to use index keys and custom properties as parameters
  38. in the email subject and body.
  39. 10/02/2015-KW: Updated copyright
  40. 12/31/2015-EDW: Converted config file to JSON config, now using getValueFromComplexArray, supports
  41. multiple to address types.
  42. 01/28/2016-WMT: Updated iScriptDebug and added stats object
  43. 05/12/2016-EDW: Updated script to do eForm value extraction (no line items), and support for full dry run
  44. mode.
  45. 01/04/2017-MFC: Addition of getINEmailAddressForUser STL function to use as a massage func when the
  46. doc contains only a username value
  47. 01/25/2017-WJF: Exposed useCDO & useUtility options for email config - Defaults to useCDO
  48. 02/15/2017-JJM: Updated to pass any parameter to iEmail configuration and allow for any emailConfig
  49. parameter to use a complex array configuration.
  50.  
  51. Business Use:
  52. This script is designed to be run as inbound on a workflow queue.
  53.  
  54. Installation Instructions :
  55. All configuration options can be found in the JSON configuration file whose path can be configured
  56. in the #includes. It is (by default) located in inserver6\etc\config\SendEmailWorkflow_config.js.
  57.  
  58.  
  59. *************************************************************************/
  60.  
  61. // ********************* Include additional libraries *******************
  62. //Linked Libraries
  63. #link "inxml" //XML parser
  64. #link "secomobj" //COM object
  65.  
  66. #if defined(imagenowDir6)
  67. // 6.7.0.2717+, including Active-Active support
  68. #include "$IMAGENOWDIR6$/script/STL/packages/Date/convertToDateStr.js"
  69. #include "$IMAGENOWDIR6$/script/STL/packages/Date/convertToDateObj.js"
  70. #include "$IMAGENOWDIR6$/script/STL/packages/Document/exportDocPhsOb.js"
  71. #include "$IMAGENOWDIR6$/script/STL/packages/Document/isValidIndexKey.js"
  72. #include "$IMAGENOWDIR6$/script/STL/packages/Document/setDocNotes.js"
  73. #include "$IMAGENOWDIR6$/script/STL/packages/Email/iEmail.js"
  74. #include "$IMAGENOWDIR6$/script/STL/packages/File/doesFileExist.js"
  75. #include "$IMAGENOWDIR6$/script/STL/packages/Form/FormManager.js"
  76. #include "$IMAGENOWDIR6$/script/STL/packages/Logging/iScriptDebug.js"
  77. #include "$IMAGENOWDIR6$/script/STL/packages/Logging/StatsObject.js"
  78. #include "$IMAGENOWDIR6$/script/STL/packages/Object/getValueFromComplexArray.js"
  79. #include "$IMAGENOWDIR6$/script/STL/packages/Object/hashKeysToUpperCase.js"
  80. #include "$IMAGENOWDIR6$/script/STL/packages/Properties/PropertyManager.js"
  81. #include "$IMAGENOWDIR6$/script/STL/packages/String/escapeForRegExp.js"
  82. #include "$IMAGENOWDIR6$/script/STL/packages/User/getEmailsFromUsers.js"
  83. #include "$IMAGENOWDIR6$/script/STL/packages/User/getINEmailAddressForUser.js"
  84. #include "$IMAGENOWDIR6$/script/STL/packages/Workflow/createOrRouteItem.js"
  85. #include "$IMAGENOWDIR6$/script/STL/packages/Workflow/routeItem.js"
  86.  
  87. #include "$IMAGENOWDIR6$/script/SendEmailWorkflow_config.js" // <-- path to config file
  88. #else
  89. // pre-6.7.0.2717, no Active-Active support
  90. #include "../script/STL/packages/Date/convertToDateStr.js"
  91. #include "../script/STL/packages/Date/convertToDateObj.js"
  92. #include "../script/STL/packages/Document/exportDocPhsOb.js"
  93. #include "../script/STL/packages/Document/isValidIndexKey.js"
  94. #include "../script/STL/packages/Document/setDocNotes.js"
  95. #include "../script/STL/packages/Email/iEmail.js"
  96. #include "../script/STL/packages/File/doesFileExist.js"
  97. #include "../script/STL/packages/Form/FormManager.js"
  98. #include "../script/STL/packages/Logging/iScriptDebug.js"
  99. #include "../script/STL/packages/Logging/StatsObject.js"
  100. #include "../script/STL/packages/Object/getValueFromComplexArray.js"
  101. #include "../script/STL/packages/Object/hashKeysToUpperCase.js"
  102. #include "../script/STL/packages/Properties/PropertyManager.js"
  103. #include "../script/STL/packages/String/escapeForRegExp.js"
  104. #include "../script/STL/packages/User/getEmailsFromUsers.js"
  105. #include "../script/STL/packages/User/getINEmailAddressForUser.js"
  106. #include "../script/STL/packages/Workflow/createOrRouteItem.js"
  107. #include "../script/STL/packages/Workflow/routeItem.js"
  108.  
  109. #include "../script/SendEmailWorkflow_config.js" // <-- path to config file
  110. #endif
  111.  
  112. // ********************* Configuration **************************
  113.  
  114. var CONFIG_VERIFIED = true; // set to true when configuration values have been verified
  115.  
  116. //Document Error Notes Mode
  117. var RESET_DOC_NOTES = false; // true - reset document notes on success, false - do nothing
  118. var DOC_NOTE_MODE = -1; // -1=Do Nothing, 0=overwrite, 1=append, 2=prepend
  119.  
  120. // Logging
  121. var LOG_TO_FILE = true; // false - log to stdout if ran by intool, true - log to inserverXX/log/ directory
  122. var DEBUG_LEVEL = 5; // 0 - 5. 0 least output, 5 most verbose
  123. var SPLIT_LOG_BY_THREAD = false; // set to true in high volume scripts when multiple worker threads are used (workflow, external message agent, etc)
  124. var MAX_LOG_FILE_SIZE = 100; // Maximum size of log file (in MB) before a new one will be created
  125.  
  126. var DRY_RUN = true; //If true, the script will simulate the script execution without making any updates
  127.  
  128. var UNDEFINED_VALUE = "[undefined]"; // default value used in email subject or body when parameter cannot be populated.
  129.  
  130. // ********************* End Configuration *******************
  131.  
  132. // ********************* Initialize global variables ********************
  133.  
  134. var EXECUTION_METHODS = ["WORKFLOW"]; //Allowed script execution methods: WORKFLOW, INTOOL, TASK, EFORM, EMA
  135. var DOC_NOTE_DELIMITER = "\n";
  136.  
  137. var debug, stats, formData, form = false;
  138.  
  139. /** ****************************************************************************
  140. * Main body of script.
  141. *
  142. * @param {none} None
  143. * @returns {void} None
  144. *****************************************************************************/
  145. function main ()
  146. {
  147. try
  148. {
  149. // Logging and verification
  150. debug = new iScriptDebug("USE SCRIPT FILE NAME", LOG_TO_FILE, DEBUG_LEVEL, undefined, {splitLogByThreadID:SPLIT_LOG_BY_THREAD, maxLogFileSize:MAX_LOG_FILE_SIZE});
  151. debug.showINowInfo("INFO");
  152. debug.logAlways("INFO", "Script Version: $Id$\n");
  153. debug.logAlways("INFO", "Script Name: %s\n", _argv[0]);
  154. stats = new StatsObject();
  155.  
  156. if (!CONFIG_VERIFIED)
  157. {
  158. var errorStr = "\nConfiguration not verified. Please verify \n" +
  159. "the defines in the *** Configuration *** section at the top \n" +
  160. "of this script and set CONFIG_VERIFIED to true. Aborting.\n\n";
  161. debug.log('CRITICAL', errorStr);
  162. printf(errorStr);
  163. return false;
  164. }
  165.  
  166. // Check script execution
  167. if (!debug.checkExecution(EXECUTION_METHODS))
  168. {
  169. debug.log('CRITICAL', "This iScript is running as [%s] and is designed to run from [%s]\n", debug.getExecutionMethod(), EXECUTION_METHODS);
  170. return false;
  171. }
  172.  
  173. if(DRY_RUN)
  174. {
  175. debug.logAlways("INFO", "**************** DRY RUN MODE ****************\n");
  176. }
  177.  
  178. var wfItem = new INWfItem(currentWfItem.id);
  179. if(!wfItem.id || !wfItem.getInfo())
  180. {
  181. debug.log('ERROR', "Couldn't get wfItem info [%s]: [%s]\n", currentWfItem.id, getErrMsg());
  182. return false;
  183. }
  184.  
  185. hashKeysToUpperCase(EMAIL_CONFIG);
  186.  
  187. var currentQueueToUpper = ToString(wfItem.queueName).toUpperCase(), curCfg = false;
  188. if(!(currentQueueToUpper in EMAIL_CONFIG))
  189. {
  190. debug.log('ERROR', "Queue [%s] does not exist in config; sending to error queue.\n", wfItem.queueName);
  191. routeToQueue(wfItem, ERROR_QUEUE, "", Clib.rsprintf("Queue [%s] is not set up for email functionality; check XML file", wfItem.queueName));
  192. return false;
  193. }
  194. else
  195. {
  196. debug.log("DEBUG", "Current Queue for configuration: [%s]\n", wfItem.queueName);
  197. curCfg = EMAIL_CONFIG[currentQueueToUpper];
  198. }
  199.  
  200. if (wfItem.type !== WfItemType.Document)
  201. {
  202. debug.log("CRITICAL", "This script is designed to process document items of type [%s], received type [%s], item id [%s]\n", WfItemType.Document, wfItem.type, wfItem.id);
  203. routeToQueue(wfItem, curCfg.queueError, "", "This is not a document");
  204. return false;
  205. }
  206.  
  207. var wfDoc = new INDocument(wfItem.objectId);
  208. if(!wfDoc.id || !wfDoc.getInfo())
  209. {
  210. debug.log('ERROR', "Couldn't get doc info [%s]: [%s]\n", wfItem.objectId, getErrMsg());
  211. routeToQueue(wfItem, curCfg.queueError, "", "Form data requested but no form name provided");
  212. return false;
  213. }
  214. debug.log("INFO","Processing document [%s] (Item id: [%s])\n", wfDoc, wfItem.id);
  215. if(RESET_DOC_NOTES) updateDocNotes(wfDoc, "");
  216.  
  217. if(!curCfg.emailConfig)
  218. {
  219. debug.log("ERROR", "No emailConfig in the configuration for queue [%s]\n", wfItem.queueName);
  220. updateDocNotes(wfDoc, Clib.rsprintf("ERROR: No emailConfig in the configuration for queue [%s]", wfItem.queueName));
  221. routeToQueue(wfItem, curCfg.queueError, "", "No emailConfig in the configuration for queue [" + wfItem.queueName + "]");
  222. return false;
  223. }
  224.  
  225. var emailReplacementText = new Array();
  226. if(curCfg.emailTextToReplace)
  227. {
  228. for(var pattern in curCfg.emailTextToReplace)
  229. {
  230. var currentProp = curCfg.emailTextToReplace[pattern];
  231. if(!currentProp) continue;
  232.  
  233. if(typeof(currentProp) == "boolean")
  234. {
  235. currentProp = ToString(currentProp);
  236. }
  237.  
  238. var currentVal = getComplexValue(currentProp, pattern, wfDoc, wfItem, curCfg);
  239. if(currentVal === false)
  240. {
  241. debug.log("ERROR", "Failed to get data for property [%s]\n", pattern);
  242. updateDocNotes(wfDoc, Clib.rsprintf("ERROR: Failed to get data for property [%s]. Please refer to the log file for further details\n", pattern));
  243. routeToQueue(wfItem, curCfg.queueError, "", Clib.rsprintf("Failed to get data for property [%s]\n", pattern));
  244. return false;
  245. }
  246.  
  247. if(UNDEFINED_VALUE && currentVal == "")
  248. {
  249. currentVal = UNDEFINED_VALUE;
  250. }
  251.  
  252. var safePattern = new RegExp(escapeForRegExp(pattern), 'ig');
  253. emailReplacementText.push({regex: safePattern, value: ToString(currentVal)});
  254. }
  255. }
  256.  
  257. var emailConfig = new Object();
  258. for(var emailProperty in curCfg.emailConfig)
  259. {
  260. var currentEmailPropertyValue = curCfg.emailConfig[emailProperty];
  261. if(currentEmailPropertyValue === undefined) continue;
  262.  
  263. var arrayEmailPropertyValues = new Array();
  264. if(!(currentEmailPropertyValue instanceof Array)) currentEmailPropertyValue = [currentEmailPropertyValue];
  265. for(var i = 0; i < currentEmailPropertyValue.length; i++)
  266. {
  267. if(currentEmailPropertyValue[i] === undefined) continue;
  268.  
  269. var arrayEmailPropertyValue = currentEmailPropertyValue[i];
  270. if(typeof(currentEmailPropertyValue[i]) !== "boolean")
  271. {
  272. arrayEmailPropertyValue = getComplexValue(currentEmailPropertyValue[i], emailProperty, wfDoc, wfItem, curCfg);
  273. if(arrayEmailPropertyValue === false)
  274. {
  275. //Logging and routing handled in the getComplexValue function
  276. return false;
  277. }
  278. }
  279. arrayEmailPropertyValues.push(arrayEmailPropertyValue);
  280. }
  281.  
  282. var useEmailPropertyValue = (arrayEmailPropertyValues.length > 1) ? arrayEmailPropertyValues.join(",") : arrayEmailPropertyValues[0];
  283. if(typeof(useEmailPropertyValue) == "string" && useEmailPropertyValue)
  284. {
  285. debug.log("DEBUG", "Before replacement: [%s] => [%s]\n", emailProperty, useEmailPropertyValue);
  286. for(var r=0; r<emailReplacementText.length; r++)
  287. {
  288. useEmailPropertyValue = useEmailPropertyValue.replace(emailReplacementText[r].regex, emailReplacementText[r].value);
  289. }
  290. //debug.log("DEBUG", "After replacement: [%s] => [%s]\n", emailProperty, useEmailPropertyValue);
  291. }
  292.  
  293. emailConfig[emailProperty] = useEmailPropertyValue;
  294. }
  295.  
  296. //debug.logObject("DEBUG", emailConfig, 10, "-- emailConfig --");
  297.  
  298. if(!emailConfig.to)
  299. {
  300. debug.log("ERROR", "Missing the TO email address.\n");
  301. updateDocNotes(wfDoc, "ERROR: Missing the TO email address.");
  302. routeToQueue(wfItem, curCfg.queueError, "", "Missing the TO email address");
  303. return false;
  304. }
  305.  
  306. var attachmentPageNo = curCfg.attachmentPageNum != undefined ? curCfg.attachmentPageNum.toUpperCase() : "";
  307. var attachmentFlag = (attachmentPageNo && attachmentPageNo !== "NONE");
  308.  
  309. if(attachmentFlag && !emailConfig.useUtility && !emailConfig.useCDO && !emailConfig.UnixSendmail)
  310. {
  311. debug.log("ERROR", "The configuration has attachments enabled (i.e. attachmentPageNum is not \"NONE\"), but the emailConfig needs to enable useUtility, useCDO or UnixSendmail in order to send attachments\n");
  312. updateDocNotes(wfDoc, "ERROR: The configuration has attachments enabled (i.e. attachmentPageNum is not \"NONE\"), but the emailConfig needs to enable useUtility, useCDO or UnixSendmail in order to send attachments");
  313. routeToQueue(wfItem, curCfg.queueError, "", "The configuration has attachments enabled but emailConfig does not");
  314. return false;
  315. }
  316.  
  317. var pagesToattach = false;
  318.  
  319. var emailToArr = (curCfg.emailSplit) ? ToString(emailConfig.to).split(",") : [emailConfig.to];
  320. for(var m = 0; m < emailToArr.length; m++)
  321. {
  322. debug.setIndent(0);
  323. debug.log("INFO", "Processing email [%s/%s] [%s]...\n", (m+1), emailToArr.length, emailToArr[m]);
  324. debug.setIndent(1);
  325.  
  326. emailConfig.to = emailToArr[m]; //Update to the individual/group email address
  327. var email = new iEmail("", emailConfig);
  328.  
  329. // Only add attachments to the email, if the HTML_FLAG is true AND the ATTACHMENT_FLAG is true
  330. if (attachmentFlag)
  331. {
  332. if(!pagesToattach)
  333. {
  334. var pagesToExport = attachmentPageNo ? attachmentPageNo : "ALL";
  335. if (pagesToExport != "LAST" && pagesToExport != "ALL")
  336. {
  337. pagesToExport = ToNumber(pagesToExport);
  338. if (isNaN(pagesToExport))
  339. {
  340. debug.log("ERROR", "[%s] is not a valid page number.\n", curCfg.attachmentPageNum);
  341. updateDocNotes(wfDoc, "ERROR: The attachmentPageNum is configured to an invalid page number for queue [" + wfItem.queueName + "]. Please refer to the log file for further details");
  342. routeToQueue(wfItem, curCfg.queueError, "", "attachmentPageNum is configured to an invalid page number");
  343. return false;
  344. }
  345. }
  346.  
  347. pagesToattach = exportDocPhsOb(wfDoc, curCfg.attachmentTempDir, pagesToExport, "", true);
  348. if(!pagesToattach || pagesToattach.length == 0)
  349. {
  350. debug.log("ERROR", "Failed to export document to attach to email\n");
  351. updateDocNotes(wfDoc, "ERROR: Failed to export document to attach to email. Please refer to the log file for further details");
  352. routeToQueue(wfItem, curCfg.queueError, "", "Failed to export document to attach to email");
  353. return false;
  354. }
  355. if(!(pagesToattach instanceof Array)) pagesToattach = [pagesToattach];
  356. }
  357.  
  358. //ADD ATTACHMENTS TO THE EMAIL
  359. for(var f = 0; f < pagesToattach.length; f++)
  360. {
  361. debug.log("DEBUG", "Adding attachment [%s]\n", pagesToattach[f]);
  362. email.addAttachment(pagesToattach[f]);
  363. }
  364. }
  365.  
  366. // Send email
  367. if(!DRY_RUN)
  368. {
  369. if (!email.send())
  370. {
  371. debug.log("ERROR","Failed to send email. Error: [%s]\n", email.error);
  372. updateDocNotes(wfDoc, "ERROR: Failed to send email. Please refer to the log file for further details");
  373. routeToQueue(wfItem, curCfg.queueError, "", "Failed to send email");
  374. return false;
  375. }
  376. else
  377. {
  378. debug.log("INFO", "Sent email notification to: [%s]\n", email.to);
  379. }
  380. }
  381. else
  382. {
  383. debug.log("INFO", "Would have sent email to [%s]\n", email.to);
  384. //debug.logObject("INFO", emailConfig, 5, "Would send email");
  385. }
  386. }
  387.  
  388. debug.setIndent(0);
  389. debug.log("NOTIFY","Email(s) sent successfully\n");
  390.  
  391. if(RESET_DOC_NOTES) updateDocNotes(wfDoc, "");
  392. routeToQueue(wfItem, curCfg.queueSuccess, curCfg.queueError, "Emails sent");
  393. }
  394. catch(e)
  395. {
  396. if (!debug)
  397. {
  398. printf("\n\nFATAL iSCRIPT ERROR: %s\n\n", e.toString());
  399. }
  400. else
  401. {
  402. debug.setIndent(0);
  403. debug.log("CRITICAL", "***********************************************\n");
  404. debug.log("CRITICAL", "***********************************************\n");
  405. debug.log("CRITICAL", "** **\n");
  406. debug.log("CRITICAL", "** *** Fatal iScript Error! *** **\n");
  407. debug.log("CRITICAL", "** **\n");
  408. debug.log("CRITICAL", "***********************************************\n");
  409. debug.log("CRITICAL", "***********************************************\n");
  410. debug.log("CRITICAL", "\n\n\n%s\n\n\n", e.toString());
  411. debug.log("CRITICAL", "\n\nThis script has failed in an unexpected way. Please\ncontact Lexmark Enterprise Software Customer Support at 800-941-7460 ext. 2\nAlternatively, you may wish to email es_support@lexmark.com\nPlease attach:\n - This log file\n - The associated script [%s]\n - Any supporting files that might be specific to this script\n\n", _argv[0]);
  412. debug.log("CRITICAL", "***********************************************\n");
  413. debug.log("CRITICAL", "***********************************************\n");
  414. if (DEBUG_LEVEL < 3 && typeof(debug.getLogHistory) === "function")
  415. {
  416. debug.popLogHistory(11);
  417. debug.log("CRITICAL", "Log History:\n\n%s\n\n", debug.getLogHistory());
  418. }
  419.  
  420. if(typeof(wfDoc) != "undefined" && wfDoc)
  421. {
  422. updateDocNotes(wfDoc, "ERROR: Fatal iScript Error. Please refer to the log file for further details");
  423. }
  424.  
  425. //Fatal error routing
  426. if(typeof(wfItem) != "undefined" && wfItem && typeof(curCfg) != "undefined" && curCfg)
  427. {
  428. routeToQueue(wfItem, curCfg.queueError, "", "Fatal iScript Error");
  429. }
  430.  
  431. }
  432. }
  433. finally
  434. {
  435. if (debug) debug.setIndent(0);
  436. if(typeof(pagesToattach) != "undefined" && pagesToattach)
  437. {
  438. //clean up temp directory (if needed)
  439. if(!(pagesToattach instanceof Array)) pagesToattach = [pagesToattach];
  440. for(var rf = 0; rf < pagesToattach.length; rf++)
  441. {
  442. debug.log("DEBUG", "Deleting file [%s/%s] [%s]\n", (rf+1), pagesToattach.length, pagesToattach[rf]);
  443. if(Clib.remove(pagesToattach[rf]) != 0)
  444. {
  445. debug.log("WARNING", "Error deleting file [%s]: [%s]\n", pagesToattach[rf], Clib.strerror(Clib.errno));
  446. }
  447. }
  448. }
  449. if (typeof(stats) == "object" && stats)
  450. {
  451. if (stats.isEmpty()) stats.inc("Stats successfully generated.");
  452. if (debug) debug.logAlways("NOTIFY", "Done:\n\n%s\n", stats.getSortedStats());
  453. else printf("Done:\n\n%s\n", stats.getSortedStats());
  454. }
  455. if (debug && (typeof(debug.finish) === "function"))
  456. {
  457. debug.finish();
  458. }
  459. }
  460. }
  461.  
  462. // ********************* Function Definitions **********************************
  463. /**
  464. * The function will convert a date string to a different date format in a complex array
  465. *
  466. * @param {String} date - date to format
  467. * @param {Object} fieldMap - current field map
  468. * @return {String} formatted date
  469. */
  470. function convertToDateStrUsingComplexArray(date, fieldMap)
  471. {
  472. //debug.log("DEBUG", "convertToDateStrUsingCA: Date [%s]\n", date);
  473. if(!date) return ""; //No need to convert blank string
  474.  
  475. var newDate;
  476. if(typeof(date) == "number")
  477. {
  478. newDate = new Date(date * 1000);
  479. }
  480. else
  481. {
  482. newDate = convertToDateObj(date, oFieldMap);
  483. if(newDate === false)
  484. {
  485. //Logging in the convertToDateObj function
  486. return false;
  487. }
  488. }
  489.  
  490. return (newDate) ? convertToDateStr(newDate, oFieldMap.format) : "";
  491. }
  492.  
  493. /**
  494. * Gets all the complex value for the given property configuration
  495. *
  496. * @method getEmailsFromQueue
  497. * @param {String} queue Queue name to get users from.
  498. * @return {String/Boolean} List of email addresses joined by a ',' on success, false on error.
  499. */
  500. function getComplexValue(currentPropCfg, property, wfDoc, wfItem, curCfg)
  501. {
  502. var currentVal = undefined;
  503.  
  504. if(currentPropCfg && currentPropCfg instanceof Array)
  505. {
  506. //Check if their are any nested arrays
  507. var arrayValues = new Array();
  508. for (var ai=0; ai<currentPropCfg.length; ai++)
  509. {
  510. var arrayValue = getComplexValue(currentPropCfg[ai], property, wfDoc, wfItem, curCfg);
  511. if(arrayValue === false)
  512. {
  513. debug.log("ERROR", "getComplexValue: Failed to get array data for property [%s]\n", property);
  514. updateDocNotes(wfDoc, "ERROR: The script failed to get array data for property [" + property + "]. Please refer to the log file for further details");
  515. routeToQueue(wfItem, curCfg.queueError, "", "Failed to get array data for property "+property);
  516. return false;
  517. }
  518. arrayValues.push(arrayValue);
  519. }
  520. currentVal = (arrayValues.length > 1) ? arrayValues.join(",") : arrayValues[0];
  521. }
  522. else if(currentPropCfg && currentPropCfg.type !== undefined && currentPropCfg.source !== undefined)
  523. {
  524. //Check for a complex array configuration
  525. var newComplexArrayCfg = currentPropCfg;
  526. switch(currentPropCfg.type)
  527. {
  528. case "COMPLEX":
  529. var complexValues = new Array();
  530. for (var ci=0; ci<currentPropCfg.source.length; ci++)
  531. {
  532. var complexValue = getComplexValue(currentPropCfg.source[ci], property, wfDoc, wfItem, curCfg);
  533. if(complexValue === false)
  534. {
  535. debug.log("ERROR", "getComplexValue: Failed to get complex data for property [%s]\n", property);
  536. updateDocNotes(wfDoc, "ERROR: The script failed to get complex data for property [" + property + "]. Please refer to the log file for further details");
  537. routeToQueue(wfItem, curCfg.queueError, "", "Failed to get complex data for property "+property);
  538. return false;
  539. }
  540. complexValues.push(complexValue);
  541. }
  542. currentVal = (complexValues.length > 1) ? complexValues.join("") : complexValues[0];
  543. break;
  544. case "DICTIONARY":
  545. case "FORM":
  546. if(!form)
  547. {
  548. //Initialize the form data for the first time (if needed)
  549. if(!curCfg.formName)
  550. {
  551. debug.logln("ERROR","getComplexValue: Form data requested but no form name provided.");
  552. updateDocNotes(wfDoc, "ERROR: No form name configured and form data required");
  553. routeToQueue(wfItem, curCfg.queueError, "", "No form name configured and form data required.");
  554. return false;
  555. }
  556. else if(form === false)
  557. {
  558. form = new FormManager(curCfg.formName);
  559. if(!form || form.error)
  560. {
  561. debug.log("ERROR","getComplexValue: Failed to initialize FormManager for Form %s\n",curCfg.formName);
  562. updateDocNotes(wfDoc, "ERROR: Failed to find form [" + curCfg.formName + "]. Please refer to the log file for further details");
  563. routeToQueue(wfItem, curCfg.queueError, "", "Failed to initialize FormManager for Form " + curCfg.formName);
  564. return false;
  565. }
  566. }
  567. }
  568. if(!formData) formData = new Object();
  569.  
  570. if(!formData[currentPropCfg.source])
  571. {
  572. var formFieldData = form.getDataFromForm(wfDoc, [currentPropCfg.source]);
  573. if(!formFieldData)
  574. {
  575. debug.log("ERROR","getComplexValue: Failed to get form data for node [%s]\n", currentPropCfg.source);
  576. updateDocNotes(wfDoc, "ERROR: The script failed to get form data for node [" + currentPropCfg.source + "]. Please refer to the log file for further details");
  577. routeToQueue(wfItem, curCfg.queueError, "", "Failed to get data from form for node [" + currentPropCfg.source + "]");
  578. return false;
  579. }
  580. formData[currentPropCfg.source] = formFieldData[currentPropCfg.source];
  581. }
  582.  
  583. break;
  584. case "DOCUMENT_PROPERTY":
  585. if(currentPropCfg.source === "NOTES")
  586. {
  587. //Pass value to complex array in order to fulfill any additional properties (i.e. func, required)
  588. newComplexArrayCfg.type = "LITERAL";
  589. newComplexArrayCfg.source = wfDoc.getNotes();
  590. }
  591. break;
  592. case "QUEUE":
  593. currentVal = getEmailsFromQueue(currentPropCfg.source);
  594.  
  595. //Pass value to complex array in order to fulfill any additional properties (i.e. func, required)
  596. newComplexArrayCfg.type = "LITERAL";
  597. newComplexArrayCfg.source = currentVal;
  598. break;
  599. }
  600.  
  601. currentVal = getValueFromComplexArray(newComplexArrayCfg, wfDoc, wfItem, false, false, formData);
  602. if(currentVal === false)
  603. {
  604. debug.log("ERROR", "getComplexValue: Failed to get data for property [%s]\n", property);
  605. updateDocNotes(wfDoc, "ERROR: The script failed to get data for property [" + property + "]. Please refer to the log file for further details");
  606. routeToQueue(wfItem, curCfg.queueError, "", "Failed to get data for property "+property);
  607. return false;
  608. }
  609. }
  610. else
  611. {
  612. currentVal = currentPropCfg;
  613. }
  614.  
  615. //debug.log("DEBUG", "getComplexValue: Returning [%s] (%s)\n", currentVal, typeof(currentVal));
  616. return currentVal;
  617. }
  618.  
  619. /**
  620. * <div class="rev">$</div>
  621. * Gets all the email addresses for users with permissions on the passed in queue.
  622. * @requires routeItem, getEmailsFromUsers
  623. */
  624. /**
  625. * Gets all the email addresses for users with permissions on the passed in queue.
  626. * @method getEmailsFromQueue
  627. * @param {String} queueName Queue name to get users from.
  628. * @return {String/Boolean} List of email addresses joined by a ',' on success, false on error.
  629. */
  630. function getEmailsFromQueue(queueName)
  631. {
  632. debug.log("DEBUG", "getEmailsFromQueue: using queue name: %s\n", queueName);
  633.  
  634. var queue = new INWfQueue();
  635. queue.name = queueName;
  636.  
  637. var userList = queue.getAccessUserList();
  638. if(!userList || userList.length < 1)
  639. {
  640. debug.log("INFO", "getEmailsFromQueue: Queue [%s] has no members\n", queueName);
  641. return ""; //empty string for no users
  642. }
  643.  
  644. var userIDArr = [];
  645. for(var m = 0; m < userList.length; m++)
  646. {
  647. userIDArr.push(userList[m].userId);
  648. }
  649.  
  650. var emailArr = getEmailsFromUsers(userIDArr);
  651. if(!emailArr)
  652. {
  653. debug.logln("ERROR", "getEmailsFromQueue: Failed to get emails from users on queue [%s]", queue);
  654. return false;
  655. }
  656.  
  657. return emailArr.join(",");
  658. }
  659.  
  660. /**
  661. * The function only sets document notes if a document is passed in
  662. * and a valid document notes mode is specified.
  663. *
  664. * @param {String} str String to escape
  665. * @return {String} Escaped string
  666. */
  667. function updateDocNotes(doc, note, docNoteMode, docNoteDelimiter)
  668. {
  669. if(doc && doc instanceof INDocument && DOC_NOTE_MODE >= 0)
  670. {
  671. docNoteMode = (docNoteMode!==undefined) ? docNoteMode : DOC_NOTE_MODE;
  672. docNoteDelimiter = (docNoteDelimiter!==undefined) ? docNoteDelimiter : DOC_NOTE_DELIMITER;
  673. if(DRY_RUN)
  674. {
  675. debug.log("INFO", "updateDocNotes: Would have set document notes with [%s] option [%s]\n", note, docNoteMode);
  676. }
  677. else
  678. {
  679. return setDocNotes(doc, note, docNoteMode, docNoteDelimiter);
  680. }
  681. }
  682. return true;
  683. }
  684.  
  685. /**
  686. * route document/item to specified workflow queue
  687. *
  688. * @param {INDocument|INWfItem} itemOrDoc workflow item/document
  689. * @param {String} queueOrRoute - queue name to route to
  690. * @param {String} errorQueueOrRoute - error queue name to route to (if queueOrRouter route fails, blank if not needed)
  691. * @param {String} reason - reason to route item/document
  692. * @return {Boolean} true on success, false otherwise
  693. */
  694. function routeToQueue(itemOrDoc, queueOrRoute, errorQueueOrRoute, reason)
  695. {
  696. if(itemOrDoc && queueOrRoute && queueOrRoute != "")
  697. {
  698. var routeFunc;
  699. if(itemOrDoc instanceof INWfItem)
  700. {
  701. routeFunc = routeItem;
  702. }
  703. else
  704. {
  705. routeFunc = createOrRouteItem;
  706. }
  707.  
  708. if(DRY_RUN)
  709. {
  710. debug.log("INFO", "routeToQueue: Would have routed document to [%s] queue\n", queueOrRoute);
  711.  
  712. }
  713. else if(routeFunc(itemOrDoc, queueOrRoute, reason))
  714. {
  715. debug.log("INFO", "routeToQueue: Successfully routed document to [%s] queue\n", queueOrRoute);
  716. }
  717. else
  718. {
  719. debug.log("ERROR", "routeToQueue: Failed to route document to [%s] queue\n", queueOrRoute);
  720. if(itemOrDoc instanceof INDocument)
  721. {
  722. updateDocNotes(itemOrDoc, "ERROR: Failed to route document to [" + queueOrRoute + "] queue");
  723. }
  724. routeToQueue(itemOrDoc, errorQueueOrRoute, "", "Failed to route document to [" + queueOrRoute + "] queue");
  725. return false;
  726. }
  727. }
  728. return true;
  729. }
  730. // Required Comment - DO NOT REMOVE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement