Aleksandar Đokić
Aleksandar Đokić

Reputation: 2343

SuiteScript 2.1 record updates too slow

I have afterSubmit function that I wrote that will iterate through all related transactions connected with the same CTG_ID value (which is a custom parent record) and the script will actually update just one field on all of these values.

My problem is because this is a really slow method, more transactions I have connected to the same parent more time the user needs to wait after clicking the "Save" button. Script execution time is terrible.

Is there any faster / better way to update a certain field on a group of records?

My function for updating those transactions:

function afterSubmit(context) {
        const newRecord = context.newRecord;
        const ctgId = newRecord.getValue({ fieldId: 'custbody_ctgid' });
        const currentCustomerPo = newRecord.getValue({ fieldId: 'custbodyctg_customer_po'})

        search.create({
            type: 'transaction',
            filters: [['custbody_ctgid', 'anyof', ctgId],
                "AND",
                ['mainline','is','T']],
            columns: ['custbodyctg_customer_po']
        }).run().getRange({start: 0, end:100}).forEach((result,line) => {
            const ctgPo = result.getValue('custbodyctg_customer_po')        as string;
            const recType = result.recordType;
            const recId = result.id;
            let rec = record.load({
                type: recType,
                id: recId,
                isDynamic: true
            })
            rec.setValue({
                fieldId: 'custbodyctg_customer_po',
                value: currentCustomerPo,
                ignoreFieldChange: true
            })
            rec.save();
        })
    }

Thanks to Brian Duffy's answer, this is working a lot better!

I modified the script so now I iterate through results with each instead of forEach function. I'm using record.submitFields function instead of record.load

function afterSubmit(context) {
        const newRecord = context.newRecord;
        const oldRecord = context.oldRecord;
        const ctgId = newRecord.getValue({fieldId: 'custbody_ctgid'});
        const currentCustomerPo = newRecord.getValue({fieldId: 'custbodyctg_customer_po'})
        const oldCustomerPo = oldRecord.getValue({fieldId: 'custbodyctg_customer_po'})
        if (oldCustomerPo !== currentCustomerPo) {
            search.create({
                type: 'transaction',
                filters: [['custbody_ctgid', 'anyof', ctgId],
                    "AND",
                    ['mainline', 'is', 'T']],
                columns: ['custbodyctg_customer_po', 'type']
            }).run().each((result) => {
                if (result.recordType !== 'salesorder') {
                    const recType   = result.recordType;
                    const recId     = result.id;

                    record.submitFields({
                        type: recType,
                        id: recId,
                        values: {
                            custbodyctg_customer_po: currentCustomerPo
                        },
                        options: {
                            enableSourcing: false,
                            ignoreMandatoryFields: true
                        }
                    });
                }
                return true;
            })
        }
    }

Still, after testing few transactions with an average of 5 linked transactions to them this is running like 5-7 seconds. Stil slow for me. If anyone has suggestions it would be AWESOME!

Upvotes: 0

Views: 1225

Answers (2)

Joshua Henke
Joshua Henke

Reputation: 11

If speed of saving the current record is key, consider making your logic asynchronous. The current record will save nearly as fast as normal, just taking the time to schedule a Map/Reduce or Scheduled script.

The user event script would just send as parameters the current record's Id, the value in CTG_ID and the value in custbodyctg_customer_po. The asynchronous script would search for all tranx with that same Id except for the one that triggered it (or skip any records with a matching value while looping thru results), then submit the custbodyctg_customer_po for each of those.

It's a heavier solution, so you must weigh priorities.

Alternatively, look into record.submitFields.promise(options). It seems a limitation is it cannot update Select fields (ie List/Record)

Upvotes: 1

Brian Duffy
Brian Duffy

Reputation: 162

I would try using run.each instead of getRange for your search results and use record.sumbitFields instead of loading and saving the record.

Upvotes: 1

Related Questions