scottvonduhn's Profile



  • There are a few potential solutions to this.  First, are you loading an existing saved search (defined outside of code), or are you building the search directly inside the script?  If you build the search in the script, one of the simpler ways to fix this is by adding a suffix to the column name, for example:   formulatext_one, formulatext_two, or formulatext_display, formulatext_sort.  The best way is to just use your existing unique label as the suffix.  You can use this with any of the formula types.  See the solution here:

    Alternatively, you could redefine the saved search as a SuiteQL query, which provides the column resu lts as an ordered array to the map stage.  With SuiteScript 2.1 and destructuring, it’s very easy to assign each column the variable name you want.

    This answer accepted by aleseux. on April 4, 2023 Earned 15 points.

    • 2 answers
    • 0 votes
  • You should add logging at the very beginning of the entry point to verify it is running.  There are many settings that could impact this.  UE scripts can have script contexts filtered out at the deployment level.  Users and roles can also be filtered out for a UE script.   However, one final thing to consider.  If you have any SuiteCloud+ licenses, you could still have a race condition with your UE script if using multiple threads or queues for CSV imports.  This approach cannot prevent against that, no matter how it is written.  You should also remove the edit type from the script, or else it will prevent the editing of any existing records, since it does not filter itself out in the duplicate check.

    • 6 answers
    • 0 votes
  • One thing to be careful of, this User Event runs for both Create and Edit, but you probably only want or need to prevent a duplicate in Create mode.  I’d still recommend the use of the external id just for the simplicity of it.  Two ore more user events could run at nearly the same time, and there could be a race condition, where multiple UE scripts find no existing record with the two values, so they all proceed to create their records regardless.  The problem is that time passes between checking for the existing record, and the eventual saving of the record.  To ensure it never created duplicates, the check and save would have to be a single operation, but there is no API in SuiteScript for that.  The externalid approach is the only way I know of that avoids the possibility of race conditions for this kind of scenario.  It is very difficult to achieve that in SuiteScript, unless you are using a scheduled script where only one deployment can run at a time.  The best you can do otherwise is to prepare the record, then do the duplicate check at the very end, to shorten the time duration before the record is saved as much as possible.

    Also, the saved search in the code has no filters, which means it will take longer to run, and then even more time to loop through the results.  You would instead want a search that only looked for records with the two values you want to find.  Then, you just need to check if there were any results at all.  For the duplicate check to be successful, the function has to be as efficient as possible, because even then there is still a race condition, but you can limit the impact of it.

    • 10 answers
    • 0 votes
  • Are the two fields globally unique, or just unique for the record they are attached to?  If they are globally unique, you could combine both field values into a single string and set that as the external id, assuming you aren’t already setting a different value in the externalid.  Netsuite will prevent duplicate creation and throw a DUP_CSTM_RCRD_ENTRY error.  If the two values are not globally unique, then maybe a combination of those two values and the internal id of the record they are being attached to would work instead.  For example:  custrecord_field1 + ‘~’ + custrecord_field2   or + ‘~’ + custrecord_field1 + ‘~’ + custrecord_field2, using whatever separator character makes sense.

    • 10 answers
    • 0 votes
  • Beginner Asked on November 1, 2021 in How To's.

    As of the latest release, the NLAuth format for Restlet authentication is no longer accepted, which is why you are receiving that error message.  You must use what NetSuite calls Token-based Authentication, which is really just OAuth 1.0

    Postman supports OAuth 1.0, so it should be just a simple matter of setting up your access tokens in NetSuite, then changing the Authorization type in Postman and filling in the correct values, including the realm.

    • 1 answers
    • 0 votes
  • Beginner Asked on September 28, 2020 in SuiteAnalytics Connect.

    You can do the conversion locally.  What database are you using?  If SQL Server, the following may work:


    Make sure that the date you are getting back really is in UTC, otherwise this conversion will not produce the correct output.

    This answer accepted by rbigej. on September 28, 2020 Earned 15 points.

    • 1 answers
    • 0 votes
  • Yes, with SuiteScript 2.x using the N/file module, it is possible to create larger files by streaming the content.  You can write out a file by appending individual lines, and each line can be up to 10MB in size.

    • 2 answers
    • 0 votes
  • Beginner Asked on June 18, 2020 in SuiteApps.

    Even if this was easily achievable, I would advise strongly against doing this.  Your filing cabinet space is limited.  If you exceed your storage the costs to upgrade your service to a higher tier could be substantial.  You would be better off storing photos in an external system.  A cloud storage service would be much more cost-effective.  There are some that integrate with NetSuite that could be worth looking into.

    But, what is the source of these sales orders?  Are they created in NetSuite, or are they digital documents created outside of NetSuite that are printed out, then you take a photo of them?  If they are digital, I would find a way to integrate and store the original documents in NetSuite instead.  If these are hand-written sales orders, then now would perhaps be a good time to consider using NetSuite’s native Sales Orders instead, then the information would already be available in NetSuite, and no camera or photos would be needed.  This photographing process seems very time-consuming and manual, and I would find a way to eliminate or automate it using whatever technology you can.

    • 1 answers
    • 0 votes
  • SuiteScript 1.0 will work with the crypto-js library, and it may be easier to work with than the NetSuite crypto libraries.  It isn’t possibly to directly call SS 2.0 code from 1.0.  You can add the crypto-js.min.js as a library to your 1.0 script, then you can just use a function similar to the following to generate the Digest:

    function generateDigest(jsonString) {
        return 'SHA-256=' + CryptoJS.enc.Base64.stringify(CryptoJS.SHA256(jsonString));
    var digest = generateDigest(jsonString);
    nlapiLogExecution('DEBUG', 'Digest', digest);

    You’ll need to tweak this according to the CyberSource documentation and the integration method that you are using.

    This answer accepted by larryw11980. on June 5, 2020 Earned 15 points.

    • 1 answers
    • 0 votes
  • Beginner Asked on April 15, 2020 in SuiteScript.

    One bit of advice is that if this is a brand new Restlet, you’d be well-advised to use the SuiteScript 2.0 API for this restlet script, rather than 1.0, as that API is deprecated.  There are some additional benefits of SS 2.0 as well,  particularly when working with checkbox fields, as you can actually set them with JavaScript boolean values: true/false, instead of ‘T’/’F’ that is required with SS 1.0.  You could then simply call

    customer.setValue({ fieldId: 'isperson', value: data.isperson });

    This looks like a POST request handler function, so the best approach is to set the Content-Type header to application/json, and then send a JSON string as your request body (set the radio button to raw).  The restlet engine will automatically map the JSON input to a JavaScript object (data). It would look something like this:

    "companyname": "Company Name Here",
    "subsidiary": 2,
    "isperson": false

    If you don’t set the Content-Type, the input will be treated as plain text, so you’d have to parse the data yourself before using it.

    • 2 answers
    • 0 votes