Chapter 18: Managing Gaps and Creating Custom Automations

It's not terribly uncommon to find a requirement that cannot be solved by a native NetSuite feature or a partner's pre-built solution. When this happens, you have to consider creating a custom SuiteFlow or SuiteScript.

In this chapter, we will learn how workflows and scripts can help solve problems and automate activities, and how best we can help our clients when it comes to gathering customization requirements and mapping out how they will solve them.

In this chapter, we will cover the following topics:

  • Identifying gaps and needs for automation in requirements
  • Customizing NetSuite processes with workflows
  • Making NetSuite work for you with scripts
  • Documenting customization requirements and solutions
  • Managing customizations over time, including their deployments

By the end of this chapter, I hope you'll be able to discuss these technical topics with your clients, having a good sense of the options that are available within the NetSuite customization platform.

Technical requirements

Since workflows and scripts can touch upon almost any feature within NetSuite, you might be working with anyone from your client's company on these activities. Good non-technical communication skills will help you smooth out this process and it always helps if at least one or more of the people you'll work with have completed the basic SuiteCloud platform training.

Identifying gaps and needs for automation in requirements

In the earlier chapters on gathering requirements, we talked a lot about how you can't help a client solve their real-world issues without first really understanding their processes and people. For a consultant, that always involves being a good listener, asking the right questions, and suggesting the best solutions. Knowing the system well is a requirement (and yes, there's a lot to know!), but sometimes, you're going to run into situations where either no native feature does what your client needs, or where users don't want to perform a set of steps manually. As a reminder from previous chapters, your solutions to problems like these should always flow in this order:

  1. Look for native features. Try to convince the users to use them.
  2. If possible, create a SuiteFlow to streamline the work.
  3. Look for partner solutions (also known as SuiteApps) that can meet the client's requirements or automate processes for them.
  4. Create a SuiteScript as a last resort.

On that first point, sometimes users will say they can't live with a native feature, but in many of those cases, they're not clear on how small the ask is of their time or they're forgetting how infrequently it will be a problem they need to solve. We try hard to quantify every automation request and to convince the users that they will be OK with the manual process whenever we can. Of course, if someone says they need to do something 50 times per month, that's enough to make an automation worthwhile.

My recommendation here comes from the experience of working on many client projects where, for one reason or another, we couldn't complete all of a client's use cases with native features. SuiteFlows (or workflows) are automations we can create and maintain in the NetSuite user interface (UI), usually without any code or other highly technical underpinnings. Most intermediate or more advanced NetSuite users can learn how to create a workflow in an afternoon and then learn how to fine-tune and optimize them over time. This is preferable to bringing in a third-party solution (a SuiteApp from the Marketplace) since there's no cost involved with SuiteFlows. But that option is better than having someone create SuiteScripts in my opinion (and I've specialized in creating scripts for NetSuite clients for a long time). I am always concerned not just about how long these things take to create, but also how difficult they'll be to maintain in the long run. And that's why I recommend following the earlier steps 1 through 4.

The native features are all well documented in the system, and you can learn what you need to know about the available SuiteApps from their providers, so in this chapter, we will dig into the custom workflow and script options. They are part of the SuiteCloud Platform, as NetSuite calls their customization tools. The platform also includes things like SuiteBuilder and SuiteTalk (web services). Both workflows and scripts are very powerful, but as you'll see next, they can also add complexity to the system.

Customizing NetSuite processes with workflows

Workflows in NetSuite are automations you can create via a point-and-click UI. They can work with almost any record in the system, and run either as records that are saved or edited or on a schedule in a batch mode. So you can, for instance, create a workflow that validates user inputs live while they're editing a Sales Order, or you can have a process that runs at midnight, finds all of your orders that require review, and flag them as such.

The most common use we have for workflows is to automate approval processes for records such as Journal Entries, Purchase Orders (POs), or Vendor Bills. They're especially suited for this task because they support multi-step processes and can include branches in their process depending on variable inputs. For instance, we can create a PO approval workflow that allows us to send the transaction to different people depending on the value in a custom field or on the total of the PO. Workflows can loop back and reset the state of a transaction as well. For instance, if the second approver in a chain rejects a PO for some reason, they can send it back to the original creator or to the previous approver.

Workflows are best for handling edits to header fields on transactions, and less suited to making changes to sublist line details (such as an Item line on a Sales Order). Workflows do support this to a limited extent, but only for the Items sublist on transaction records. That means, for instance, that we can't apply actions to the Apply sublist on a Customer Payment. However, for items on most other transactions, we can validate their values and then edit those line or body fields, create new records, send an email, or display an error from many types of transaction records.

The first screen we see when creating a new SuiteFlow allows us to first choose between creating a new workflow from scratch or starting from one of the NetSuite-provided templates. As of 2021, there are three templates available, and they're approval flows that can work with Journals, POs, or Sales Orders. It's not possible at this time for us to create our own templates.

When we opt to create a new workflow, we then choose the record type(s) the flow will monitor and a few other settings, such as how it will handle logging. Workflow logging appears on the record's screen in the UI, so users can troubleshoot without having to look elsewhere. Notice in the following screenshot, that unlike other places in the system, we don't get to select Sales Order as the record type; instead, we need to select Transaction generically, and then Sales Order as one of the so-called SUB TYPES. This allows us to apply one workflow across multiple types of transactions, which is a very common use case.

Figure 18.1 – Creating a new workflow, selecting a record type

Figure 18.1 – Creating a new workflow, selecting a record type

Once you've made these selections, click Save to move on to defining your workflow's states and transitions, and actions. States are what the system calls the steps in the workflow's process, and transitions connect one state to another. For instance, I've set up a workflow here that would start whenever a sales transaction is saved, review a few field values on the transaction, and if any fail that validation, then display a message to the user warning them of the problem. Otherwise, when all validations pass, the user will be allowed to save the transaction.

You can see in the following screenshot here that we branch in one of two directions from the initial state in the flow. We place those conditions into the transition lines that connect each state box.

Figure 18.2 – A workflow with three states and two transitions

Figure 18.2 – A workflow with three states and two transitions

Inside each State box, we can enter actions, and those allow us to control the flow the user will experience while working on their transaction. There are quite a few types of actions, including adding a button to the page, sending the user to another page, locking the record from all further edits, setting field values, and displaying a message to the user (the NetSuite Help lists all of the available actions). We can add as many actions as we need in any single state, and we can group them if we need to, as well. A special type of group is needed when we want to perform any actions on a sublist, and that's called a Sublist Action Group. Within one of these, we can perform a few actions on the Items sublist if there is one available on the transaction. So, for instance, if we want to look at a field value on a Sales Order item line and then display a message to the user when it breaks a rule, we can do that with a Message action inside of a Sublist Action Group.

Workflows are very powerful. We can do a lot with them, well beyond just approval workflows, but know that they can get complicated pretty fast, and controlling their conditions and events and so on is for more advanced users. Most of my clients have had at least a few people who could learn to do this in a short time, and so could create their own simple workflows whenever they need to. However, once a workflow has more than a couple of states with lots of conditions and various events it is triggered on, there's definitely a skill to making it not interfere with other operations on the given record in the system. Anyone can learn to do this, but practicing in a Sandbox or Development account is a good idea since we can't ever afford to cause issues in a live Production account.

So, we like workflows because they're completely defined by a user working in a point-and-click UI in the system. But let's move on next to learn about scripts, which are developed in a different way while offering similar automation options.

Making NetSuite work for you with scripts

As I mentioned in the previous section, there are requirements from a client that cannot be met via native features, workflows, or any existing SuiteApps. In these cases, we typically consider whether a SuiteScript can meet the client's need next. A script is a lot like a workflow, except for a couple of differences.

First, they are developed with what we call code, which is a set of script commands written out in a text file. NetSuite offers its own programming language for automating tasks within the system, and that's SuiteScript. It's based on JavaScript, a very common web programming language that's been around for a long time. There are a lot of developers in the world with JavaScript experience, although learning how to use SuiteScript is not nearly as common a skill.

Second, scripts are executed by the system in the background and they do not have any logs you can see when looking at a given record's screen. When a script changes a field's value, we do see that on the System Notes on the record, but otherwise, we have to look specifically at the script in question to see its logs, or we can create a search whose results show the same data.

Scripts are great for the same sorts of automation steps we use workflows for — validating user inputs, automating the creation of related records, and other UI tasks — but they can also be used to create integrations with other systems and scheduled processes that run in the cloud on whatever frequency we choose. For example, we create scripts for clients to set field values on records so their users don't have to remember to do this, and to automatically create Item Fulfillment transactions from Sales Orders when conditions indicate this can be done without a user having to click through those screens. We also create scripts to make web services call out to other systems, or to listen for web calls coming into NetSuite from other systems, for integration reasons.

In general, though, we don't ever want to get too carried away with all the powerful options scripts offer. We would not, for instance, want to build something completely unrelated to the NetSuite functionality on top of the system. As script projects get more and more complicated, they become difficult to manage and maintain, they can have a negative impact on the system's performance, and they can create confusion among users if they're not designed properly. All of the SuiteApps in the marketplace are solutions that combine SuiteBuilder custom objects (fields, records, lists, and so on) with scripts. However, these are all full-fledged products developed by professional developers with a lot of careful design time and plenty of testing applied to them. When you're considering developing a script for a client, always keep in mind that your time is limited and so keep your automations as simple as you can to avoid the problems I mentioned earlier.

To create a script in NetSuite, we follow these steps:

  1. Develop the code file on your workstation and outside of NetSuite.
  2. Upload that text file into the account, saving it into the File Cabinet.
  3. Create a new script using the UI.
  4. Create at least one deployment for that script, so NetSuite knows where and when it will run.

The Help system has many great examples of what SuiteScript looks like and it also goes into what it takes to develop a script. No fancy tools are needed though. If you're just copying a code sample from a SuiteAnswer page, for instance, Notepad (free with Windows) or TextMate (on Macs) is fine for the basic task. You just need a place to copy and type the text that won't apply any unwanted formatting (so Microsoft Word and other similar WYSIWYG editors are out). The process is very simple — just open the text editor of your choice, paste some code in there (if you have it) or edit your own code, save the file with a .js extension, and upload that file into the SuiteScripts folder in NetSuite.

The following example is not a complete script, but it should be just enough code that you can see how we mix JavaScript and SuiteScript commands in them to accomplish our goals:

function pageInit(ct) {

  let status = ct.currentRecord.getValue('status');

  if (status !== 'approved') {

    ui_message.create({

      title: "",

      message: "This PO needs to be approved, after you're

                finished editing.",

      type: message.Type.WARNING

    });

}

The function in the preceding sample might run as a page is being loaded in the UI for a user, and when it's executed, it will check the current status of the transaction it's associated with. If that status is not Approved already, it will display a warning message to the user on their screen. There is some JavaScript in there (the let and if statements) and some SuiteScript (the getValue() API call) and they are used together to make a fully functioning script.

The system supports a variety of script types, and it's good to know how the most commonly used script types can affect a client's data or the users, so let's break that down next.

Client scripts

These scripts run in the user's web browser when they're working in the NetSuite UI. Client scripts can be triggered to start their processing when a record is first displayed, or when a field or list entry changes, and so on. We can validate their inputs while they're editing a record, for instance, or display a message (confirmation, warning, error) when we need to. However, client scripts are more complicated to control and should be avoided for things like creating new records unrelated to the one the script runs against or performing multiple complex searches. Instead, push those automations to the server-side scripts.

User Event scripts

These scripts run in the NetSuite server cloud, in the background, as we say. They can be triggered before a record is loaded by a user or any automation process before it is saved into the system or immediately after. I'm pretty sure User Event scripts are the most commonly developed script type, since they have the lowest impact on the user's perception of system performance, and they are capable of making almost any change we need in an account.

However, the trade-off with this script type is that they don't run while the user is still editing a record – the user has to save the record before the script will complete its process.

There are many reasons why we might create a User Event script. We can use them to create new custom records to go along with a transaction after the user saves it. User Event scripts can also be used to send data from a Sales Order out to a third-party logistics system in something close to real time, when that's needed.

Scheduled and Map/Reduce scripts

When we have an automation task that does not need to run in real-time against a single record, we can create one of these batch process scripts to run in the background instead. Both Scheduled and Map/Reduce scripts run on a predefined schedule (or they can be triggered manually). However, scheduled scripts always run in a single thread, performing whatever logic you write into the code file, and then exiting. Map/Reduce scripts though can make updates to records in a multi-threaded way, using multiple processors or servers to do their work simultaneously. Either of these scripts is great for batch processing, either running at regular intervals throughout the day, or once per day, week, and so on.

Suitelets and RESTlets

When we need to create a custom page in the UI for users to visit to perform some custom function, we usually create a Suitelet. These are scripts that run when accessed via a menu option. They display whatever data we want on the page, and allow users to interact with that data in a variety of ways. For instance, these pages very commonly display one or more tables of data, with a checkbox shown on each row, allowing a user to choose which one they want to act on. Suitelets usually include a Submit button, which can trigger further automated actions. Just recently, for instance, I created a page like this for a client who wanted to see a list of POs that did not yet have a Vendor Prepayment applied. The user could select the orders they know should have payments applied, and when they select the Submit button, the script generates those Vendor Prepayments automatically, in no time at all.

A RESTlet sounds like it's similar to a Suitelet, but these scripts have their own separate use-case. We create them when we need to provide a mini-web service in the account, always listening for requests to come to it from outside of NetSuite, and performing some processing. This is usually some very limited action, such as updating Sales Orders based on the data being passed in, or searching for and returning a set of data in the script's response. We don't use RESTlets when we need a full-blown integration with another system, such as when many record types need to be passed to it (since they have a relatively short timeout for sending a response), but they're great for the situation where just one kind of data needs to come into NetSuite or go out to another system in a limited way.

There are other script types as well, for instance, Portlet scripts allow us to customize the contents of a portlet on user dashboards. They're all described on the Help page, along with all of the supported API calls, and more. However, this topic is very complex, so it's always recommended that users looking to create scripts take the NetSuite-offered training courses to gain a solid understanding before they go too far with development. And just as I said for workflows, developing in a Sandbox or Development account is critical to ensure we avoid issues in our live Production account.

Once you've committed to creating one or more scripts, you should have an idea of how you're going to document how they work, which parts of the system they touch upon, and so on. Let's dig into that topic next.

Documenting customization requirements and solutions

When we work with scripts in clients' accounts, we usually need to create a couple of types of documentation to support our work. It's not enough to just have automations running in the account – users need to know how they affect their work, and administrators need to know how to maintain/change them in the future. The first document we typically provide to clients is a requirement and design document. This should be a very plain English document which any user can make sense of. This isn't the place for a lot of technical terms or code samples or even what we sometimes call pseudo-code. Instead, I like these documents to have at least three sections:

  • A clear statement of the problem we're trying to solve with the customization.
  • A detailed functional description of the client's requirements for it.
  • A good understandable description of the solution we'll create to meet the requirements.

With this, the client can review the document upfront and decide whether we really understand what they're looking to achieve, and they can also use the document in the future too, to remind them of what the automation actually does (and doesn't do) in their account.

In one of these functional designs then, when we describe the problem, requirements, and solution, we try to follow a few simple rules to make sure they communicate well and nobody gets lost in their details.

Here are some guidelines you can follow when writing one of these functional documents:

  • Problem statements are written from the user's perspective. So, Users need to be able to process a third-party payment from Sales Orders is good. NetSuite needs to process third-party payments is wrong, since it's not the system that needs to solve this problem.
  • Requirements should name the real features they will involve, should include quantifiable values, and should not mention how we'll solve them. A script will automatically fulfill certain Transfer Orders is not good enough, since we don't know which Transfer Orders are affected, and also no client ever asks for a script to be written. Instead, they ask for automations and let you tell them how it will get done. The better wording would be the following: Users require that when inventory is transferred from the Secondary Warehouse to the Main Warehouse, the transfer orders are fulfilled automatically.
  • Solutions should be specific, but not technical. I don't like to mention the type of script I plan to create here unless I'm sure everyone reading the document will be technically inclined (which is rarely the case). Instead, I focus on how the solution will work from the user's standpoint: An automation will run as Transfer Orders are saved into NetSuite and it will … I do mention any custom configuration the solution will use though, so custom fields and records and lists should be named here. Lastly, I try to address how the automation will perform and how it will scale with the business — for example, The automation will add about 2 seconds to new Sales Orders processing time or, The automation will be able to process up to 100 Purchase Orders in any 60-minute window of operation. This sets an expectation with the client which helps us avoid performance-related concerns later on, which can be a real problem if you've not nailed this down very early on in the script's development.

If we create multiple scripts, and the client installs multiple other SuiteApps and solutions from other vendors, it gets very hard to keep track of what's a native feature and what's custom. When this happens, it's nice to provide an overview flow diagram as well, showing the client how their business processes have been customized and which parts are native features versus the custom things we've added on. This kind of diagram will be invaluable to the administrators and we usually encourage clients to maintain the document after we're done working with them, as part of their long-term change management process.

Here is a very simplified version of a flow diagram, just to show you what these things can look like:

Figure 18.3 – A very simple Sales process flow diagram

Figure 18.3 – A very simple Sales process flow diagram

The main idea is that you need one of these diagrams for each business process which includes any customizations, and it should be very clear which steps use native functions and which use your customizations. It doesn't hurt to catalog your customizations in this same document, listing their names and the names of the records in the account which they read, create, modify, or delete. With this, the client's administrators can always tell where they need to focus their maintenance and upkeep over time, and this will also help them when they reach out to NetSuite or any other service for support after you've moved on from working with them.

Another aspect of workflow and script maintenance is code versioning and deployment planning since customizations don't move themselves from one account to the next. I will talk about those topics next.

Managing customizations over time, including their deployments

Once you have added any custom things to an account, including custom records and searches and forms and roles and potentially so much more, you need a way to manage those things outside of the system. This should be part of the client's change management process, and you will probably be asked to help them get that set up. If you've just created a couple of scripts and a workflow, it's not hard to help the client find those things in their account and to keep track of them in a simple spreadsheet or similar document. The document you choose to use just has to list all of the custom things your solutions are using, including fields and searches and so on, and the workflows or scripts they use too. That can be one large document listing everything, or one customization-specific deployment document for each custom solution you've delivered. Handing this documentation to the client near the end of their implementation project can really help keep them organized and give them a sense that they know what they're going live with.

But that approach starts to fall when you add a lot more components and have many separate solutions in use. At some point, maintaining the spreadsheet based on searches of object types from the system becomes too difficult. NetSuite doesn't let us tag each custom thing we create to named customization, for instance, so it can become confusing to figure out which solution a custom field is used with or whether it's still even needed in an account.

Beyond about 10 custom solutions, most clients will look for some help, since users will forget to report changes they make sometimes, and there are just so many things to keep track of. In these cases, we've recommended a third-party solution that can keep an eye on all custom objects created/modified/deleted in an account by any user, and then report on those changes in lots of useful ways. When this seems appropriate, I suggest my clients check out the StrongPoint solution in the SuiteApp Marketplace. I do not recommend any specific solution in cases like this, since I want the client to figure out for themselves whether someone else's custom application will work for their needs, but this is currently a solid suggestion to make.

In addition to managing the custom objects in the account, it's important for a client to know how to move those things from one account to another (such as if they begin using a new Sandbox or Development account). Moving SuiteApps is not a challenge, since they're packaged up and easily installed in any account we need. But moving a custom solution consisting of two scripts, three searches, and a few email templates from a Sandbox takes a little more work.

For many years now, the main option we've had for doing this within NetSuite has been the SuiteBundler. It's a point-and-click tool we can access directly in any account's UI to create so-called bundles of custom configuration objects we've created there. Those bundles can then be installed into any other account we have access to. This works great for creating new things in a destination account for the first time, like when we first move a set of things from our development sandbox to our testing account. However, issues can arise when using the SuiteBundler to update things that are already in the second account. It doesn't always handle overwriting or replacing things as we might want, and that can create problems if we're not aware of the potential, or validating the results carefully enough.

A newer option that's just become available in the last few years is called the SuiteCloud Development Framework (SDF). This is a more technical tool; however, it's also much more powerful and, for technical users with a little training, it's a life-saver. What it does is allow us to collect a set of code files and custom objects from one account (again, say that's your development account) and then package up that set of things into an SDF Project and deploy that into any other account when we're ready to. For me, the main advantage of the SDF approach over bundles is that they give me a great deal of control over what I am deploying. I can, for instance, grab a copy of a custom record type from one account, change its definition offline on my workstation, and then deploy that modified version to another account. This is possible because of the way the SDF defines a text file for each custom object we add to the project, and so we can edit that file when we need to.

If you've never used this before, you can check out the Help and SuiteAnswers pages for more on this really helpful feature. There's also a simplified version of the SDF built into the UI for most types of custom objects, called Copy To Account. We can only use it to move one specific object to another account at a time, but many non-technical folks I work with have told me they love having this option available to them.

I hope you've seen how important it is to both track your customization work outside of the system (for disaster recovery and change management reasons) and to also have a plan in mind for how you will move your custom work from one NetSuite account to another. The tools I suggested here are not terribly hard to learn, but they can be a real game-changer for larger clients who start to struggle with the complexity of all of their customizations.

Summary

NetSuite is a great product, combining so many disparate parts together into one streamlined system — CRM/ERP/Web Store, and so on. But since every business that uses the system is unique, it's not uncommon to find reasons why they need either customizations or automations to make their processes even more efficient. Workflows are great for approval and for many other processes where we just want a relatively simple condition applied to some data. They include branching flows in one of multiple directions so we can really model the system's behaviors closely on what they need.

However, when a workflow can't do what is needed, we turn to SuiteApps from partners, and then to creating our own custom scripts. They add complexities and schedule delays and usually also costs to an implementation project, so we keep scripts as a last resort in all cases, but sometimes there is no alternative. NetSuite doesn't charge extra to have a script running in an account, but there are always costs involved in their design, development, and testing to be mindful of.

When any implementation project includes a set of customizations, we need to help the client keep track of them in some useful way and that usually includes documents listing all of them and highlighting their functions. Managing those customizations' deployments from one account to another is yet another thing we must learn to do well since no client has the expertise to do this themselves during a normally brief implementation time frame. You'll do well to keep all these things in mind when the subject of customizing an account arises.

In the next chapter, I will discuss integrations with other systems, and how we manage clients' requirements and expectations about them.

Self-assessment

Here are some simple thought experiments you can consider. Think about how you would handle each of these situations if they came up in one of your NetSuite projects.

  1. You're on a requirements gathering call with your client when they let you know that they don't like how customer payments must be manually applied to a set of open invoices. They ask if there's any way to have NetSuite apply the payment to the oldest open invoice first, and then the next oldest, and so on. How can you help them with this, without creating a workflow or a script?
  2. During a working session with a group of sales reps where you covered sales commissions, Susan reminds you that they have a custom gross profit field in effect on Sales Orders. She asks if there's a way to change the commission calculation to use that custom gross profit field's value instead of the native fields. Is there a way you can accomplish what she's asking for with a SuiteFlow?
  3. Your client's service business includes the use of Charge records in their accounts, which will tie into the contracts they sign with their customers. They've asked you to automate an update on every Charge record to make sure the data is prepared correctly before it gets applied to their Invoices. They will create approximately 10,000 Charges per month (throughout the month) and generate something like 2,000 Invoices (at the end of each month). You are debating between these two types of scripts to automate this process: a User Event that would run on save of every Charge, or a Map/Reduce script, which would run once per day to process all of the new Charges created that day. What are the advantages and disadvantages of each script type in this context?
  4. ABC Co is nearly ready to go live in their NetSuite account. Your team has created a set of scripts and workflows to customize and automate certain key business processes for them during their implementation. You've already provided them with a document listing each of those automations and their purpose. Now, they're asking if there's any way for you to include that information somewhere within their NetSuite account. There are a number of ways you could accomplish this, given some time. Can you think of a few ways you could help them with this request?
  5. During the implementation project, your team has created many custom objects for a client. You've documented them all and are prepared to move them into Production just before the scheduled go-live. Included in those custom objects are a set of Forms that include many tweaks from the standard options. The client lets you know that they've already customized their Forms in Production, so they don't want you to deploy your Forms, as your settings might overwrite their changes, and they're upset now. Think of a couple of ways you could use either the SuiteBundler or the SDF to work around this issue.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.217.177