https://netsuiteprofessionals.com logo
Join Slack
Powered by
# suitescript
  • c

    Craig

    05/08/2025, 3:26 PM
    Is there any shared key/field between invoice lines and sales order lines? I need to match the lines between transactions.
    a
    s
    • 3
    • 17
  • k

    kns25

    05/08/2025, 3:53 PM
    Hi everyone, does anyone tried storing the time or date an Invoice was sent in Versapay? Storing it on a custom field in the Invoice record. There is a Send Reminder button in the Versapay Network Invoice page then I would like to get the time or date when a user hit that button to store on a custom field.
  • k

    Kristine

    05/08/2025, 6:00 PM
    When submitting a CSV import task via script using the
    N/task
    module, the
    task.checkStatus()
    method only indicates whether the job is *Pending/Completed*—it does not provide detailed results on whether the import itself was successful or if it encountered errors. See screenshot this would appear Completed but actually is a failed import of 0/2 records Has anyone found a workaround to programatically retrieve detailed import results (success/failure counts, error messages, etc.) outside of manually checking the UI?
    a
    • 2
    • 4
  • a

    acuestajohnmark

    05/08/2025, 8:29 PM
    Good day mates, I'm trying to work on a custom GL plugin that checks for all the GL lines and if it does not match the main line location, It would create lines to point the amount to the same location as the main line. I am writing the custom GL plugin using SS2.x and has been following the guide found in SuiteAnswers. Now I have encountered this weird behavior where in if I am using loops to get line details, it just returns me the detail for line 0 (main line). But using the get line outside of a loop and feeding it a static value gives the actual line detail for whichever index was used.
    Copy code
    /**
     * @NApiVersion 2.x
     * @NScriptType customglplugin
     */
    define([
        'N/record'
        ],
        /**
         * @param {record} record
         */
        function (
            record
        ) {
            function reclassifyInterBranchInvoicesToMainLocation(scriptContext) {
                try {
                    const invoiceRecord = scriptContext['transactionRecord'];
                    const standardLines = scriptContext['standardLines'];
                    const customLines = scriptContext['customLines'];
    
                    const transactionType = invoiceRecord['type'];
    
                    const mainlineLocationId = invoiceRecord.getValue({
                        fieldId: 'location'
                    });
    
                    const standardLinesCount = standardLines.count;
    
                    log.audit({
                        title: 'Details',
                        details: {
                            mainlineLocationId: mainlineLocationId,
                            standardLinesCount: standardLinesCount
                        }
                    });
                    const standardLinesArr = [];
                    for (var i = 0; i < standardLinesCount; i++) {
                        const standardLine = standardLines.getLine({
                            index: i
                        });
                        standardLinesArr.push(standardLine)
                    }
    
                    const manualStandardLineArr = [];
                    const line1 = standardLines.getLine({
                        index: 0
                    });
                    manualStandardLineArr.push(line1);
                    const line2 = standardLines.getLine({
                        index: 1
                    });
                    manualStandardLineArr.push(line2);
                    const line3 = standardLines.getLine({
                        index: 2
                    });
                    manualStandardLineArr.push(line3);
                    const line4 = standardLines.getLine({
                        index: 3
                    });
                    manualStandardLineArr.push(line4);
                    const line5 = standardLines.getLine({
                        index: 4
                    });
                    manualStandardLineArr.push(line5);
                    const line6 = standardLines.getLine({
                        index: 5
                    });
                    manualStandardLineArr.push(line6);
    
                    log.audit({
                        title: 'Standard Lines',
                        details: standardLinesArr
                    });
                    log.audit({
                        title: 'Manual Standard Lines',
                        details: manualStandardLineArr
                    });
    
                    if (transactionType === record.Type.INVOICE) {
                        log.audit({
                            title: 'TRIGGER INVOICE RECLASS HERE'
                        });
                    }
                } catch (errorObj) {
                    log.error({
                        title: 'Error in reclassifyInterBranchInvoicesToMainLocation',
                        details: errorObj
                    });
                }
            };
    
            return {
                customizeGlImpact: reclassifyInterBranchInvoicesToMainLocation
            };
    
    });
    I'm hoping to actually makes this work on SS2.x, but if there's no way around it, I'll just have to make it using SS1.0 As for the logs, here's what I am getting (tabularized for easier comparison):
  • e

    eblackey

    05/08/2025, 9:41 PM
    could you try this and see if it changes anything?
    Copy code
    for (var i = 0; i < standardLinesCount; i++) {
                        standardLinesArr.push(standardLines.getLine({
                            index: i
                        }));
                    }
    👀 1
    ✅ 1
    🙌 1
    a
    • 2
    • 1
  • e

    eblackey

    05/08/2025, 9:42 PM
    I would have expected your code to work by the way, so I'm curious.
  • a

    ashokkumar9640444

    05/09/2025, 10:52 AM
    Hi Team, I want to unselect the values in the Multiselect field while making a copy. I have used the below code to unselect/remove the values in that field. invoiceRecord.setValue({ fieldId: 'custbody_related_je', value: []}); But still, I can see the values are present in that field, and it is not making the value null. Can anyone please help me with this? Any suggestions or tips to resolve this issue?
    a
    • 2
    • 10
  • g

    G

    05/09/2025, 3:06 PM
    Generic question for the group: custom button workflow triggering a WF action script to set the reject button on a purchase order form with an expense line, reckon it would work? I've tried and although it's trying to set the status to rejected, it still doesn't work. (Not looking to use the native reject button)
    • 1
    • 1
  • s

    Slackbot

    05/09/2025, 4:06 PM
    This message was deleted.
    e
    d
    a
    • 4
    • 7
  • s

    Sitaram upadhya

    05/10/2025, 11:12 AM
    Hi everyone, I am encountering the following error while trying to create the credit memo, although the field value "6" for the taxcode exists -
    Copy code
    "type":"error.SuiteScriptError","name":"INVALID_FLD_VALUE","message":"You have entered an Invalid Field Value 6 for the following field: taxcode"
    Below is the code. Where am I going wrong?
    Copy code
    /**
     * @NApiVersion 2.1
     * @NScriptType Restlet
     * @NModuleScope SameAccount
     */
    define(['N/record', 'N/format', 'N/error', 'N/log'], 
    function(record, format, error, log) {
        
        /**
         * Function to handle POST request - creates a Credit Memo
         * @param {Object} requestBody - The request body from the external system
         * @returns {Object} Response object with created Credit Memo ID and other details
         */
        function doPost(requestBody) {
            try {
                log.debug('Request Body', JSON.stringify(requestBody));
                
                // Validate required fields
                if (!requestBody.entity) {
                    throw error.create({
                        name: 'MISSING_REQ_PARAM',
                        message: 'Entity (customer) is required'
                    });
                }
                
                // Create Credit Memo record
                const creditMemo = record.create({
                    type: record.Type.CREDIT_MEMO,
                    isDynamic: true
                });
                
                // Set header level fields
                creditMemo.setValue({
                    fieldId: 'entity',
                    value: requestBody.entity
                });
                
                // Set trandate if provided (format: mm/dd/yyyy)
                if (requestBody.trandate) {
                    const parsedDate = format.parse({
                        value: requestBody.trandate,
                        type: format.Type.DATE
                    });
                    
                    creditMemo.setValue({
                        fieldId: 'trandate',
                        value: parsedDate
                    });
                }
                
                // Set tax details override flag
                if (requestBody.taxdetailsoveride) {
                    creditMemo.setValue({
                        fieldId: 'taxdetailsoverride',
                        value: requestBody.taxdetailsoveride
                    });
                }
                
                // Add line items
                if (requestBody.lines && Array.isArray(requestBody.lines)) {
                    for (let i = 0; i < requestBody.lines.length; i++) {
                        const line = requestBody.lines[i];
                        
                        // Select new line
                        creditMemo.selectNewLine({
                            sublistId: 'item'
                        });
                        
                        // Set line item
                        creditMemo.setCurrentSublistValue({
                            sublistId: 'item',
                            fieldId: 'item',
                            value: line.item
                        });
                        
                        // Set amount
                        if (line.amount) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'item',
                                fieldId: 'amount',
                                value: line.amount
                            });
                        }
                        
                        // Set HSN code if provided
                        if (line.hsncode) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'item',
                                fieldId: 'custcol_in_hsn_code', // Adjust field ID as needed
                                value: line.hsncode
                            });
                        }
                        
                        // Commit the line - only need to commit once
                        creditMemo.commitLine({
                            sublistId: 'item'
                        });
                    }
                }
                
                // Handle tax details separately after all item lines are added
                if (requestBody.taxdetails && Array.isArray(requestBody.taxdetails)) {
                    for (let j = 0; j < requestBody.taxdetails.length; j++) {
                        const taxDetail = requestBody.taxdetails[j];
                        
                        // Select the tax details sublist
                        creditMemo.selectNewLine({
                            sublistId: 'taxdetails'
                        });
                        
                        // Tax code is required - make sure we have a valid value before proceeding
                        if (!taxDetail.taxcode) {
                            throw error.create({
                                name: 'MISSING_REQ_PARAM',
                                message: 'Tax code is required for tax details'
                            });
                        }
                        
                        // Set tax code first since it's required
                        creditMemo.setCurrentSublistValue({
                            sublistId: 'taxdetails',
                            fieldId: 'taxcode',
                            value: taxDetail.taxcode
                        });
                        
                        // Now set the other tax detail fields
                        if (taxDetail.linename) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'linename',
                                value: taxDetail.linename
                            });
                        }
                        
                        if (taxDetail.linenumber) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'linenumber',
                                value: taxDetail.linenumber
                            });
                        }
                        
                        if (taxDetail.linetype) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'linetype', 
                                value: taxDetail.linetype
                            });
                        }
                        
                        if (taxDetail.netamount) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'netamount',
                                value: taxDetail.netamount
                            });
                        }
                        
                        if (taxDetail.taxamount) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'taxamount',
                                value: taxDetail.taxamount
                            });
                        }
                        
                        if (taxDetail.taxbasis) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'taxbasis',
                                value: taxDetail.taxbasis
                            });
                        }
                        
                        if (taxDetail.taxdetailsreference) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'taxdetailsreference',
                                value: taxDetail.taxdetailsreference
                            });
                        }
                        
                        if (taxDetail.taxrate) {
                            // Remove percentage symbol if present and convert to number
                            let rateValue = taxDetail.taxrate;
                            if (typeof rateValue === 'string') {
                                rateValue = rateValue.replace('%', '');
                            }
                            
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'taxrate',
                                value: parseFloat(rateValue)
                            });
                        }
                        
                        if (taxDetail.taxtype) {
                            creditMemo.setCurrentSublistValue({
                                sublistId: 'taxdetails',
                                fieldId: 'taxtype',
                                value: taxDetail.taxtype
                            });
                        }
                        
                        // Commit the tax detail line
                        creditMemo.commitLine({
                            sublistId: 'taxdetails'
                        });
                    }
                }
                
                // Save the credit memo
                const creditMemoId = creditMemo.save();
                
                // Return success response
                return {
                    success: true,
                    creditMemoId: creditMemoId,
                    message: 'Credit Memo created successfully'
                };
                
            } catch (e) {
                log.error('Error creating Credit Memo', e);
                
                // Return error response
                return {
                    success: false,
                    error: {
                        code: e.name,
                        message: e.message
                    }
                };
            }
        }
    
        /**
         * Function to handle GET request - retrieves a Credit Memo by ID
         * @param {Object} requestParams - Contains the ID of the Credit Memo to retrieve
         * @returns {Object} Credit Memo data
         */
        function doGet(requestParams) {
            try {
                // Check if ID is provided
                if (!requestParams.id) {
                    throw error.create({
                        name: 'MISSING_REQ_PARAM',
                        message: 'Credit Memo ID is required'
                    });
                }
                
                // Load Credit Memo record
                const creditMemo = record.load({
                    type: record.Type.CREDIT_MEMO,
                    id: requestParams.id,
                    isDynamic: false
                });
                
                // Get basic info
                const creditMemoData = {
                    id: creditMemo.id,
                    tranId: creditMemo.getValue({fieldId: 'tranid'}),
                    entity: creditMemo.getValue({fieldId: 'entity'}),
                    tranDate: creditMemo.getValue({fieldId: 'trandate'}),
                    total: creditMemo.getValue({fieldId: 'total'}),
                    status: creditMemo.getValue({fieldId: 'status'})
                };
                
                return {
                    success: true,
                    creditMemo: creditMemoData
                };
                
            } catch (e) {
                log.error('Error retrieving Credit Memo', e);
                
                return {
                    success: false,
                    error: {
                        code: e.name,
                        message: e.message
                    }
                };
            }
        }
    
        // RESTlet entry points
        return {
            post: doPost,
            get: doGet
        };
    });
    a
    • 2
    • 2
  • t

    Tyn Guardian

    05/11/2025, 2:12 PM
    I am trying to create custom record using MR script. But I received this error messag "INVALID_RCRD_TYPE","message":"The record type [CUSTOMRECORD_FEATURE] is invalid."
    Copy code
    var deltaRecord = record.create({
                    type: 'customrecord_feature',
                    isDynamic: true
                });
    a
    • 2
    • 5
  • e

    Emanuel V

    05/12/2025, 12:20 PM
    Hi folks. I'm using server-side suitescript to get item data from an external API and then create the items in Netsuite. Is there some recommended approach to throttle the API requests when creating multiple items? I am making one request per item in a loop.
    e
    w
    • 3
    • 5
  • d

    dh_1101

    05/12/2025, 6:22 PM
    I'm trying to grab all fields related to 'inventory' item sublist in inventory adjustment form. It currently grabs surface level information. Is there a way to recursively grab all the related fields as well from 'inventory' sublist ? This is my current code:
    var inventoryLineCount = ia.getLineCount({ sublistId: 'inventory' });
    var inventoryLines = [];
    for (var i = 0; i < inventoryLineCount; i++) {
    var lineData = {};
    var lineFields = ia.getSublistFields({ sublistId: 'inventory' });
    log.debug('lineFields', lineFields);
    lineFields.forEach(function(fieldId) {
    lineData[fieldId] = ia.getSublistValue({
    sublistId: 'inventory',
    fieldId: fieldId,
    line: i
    });
    });
    inventoryLines.push(lineData);
    }
    return ({
    recordId: recordId,
    bodyFields: bodyFieldValues,
    inventoryLines: inventoryLines
    });
    }
  • s

    Shubham Jadhav

    05/12/2025, 9:23 PM
    Hey guys I am building a React app that is either: • Deployed as a static bundle inside a NetSuite Suitelet, or • Running locally during development. My goal is to fetch data from a NetSuite backend (Suitelet or RESTlet) using AJAX/fetch from the React frontend. However, I keep running into CORS errors when making these requests, both from my local React dev server and from the deployed Suitelet version. Has anyone faced similar issues? Any guidance would be greatly appreciated!
    m
    • 2
    • 4
  • b

    Bryan Miller

    05/13/2025, 5:41 PM
    I have a UE deployed to work orders that is trying to populate fields based on data from the createdfrom record. These are multi-level boms and the item source is set to work order so we create the top level in the UI and then the system creates all of the sub work order. The problem that I'm running into is that the top level work order doesn't seem to submit to the server until the lower levels are all saved so all of my search for the data to set to fields in the createdfrom are returning null. What is the best way to handle this? It's really just three fields that I need to write - two are static based on what is set at the parent work order and one is numeric so createdfrom.number + 1 to create a sequence.
    m
    • 2
    • 4
  • c

    Craig

    05/13/2025, 11:06 PM
    Do we know of anyone selling custom NetSuite bundles that aren't a part of the SDN (I've heard it's impossible to be accepted into SDN nowadays).
    m
    • 2
    • 1
  • s

    Scot Sunnergren

    05/15/2025, 2:59 PM
    I am trying to get a listing of when scripts run during the day along with the duration of the run, I created a saved search of the Server Script Log but that appears to only log entries that the script is programmed to log. There appears to be no default log entry of the start and/or end time of script execution if the script does not itself log those entries. I tried a saved search of Scheduled Script Instances and that gives me the start time of scheduled scripts but the end time is ALWAYS the same as the start time down to the minute. I know that we have scripts that take longer than a minute. ...and, unfortunately, that is only for scheduled scripts. Does anyone know a way to get more info on script execution?
    a
    e
    f
    • 4
    • 13
  • a

    Alan Fitch

    05/15/2025, 6:41 PM
    Any gotchyas when attaching a client script UE? I'm attaching the client script before load, but my pageInit code doesn't seem to be executed.
    e
    t
    • 3
    • 6
  • r

    Ryan Longenecker

    05/16/2025, 5:39 PM
    Hey all, I’m working on an integration and getting “invalid_grant”. Wondering if anyone has encountered this and found steps to resolve it? Thanks
    e
    • 2
    • 5
  • m

    Marc

    05/18/2025, 8:26 PM
    How can I reproduce NetSuite’s native progress tracking (percentage) for a Map/Reduce script? In the standard NetSuite UI (e.g., when creating transactions in batch), the progress of background tasks is shown as a percentage that updates in real-time. I’d like to replicate this behavior for a custom Map/Reduce process — ideally showing the live progress percentage in a Suitelet. So far, I’ve tried using getPercentageComplete() in the Map/Reduce, but it seems to only return 0% or 100%. I’ve also looked into caching or custom records to track the execution progress manually. Question: What’s the best practice to implement this kind of real-time progress feedback? Is there a recommended way to track and display the actual progress percentage of a running Map/Reduce, like NetSuite does internally?
    e
    • 2
    • 4
  • a

    Anek Porwal

    05/19/2025, 12:41 PM
    Hi Team, I have implemented a customization that adds a button to the Sales Order form using a User Event script. When this button is clicked, it opens a form prompting the user to input certain details. Upon submission, the form sends a POST request to a Suitelet, which performs additional actions. Once the Suitelet completes its tasks, it redirects back to the Sales Order. I would like to enhance the user experience by displaying a loading screen or spinner when the user submits the form, maintaining it until the Suitelet finishes processing and the redirection occurs. Is there a recommended approach to achieve this?
  • m

    M Ureddy17

    05/19/2025, 5:43 PM
    am getting this in my workflow and what mistake i did ?
    a
    • 2
    • 1
  • s

    Sarim Khan

    05/20/2025, 6:54 AM
    Hi everyone, I'm trying to call a RESTlet deployed in a different NetSuite account using OAuth 1.0 from SuiteScript (2.1). I have the consumer key/secret and token key/secret from the target account, and the RESTlet URL is correct and accessible when tested with Postman. However, I'm having trouble generating the correct OAuth 1.0 header in SuiteScript using
    HMAC-SHA256
    and
    N/crypto
    . I’ve followed the standard OAuth flow: building the base string, signing with the key, and encoding the header. But the response from the target account either shows an auth error or nothing at all. Has anyone successfully made a SuiteScript-to-SuiteScript cross-account call using OAuth 1.0? If so, I’d really appreciate: • A working example of generating the OAuth header using
    N/crypto
    • Any gotchas around formatting the
    Authorization
    header for NetSuite RESTlets • Advice on cross-account permissions or setup (token roles, integration records, etc.) Thanks in advance!
  • s

    sonu kumar

    05/20/2025, 9:29 AM
    Hello everyone, I am creating a cash sale from sales order using record.transform in the userEvent script, The cash sale is created successfully but it not showing on the related record of sales order. can any one help me out to resolve this issue.
  • s

    Shob S

    05/20/2025, 3:10 PM
    Does anyone use unit test cases with Jest to ensure script quality and reduce bugs? Curious to know what practices are generally followed to maintain development quality and minimize issues.
    a
    s
    c
    • 4
    • 44
  • c

    Craig

    05/21/2025, 10:13 AM
    I notice the beforeLoad entry point doesn't trigger on billing schedules - is this correct?
  • v

    Vishal Chaudhari

    05/21/2025, 11:34 AM
    How to image clickable in advance pdf template
    t
    • 2
    • 2
  • s

    Sim Greenbaum

    05/21/2025, 4:03 PM
    how can i hae a suitlet display on dashboard without recreating it to be a protlet ?
    e
    • 2
    • 2
  • c

    cweier

    05/21/2025, 11:05 PM
    Hi all, hopefully easy question that I am overthinking - does a user event script run no matter what has edited the record? Trying to run some automation on Item Location Configuration and have noticed they'll occasionally be created by System - would a UE script run in these instances?
    i
    s
    +3
    • 6
    • 14
  • l

    Luis

    05/22/2025, 3:04 AM
    Is it possible to show the actual role used by the user who triggered the suitelet in the system notes? Use case: When a user clicks the Reject button on a journal entry, the user is routed to the Rejection Reason custom record. Once saved, a suitelet is triggered to copy the rejection notes from the custom record to the journal entry. When we look at the system information of the journal, it doesn't show the actual user and/or role used.
    a
    • 2
    • 1