3

I would like to (eager) load a list of customers in netsuite that has been updated between 2 date/time range and have the results paginated.

I am relatively new to NetSuite SuiteScript 2.0, so I've implemented the lazy loading mvp version that works (without filtering) and it looks something like this:

define(['N/record', 'N/search'], function(record, search) {

    function loadClients(context) {

        var currencyMap = {};
        var statusMap = {};

        var results = [];

        search.create({

            type: search.Type.CUSTOMER,
            // todo: Workout how to apply filter to load only customers updated between two date ranges (supplied via context) using 'lastmodifieddate'

        }).run().getRange({

            start: context.start || 0,
            end: context.end || 100,

        }).forEach(function(result) {

            var customer = loadCustomer(result.id);

            var currencyId = customer.getValue({ fieldId: 'currency' });
            if (typeof currencyMap[currencyId] === 'undefined') {
                currencyMap[currencyId] = loadCurrency(currencyId).getValue({ 
                    fieldId: 'name'
                });
            }

            var statusId = customer.getValue({ fieldId: 'entitystatus' });
            if (typeof statusMap[statusId] === 'undefined') {
                statusMap[statusId] = loadStatus(statusId).getValue({
                    fieldId: 'name'
                });
            }

            results.push({
                tax_number: customer.getValue({ fieldId: 'vatregnumber' }),
                name: customer.getValue({ fieldId: 'companyname' }),
                first_name: '',
                last_name: '',
                updated_date: customer.getValue({ fieldId: 'lastmodifieddate' }),
                has_attachments: '',
                default_currency: currencyMap[currencyId],
                is_supplier: 0,
                contact_id: customer.id,
                email_address: customer.getValue({ fieldId: 'email' }),
                phones: customer.getValue({ fieldId: 'phone' }),
                is_customer: 1,
                addresses: customer.getValue({ fieldId: 'defaultaddress' }),
                contact_status: statusMap[statusId],
            });

        });

        return results;

    }

    function loadCustomer(customerId) {
        return record.load({
            type: record.Type.CUSTOMER,
            id: customerId,
            isDynamic: false
        });
    }

    function loadCurrency(currencyId) {
        return record.load({
            type: record.Type.CURRENCY,
            id: currencyId,
            isDynamic: false
        });
    }

    function loadStatus(statusId) {
        return record.load({
            type: record.Type.CUSTOMER_STATUS,
            id: statusId,
            isDynamic: false
        });
    }

    return {
        post: loadClients
    }

});

As you can see, due to lack of knowledge of how this works, I am doing incredibly inefficient data loading and it's very slow. Takes approximately 1 minute to load 100 records.

Does anyone know how to achieve the above with filtering on lastmodifieddate for the date/time range and eager loading correctly?

Latheesan
  • 23,247
  • 32
  • 107
  • 201

1 Answers1

4

The main issue here is that you are loading each entire customer record individually. It's unlikely you actually need to do that. My suggested approach instead would be to include the results you need in the search columns. Something like:

var results = [];
search.create({
    type: search.Type.CUSTOMER,
    filters: [['lastmodifieddate', 'within', '1/1/2018', '2/1/2018']],
    columns: ['vatregnumber','companyname', 'lastmodifieddate', /*ETC*/ ]
}).run().each(function(result) {
    results.push({
        tax_number: result.getValue('vatregnumber'),
        name: result.getValue('companyname'),
        updated_date: result.getValue('lastmodifieddate')
    });
    return true;
});

To create the filter dynamically, you would have to pass a start and end date as parameters within the post body ( {startDate: '1/1/2018', endDate: 2/1/2018} ), and use them in the filter, like:

filters: [['lastmodifieddate', 'within', context.startDate, context.endDate]]
Krypton
  • 4,394
  • 2
  • 9
  • 13
  • hey thanks a a lot for this approach. Customer's could have one or more contacts. What if I want to load the default contact on the customer record (so that i can get to their firstname/lastname for example)? How would you define that in the search column criteria and then get to the value via `getValue()`? – Latheesan Aug 15 '18 at 15:14
  • Nevermind; I've figured it out after some experimenting. If I did `contact.firstname` in the search column, it eager loads the relationship (customer -> contacts) and on the primary contact of the customer, grabs the first name and returns it on the field (on result object) like this: `contact.firstname` - phew! that was easy. – Latheesan Aug 15 '18 at 15:42
  • Actually ignore the last part of my previous comment. I can't figure out is how to retrieve this value using `getValue()` method on the result object. `result.getValue('contact.firstname')` returns null, but if i return the whole result object, I can see the field/value there. – Latheesan Aug 15 '18 at 15:53
  • Actually never-mind again, after some more tinkering around; found the answer: `result.getValue({ name: 'firstname', join: 'contact' });` I needed this to retrieve eager loaded relational data value. – Latheesan Aug 15 '18 at 15:57