• NetSuite Plug-In 101


    进入了我的学术休假季,开始做一些自己喜欢的题目。今天就来扒一扒一个NetSuite落满灰尘的功能--Plug-In。

    大家可能听到过一个叫做Email Approval的应用场景,可以让用户在不登录NetSuite系统的情况下,跟NetSuite产生交互。例如,通过邮件回复或者“按钮”来审批PO或费用报告。

    这就是一个典型的Plug-In应用。

    什么是NetSuite Plug-In

    NetSuite Plug-In的背后是NetSuite架构师的一个想法,就是“面向对象”。这个设计的初衷是,将NetSuite系统中的某些业务逻辑松耦合,让开发者可以对这些业务环节进行修改。例如,我们俗称为“过账引擎” 的Custom GL Plug-In,其基本思路就是让开发者可以干预过账逻辑,从而适应客户业务场景的多变。例如,在销售发票过账环节,系统的标准处理是取Item上的Income科目预设值,以及客户上的AR科目预设值。但是,客户说我能不能在发票上客制一个“收入”字段,让这个发票都计入到这个临时设定的收入,而不是Item上的收入科目。这个需求在不同的财务软件中有不同的名字,在NetSuite中我们是通过Custom GL Plug-In来实现的。

    NetSuite Plug-In分为两类,一种叫做Custom Plug-In,另一种叫做Core Plug-In,前者是NetSuite鼓励其他开发商使用的,后者是NetSuite自己用的。

    这是一个架构示意图,满满的面向对象的想法。

    1. -开发商:定义对象
    2. -实施商:实例化对象
    3. -用户:选择参数,启用功能

     以上面Email Approval的应用场景来举例,实际上是应用了一个叫做Email Capture的NetSuite Core Plug-In类型,做的一个实例化。

     

     但是,不知为何。NetSuite并没有在更大范围里推广Plug-In。甚至在上面所说的过账引擎中,也是浅尝辄止。

    目前NetSuite提供了不多的几个Core Plug-In,见下表:

     其中好用的还是前两个,一个用于过账引擎,另一个用于Email侦听。

    Plug-In结构

    如上所述,如果我们作为实施顾问来应用NetSuite Core Plug-In的话,基本上是在既有的框架下,填入自己的处理逻辑来实现的。例如,如果是基于Email Capture Plug-In来写自己的应用到话。就是遵从其Interface Definition就可以了。也有示例代码啥的,把自己的代码抄进去就行了。

    典型应用--邮件侦听

    如下是一个典型的邮件侦听应用,用于进行特定邮箱邮件的收集汇总。

    转载自网文:

    NetSuite Email Capture Example – NetSuite Experiences

    1. function process(email) {
    2. const IS_PRODUCTION = true;
    3. const valid_types = [
    4. 'APPCACHE',
    5. 'AUTOCAD',
    6. 'BMPIMAGE',
    7. 'CERTIFICATE',
    8. 'CONFIG',
    9. 'CSV',
    10. 'EXCEL',
    11. 'FLASH',
    12. 'FREEMARKER',
    13. 'GIFIMAGE',
    14. 'GZIP',
    15. 'HTMLDOC',
    16. 'ICON',
    17. 'JAVASCRIPT',
    18. 'JPGIMAGE',
    19. 'JSON',
    20. 'MESSAGERFC',
    21. 'MP3',
    22. 'MPEGMOVIE',
    23. 'MSPROJECT',
    24. 'PDF',
    25. 'PJPGIMAGE',
    26. 'PLAINTEXT',
    27. 'PNGIMAGE',
    28. 'POSTSCRIPT',
    29. 'POWERPOINT',
    30. 'QUICKTIME',
    31. 'RTF',
    32. 'SCSS',
    33. 'SMS',
    34. 'STYLESHEET',
    35. 'SVG',
    36. 'TAR',
    37. 'TIFFIMAGE',
    38. 'VISIO',
    39. 'WEBAPPPAGE',
    40. 'WEBAPPSCRIPT',
    41. 'WORD',
    42. 'XMLDOC',
    43. 'XSD',
    44. 'ZIP',
    45. ]
    46. var fromAddress = email.getFrom();
    47. nlapiLogExecution('DEBUG', 'Email - from: ' + fromAddress.getName() + ', ' + fromAddress.getEmail());
    48. nlapiLogExecution('DEBUG', 'subject - ' + email.getSubject());
    49. var newRec = nlapiCreateRecord('customrecord_xxxxxxxxxxxxxxxxxxxxxxxxxxxx');
    50. newRec.setFieldValue('custrecord_xxxxxxxxxx', fromAddress.getName());
    51. newRec.setFieldValue('custrecord_xxxxxxxxxx', fromAddress.getEmail());
    52. newRec.setFieldValue('custrecord_xxxxxxxxxx', email.getSubject());
    53. newRec.setFieldValue('custrecord_xxxxxxxxxx', email.getTextBody());
    54. var newRec_id = nlapiSubmitRecord(newRec, true);
    55. var attachments = email.getAttachments();
    56. // This variable is here in case you wanted to add notes about attachments.
    57. // it is currently unused.
    58. var processing_notes = '';
    59. for (var indexAtt in attachments) {
    60. var attachment = attachments[indexAtt];
    61. nlapiLogExecution('DEBUG', 'Attachment: ' + attachment.getName() + ', ' + attachment.getType());
    62. // If the file name does not have an extension, skip it
    63. var fileName = attachment.getName();
    64. if (fileName.indexOf('.') <= 0) continue;
    65. // add a unique suffix to the file name, but leave the extension as-is
    66. var fileArray = fileName.split('.');
    67. var newName = '';
    68. for (var i = 0; i < fileArray.length; i++) {
    69. if (i == fileArray.length - 1) {
    70. newName += ('_' + (new Date().valueOf()).toString());
    71. }
    72. newName += ('.' + fileArray[i]);
    73. }
    74. // Lookup the file type to see if it is supported, else save as PLAINTEXT
    75. // This really won't affect being able to open and download the file.
    76. // It only affects filtering files by type.
    77. var file_type = attachment.getType().toUpperCase();
    78. if (valid_types.filter(function (p) { return p == file_type }).length == 0) {
    79. file_type = 'PLAINTEXT'; // Import nonrecognized file types as Other Binary File
    80. }
    81. var file = nlapiCreateFile(newName, file_type, attachment.getValue());
    82. // Save the file under a selected folder in the file cabinet
    83. file.setFolder(1111111111); //Internal ID of folder to hold imported attachments
    84. var file_id = nlapiSubmitFile(file);
    85. // Attach the file to a custom record type
    86. nlapiAttachRecord('file', file_id, 'customrecord_xxxxxxxxxxxxxxxxxxxxxxxxxxxx', newRec_id);
    87. }
    88. // here is where you'd include notes about attachments, perhaps those that were erroniously
    89. // saved under the PLAINTEXT type.
    90. nlapiSubmitField('customrecord_xxxxxxxxxxxxxxxxxxxxxxxxxxxx', newRec_id, 'custrecord_xxxxxxxxxx', processing_notes);
    91. }

    举一反三,大家应该可以用这个作为例子,写一下你自己的邮件侦听应用了。邮件审批、邮件新建拜访日志、邮件触发工作流等等。

    以上是对NetSuite Plug-In的概述,Show me the code. Have fun!

  • 相关阅读:
    资料分析(错题、经典)
    Vue前端框架快速入门学习笔记
    Windows11环境下安装Vmware Workstation 16的方法
    VUE修饰符sync使用
    学生党性价比高的蓝牙耳机有哪些?2022年高性价比蓝牙耳机推荐
    怎么用电脑制作证件照?使用这个工具就可以了
    关于游戏介绍的HTML网页设计 HTML5期末考核大作业 HTML静态游戏网页作业 web前端开发技术 web课程设计 网页规划与设计
    实战|如何低成本训练一个可以超越 70B Llama2 的模型 Zephyr-7B
    Vue2【前端路由的概念与原理、vue-router 的基本用法、vue-router 的常见用法、后台管理案例】
    linux c++ 学习记录
  • 原文地址:https://blog.csdn.net/remottshanghai/article/details/128187371