Displaying items by tag: SuiteScript

Wednesday, 11 November 2020 15:19

Workflow Email Skript

Advanced “Send Email” Workflow action

 

‘Reply-to’ email address in NetSuite’s native Workflow action can not be set. You can define a ‘Send-from’ a ‘CC and a ‘BCC’ email address as well as only one recipient. This is sufficient in many situations, but some of our customer’s need more features.

 

Features we added to the standard functionality:

 

  • Send email to more than one recipient 
  • Define one or more ‘Reply-to’ email address

 

Our consultants can install the script in any account and then go ahead to configure the workflow action according to customer’s needs.

 

This screenshot shows the fields you can set:



If you like our support, feel invited to vet in touch with us.

 

Kind regards,

Georg Walther

 
 
 
 
 
Published in Script Solution
Friday, 24 January 2020 16:15

Alta Via Mailchimp connector

Mailchimp is one of the most popular email newsletter tools on the market. 
The usability is very much appreciated by many marketing managers around the world.

Naturally we are looking for ways to transfer data from NetSuite to MailChimp.
Common questions we have when we look for options to integrate: 

Searching a solution that fits

  • Do we really need a middleware to facilitate the integration?
  • Is the price for the middleware justified for this purpose?
  • We just want to sync an email address, do we really have to configure a middleware and maintain it?
  • Our integration needs are very custom. All products on the market are either overkill or not what we need.
  • Make or buy? Should we just start to develop the integration ourselves?

Here, Alta Via has developed a simple approach. No middleware is needed. Only the email address is pushed from NetSuite to Mailchimp and then synced going forward.
The solution is very basic but customizable to the needs of our customers.

How does it work?

In this process, NetSuite is considered to be the leading system for master data (customer’s email address), whereas the email newsletter subscription status is managed in mailchimp.

  • The connector pushes new customers/email addresses to Mailchimp.
  • Mailchimp manages the double opt-in and sends out newsletters.
  • Subscription status changes are synced back from Mailchimp into NetSuite on demand.

In detail:

After installation and configuration of the bundle, and as a first step you need to define your relevant customers, which shall become part of campaigns in mailchimp, through a saved search. The definition is important, as your customer data is precious and you might not want to share all of them.

The name of that search has to be entered in the general settings of your NetSuite account.

Note: Not all customers that you defined to be relevant will be replicated, but only the ones that have the appropriate opt-in status.

NetSuite has four status for email newsletters:

  • Confirmed Opt-In (if the customer agreed to receive campaigns)
  • Soft Opt-In (if the customer can receive opt-in eMails)
  • Soft Opt-Out (if the customer can receive opt-in eMails)
  • Confirmed Opt-Out (the customer can neither receive campaign emails nor opt-in eMails)

Your relevant customers then can be synchronized to the mailchimp account. If the status is one of Soft Opt-In or Soft Opt-Out then the customer email is synced to mailchimp in the status of "pending", meaning that the customer will receive an email from mailchimp to subscribe to a campaign.

If the customer opted-in (Confirmed Opt-In), then the customer’s email is synced to mailchimp in the status of "subscribed", so no additional subscription email will be sent to the customer.

Note: Still in all mailchimp emails you should ensure that the customer can unsubscribe from a campaign.

Customers are added as members to the configured mailchimp member list.
When customer synchronization is started, then NetSuite also reads the subscription status of the customer in mailchimp. If the customer unsubscribed, this status is also stored in the NetSuite system for information.

Note: Subscription status in NetSuite might not be up to date with the status in mailchimp, only after re-syncing the data is up to date.

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Published in Implementation
Thursday, 07 November 2019 16:35

Alta Via digging deep into #SuiteScript

A major step in moving SuiteScript to the 21st Century.

As NetSuite recently published SuiteScript 2.1  we were curious and took a deeper look into it. ... Pssst! we can use #ECMAscript 6 now :)
I was very excited when I heard it is coming and finally we have the freedom of using all the newest JavaScript features, so let's try to use it. 

Why would you want to use it?

 If you wanted to use the latest  version of ECMAScript without being forced to transform your code, so that NetSuite would understand it, by e.g. using babel or some other transpiling tool - the solution has just arrived. The new SuiteScript 2.1 (for the time being still in Beta).

The script header:

 My first script with 2.1 started with a question: which value for @version tag should be used. I started with 2.x which in theory should always match the latest version of SuiteScript. Unfortunately this option does not work yet. For the time being 2.x equals 2.0 and if you try to use it 2.x and some of the newest features of javascript you will get syntax errors, so my final header looked like this:

/**
 *
 *  @NApiVersion 2.1
 *  @NScriptType UserEventScript
 */

Next step was to find a way to add a library script. In 2.0 I used to use:

* @NAmdConfig /SuiteScripts/configuration.json

where configuration.json was a file that contained mapping  

{
  "paths": {
    "myLib": "/SuiteScripts/Libraries/myCustomLib",
  }
}

 

Thanks to that I was able to use myLib as a reference to myCustomLib.js in define clause like this:

define(['myLib'],
    function (myLib) {

However, it does not work in 2.1. I thought that maybe you need to use javascript modules instead (@export/@import), but when you try to use them the script is throwing syntax errors. It seems like some defect, or lacking feature in Beta, but the only way for now to add external libraries is to actually use a url in the define clause like:

define(['/SuiteScripts/Libraries/myCustomLib'],
   function (myLib) {

Use Classes:

 After workarounding the problems above, I was able to create a fully operational user event script with libraries attached. Moreover it seems that all the latet ECMAScript features are working (Hurray!) - I could use classes:

 /**
  *
  */
  class ShippingInformation {

  /**
   *
   * @param {*} itf
   * @param {*} itemsData
   */

   constructor(itf, itemsData) {
       this.boxes = [];
       this.itemsData = itemsData;
       this.itf = itf;
      }

Variables: Const and let

Block scope variables and constants :

for (let i = 0; i < count; i++) {

    let item = this.itf.getSublistValue({
    sublistId: 'item',
    fieldId: 'item',
    line: i
    
});

const itemData = this.itemsData[item];

Lambda functions:

 /**
  *
  * @returns {Array}
  */

  hasEmptySpace() {

    const uniqueItems = this.lines.map((line) => line.item).filter((x, i, a) => a.indexOf(x) === i);

    return uniqueItems.length < 3 && this.spaceUsed < 1;

  }

As of now my script works in my customer’s production account without any issues, so i believe 2.1 is stable.

Let's hope that NetSuite will shortly stop to consider SuiteScript 2.1 as a Beta feature and also add support for it in debugger.

 All in all, finally some major step in moving SuiteScript to 21st Century!

 
 
 
 
 
 
 
 
 
Published in Script Solution
Monday, 12 August 2019 14:37

Access more than 10.000 records in a sublist

Filtering invoices on Customer Payments in SuiteScript

Published in Script Solution
Friday, 31 May 2019 15:44

NetSuite's SFTP Module - N/sftp

With NetSuite's SuiteScript 2.0 you have the ability to access ssh servers, commonly known as secure FTP or SFTP.

You can upload or download files from an SFTP server. It is not possible to send files to NetSuite using the SFTP module. If you are looking for that, you can use a RESTLet.

If you are sure, SFTP is the answer to your question, we have a little bit of help for you here:

 

1) Alta Via has developed many SFTP integrations. Contact us if you like us to help you.

 

2) If you want to do this all by yourself, here are four steps you need to follow for a basic setup or test:

 

2.1) What do you need? Your checklist:

  • URL Address (host)
  • Port
  • Folder Name
  • Password
  • Host Key
  • Host Key type (one of these three: dsa, ecdsa, rsa )
  • GUID (Globally Unique Identifier)

While URL, Port, Folder name and password are relatively easy to get (just ask the administrator of the service), you might not easily get the host key.

 

2.2) Host Key

In a Windows command shell or on a Mac in terminal, run this command:

ssh-keyscan -t rsa -p [port] [host]

 

2.3) GUID

This is a unique identifier which the SFTP Module needs to create a connection with the remote server. Just copy the script below and enter the internal ID of the script which will later handle the connection and the domain. (restrictToScriptIds and restrictToDomains). Deploy it as a SuiteLet and run it through the link you find in the deployment.

 

/**
 *@NApiVersion 2.x
 *@NScriptType Suitelet 
 */

define(['N/ui/serverWidget', 'N/log'],
    function (serverWidget, log) {
        function onRequest(context) {
            if (context.request.method === 'GET') {
                var form = serverWidget.createForm({
                    title: 'Guid Form'
                });
                form.addField({
                    id: 'username',
                    type: serverWidget.FieldType.TEXT,
                    label: 'Username'
                });
                form.addCredentialField({
                    id: 'password',
                    label: 'Password',
                    restrictToScriptIds: 'customscript_internal_id',
                    restrictToDomains: 'host of service'
                });
                form.addSubmitButton({
                    label: 'Submit Button'
                });
                context.response.writePage(form);
                return;
            } else {
                var requset = context.request;
                var myPwdGuid = requset.parameters.password;
                log.debug("myPwdGuid", myPwdGuid);
                context.response.write(myPwdGuid);
            }
        }

        return {
            onRequest: onRequest
        };
    }
);

 

2.4) Connection and transfer

The second script handles sending your file to the remote server. This is a workflow action script. You can modify it to be a module and pass sftp credentials and a file.

/**
 *@NApiVersion 2.x
 *@NScriptType WorkflowActionScript
 */

define(['N/sftp', 'N/file', 'N/search'],
    function (sftp, file, search) {
        function onAction(context) {

            var txn = context.newRecord;
            try {
                
                var myPwdGuid = "WHAT YOUR SUITELET CREATED";
                var myHostKey = "WHAT YOU FOUND FROM SSH-KEYSCAN";
                var connection = sftp.createConnection({
                    username: 'YOUR USERNAME',
                    passwordGuid: myPwdGuid,
                    url: 'SERVICE DOMAIN',
                    port: PORT OF SERVICE IS USUALLY 22,
                    directory: 'FOLDER',
                    hostKey: myHostKey
                });

                var uploadFile = file.load({
                    id: 'PATH TO SOME FILE'
                });

                connection.upload({
                    filename: fileName,
                    file: uploadFile,
                    replaceExisting: true
                });
            }
        }

        return {
            onAction: onAction
        }
    }
);
Published in Script Solution

Hello,

 

We found that sending an email from a standard netsuite transaction does not allow us to modify the reply-to email address. Receipients are confused or do not reply to the email we want to. Here is a workflow action script which fixes this.

 

NetSuite has an enhancement request, which is currently not in progress. Enhancement # - 76077 

 

var CONST = {
    author_license: [some user id],
    replyTo: 'set this or pull it from somewhere',
    bcc: 'whatever you wish'
}

function sendEmail_WF() {

    var po = nlapiGetNewRecord();

    var emailMerger = nlapiCreateEmailMerger(yourFormId);
    emailMerger.setTransaction(po.getId());
    emailMerger.setEntity('vendor', po.getFieldValue('entity'));
    var mergeResult = emailMerger.merge();
    var subject = mergeResult.getSubject();
    var body = mergeResult.getBody();

    var recipient = getReceipients(po.getFieldValue('entity'));
    if (recipient.length == 0) {
        throw 'There is no email address to send this email to.';
    }

    var attachments = [];
    attachments = getAttachment(attachments, po);
    attachments = getPDF(attachments, po);

    var records = {
        transaction: po.getId()
    }

    if (recipient && recipient != '') {
        nlapiSendEmail(CONST.author_license, recipient, subject, body, null, CONST.bcc, records, attachments, null, null, CONST.replyTo);
    }
}

function getReceipients(vendId) {
    // Here we pull email addresses from the vendor's contacts and also addd the vendor's main email address

    var recipient = [];
    recipient.push(nlapiLookupField('entity', vendId, 'email'));
    var cS = nlapiSearchRecord("contact", null,
        [
            ["company", "anyof", vendId],
            "AND",
            ["custentity_is_po_recipient", "is", "T"],
            "AND",
            ["email", "isnotempty", ""]
        ]
    );
    for (var i = 0; cS && i < cS.length; i++) {
        recipient.push(cS[i].getId());
    }

    var recipientNoDupe = [];
    recipient.forEach(function (recipient) {
        if (recipientNoDupe.indexOf(recipient) < 0) {
            recipientNoDupe.push(recipient);
        }
    });

    return recipientNoDupe;

}

function getAttachment(attachments, po) {
    varcustbody_your_document_field = po.getFieldValue('custbody_your_document_field');
    if (custbody_your_document_field && custbody_your_document_field != '') {
        attachments.push(nlapiLoadFile(custbody_your_document_field));
    }
    return attachments;
}

function getPDF(attachments, po) {
    var paras = [];
    paras.formnumber = 'your transaction form id';
    var file = nlapiPrintRecord('TRANSACTION', po.getId(), 'PDF', paras);
    attachments.push(file);
    return attachments;
}​
Published in Script Solution

CONTACT US!

O NetSuite SuiteCloudDeveloperNetwork rgb 2NetSuite SolutionProvider horiz rgb

NOTE! This site uses cookies and similar technologies.

If you not change browser settings, you agree to it.

I understand