Marty Zigman Marty Zigman
Prolecto Labs Accelerator Templates

Best Practice: NetSuite Lead Imports and Campaign Responses

CRM NetSuite Technical

Tags: , , ,

This article is relevant if you are seeking a best practice for NetSuite for lead generation.

Background

NetSuite has good tools for marketing automation and lead generation.  However, like many things in NetSuite, if you are willing to invent a bit, you can make business practices and CRM management much better.

In most organizations, leads are obtained from many sources.   Examples may be from a web site contact form, to trade show leads,  and purchased leads.  The nature of lead management means that you may have minimal information on the individual who my be interested in your products and services.  Often it may be a name, email address and the source of where this was obtained.

In all CRM activities, duplicate records are to be avoided as it will create noise, increase your costs, and lower your ability to make good assessments of your campaign work effectiveness.  NetSuite’s lead management tools help you avoid duplicates by offering warnings include tools to help de-duplicate.  Yet, even with these tools, duplicates are common especially when there are multiple sources for obtaining leads.

A Better NetSuite Lead Import Practice

NetSuite’s CRM offers a campaign capacity.  While we can get sophisticated with campaign management, for this discussion, we will keep it simple.  NetSuite offers simple out of the box campaigns.  A new lead, via its source, can be associated with a NetSuite campaign.  Each campaign has an associated “[Default Event]”.  The default event will be used to hold information about a “response” which tells a marketing manager that there has been interaction with the organization.

The best practice is to add a lead to the system during the very first interaction.  Subsequent interactions represent responses to various offers for products and services conversation.  The best practice is to track subsequent communications as responses to campaign efforts.  This will allow marketers to understand behavior and better tailor their communications.  That said, the challenge is that a subsequent response may come in the form of another lead record to import due to the way third party systems or marketing and sales practices are organized.

Use a Custom Lead Import Table with a Custom Mass Update

Instead of importing leads directly into NetSuite lead table, instead, create a custom CSV lead import table that will pose no threat to duplicate records in the environment.  See image for an overview.  From there, use a custom mass update to read each imported record and decide if a new NetSuite lead record should be created or a campaign response should be added.  Once this practice is stabilized, it can be hooked up for real time updates against inbound customer contact forms or other integrated systems.

Sample SuiteScript Lead Import and Campaign Response Pattern

The following SuiteScript code pattern  illustrates the logic offered in the diagram above.  For other SuiteScript developers, enjoy the code pattern for adding a NetSuite address record and a campaign response.

var CONST_NEW_LEAD_STATUS 	= 19;	// Lead - Show

//------------------------------------------------------------------
//Function: 		MassUpdate_LIR (Lead Import Record)
//Record: 		MKTG - Lead Import Record : customrecord_cust_lir
//Script Type: 		Mass Update
//Description:  	When a lead import record is created, immediately lookup customer 
//			and add campaign response or add a new lead if not found
//Date:			20150301
//------------------------------------------------------------------

function MassUpdate_LIR(rectype, recid) {

	var record = nlapiLoadRecord(rectype, recid);
	
	//noempty custom function returns a default value if there is no data in the first parameter
	var custrecord_lir_customer = noempty(record.getFieldValue("custrecord_lir_customer"), '');
	var custrecord_lir_campaign = noempty(record.getFieldValue("custrecord_lir_campaign"), '');
	var custrecord_lir_companyname	= noempty(record.getFieldValue("custrecord_lir_companyname"), '');
	var custrecord_lir_firstname = noempty(record.getFieldValue("custrecord_lir_firstname"), '');
	var custrecord_lir_lastname = noempty(record.getFieldValue("custrecord_lir_lastname"), '');
	var custrecord_lir_title = noempty(record.getFieldValue("custrecord_lir_title"), '');
	var custrecord_lir_email = noempty(record.getFieldValue("custrecord_lir_email"), '');
	var custrecord_lir_phone = noempty(record.getFieldValue("custrecord_lir_phone"), '');
	var custrecord_lir_addr1 = noempty(record.getFieldValue("custrecord_lir_addr1"), '');
	var custrecord_lir_addr2 = noempty(record.getFieldValue("custrecord_lir_addr2"), '');
	var custrecord_lir_city	 = noempty(record.getFieldValue("custrecord_lir_city"), '');
	var custrecord_lir_state = noempty(record.getFieldValue("custrecord_lir_state"), '');
	var custrecord_lir_zipcode = noempty(record.getFieldValue("custrecord_lir_zipcode"), '');
	var custrecord_lir_country = noempty(record.getFieldValue("custrecord_lir_country"), '');
	
	if (custrecord_lir_customer.length > 0){
		nlapiLogExecution('ERROR', 'customer record already exists for this lead record');
		return;
	}
	
	// does this customer already exist?
	//custom lookup_customer function uses the email address as the key;
	var customer_id = lookup_customer(custrecord_lir_email); 
	nlapiLogExecution('DEBUG', 'customer_id', customer_id);
	
	// add lead or response
	if (customer_id == 0){
		nlapiLogExecution('DEBUG', 'creating new lead...');
		
		// add lead
		var full_name = (custrecord_lir_firstname + " " + custrecord_lir_lastname).trim();
		// create the record 
		NS_record = nlapiCreateRecord('lead', {recordmode: 'dynamic'});
		NS_record.setFieldValue('entitystatus', CONST_NEW_LEAD_STATUS);
		NS_record.setFieldValue('isperson', 'T');
		NS_record.setFieldValue('companyname', custrecord_lir_companyname);
		NS_record.setFieldValue('firstname', custrecord_lir_firstname);
		NS_record.setFieldValue('lastname', custrecord_lir_lastname);
		NS_record.setFieldValue('title', custrecord_lir_title);
		NS_record.setFieldValue('email', custrecord_lir_email);
		NS_record.setFieldValue('phone', custrecord_lir_phone);
		
		
		nlapiLogExecution('DEBUG', custrecord_lir_companyname, custrecord_lir_firstname + '|'
			+ custrecord_lir_lastname + '|' + custrecord_lir_title);
		
		NS_record.setFieldValue('leadsource', custrecord_lir_campaign);
		
		//Add first line to sublist   
		NS_record.selectNewLineItem('addressbook');
		NS_record.setCurrentLineItemValue('addressbook', 'defaultshipping', 'T');  //This field is not a subrecord field.
		NS_record.setCurrentLineItemValue('addressbook', 'defaultbilling', 'T');   //This field is not a subrecord field.
		NS_record.setCurrentLineItemValue('addressbook', 'label', custrecord_lir_addr1);  //This field is not a subrecord field.

	    //create address subrecord
	    var subrecord = NS_record.createCurrentLineItemSubrecord('addressbook', 'addressbookaddress');
	    
	    //set subrecord fields
	    subrecord.setFieldText('country', custrecord_lir_country); //Country must be set before setting the other address fields
	    subrecord.setFieldValue('attention', noempty(full_name,''));
	    subrecord.setFieldValue('addressee', custrecord_lir_companyname);
	    subrecord.setFieldValue('addrphone', custrecord_lir_phone);
	    subrecord.setFieldValue('addr1', custrecord_lir_addr1);
	    subrecord.setFieldValue('addr2', custrecord_lir_addr2);
	    subrecord.setFieldValue('city', custrecord_lir_city);
	    subrecord.setFieldValue('state', custrecord_lir_state);
	    subrecord.setFieldValue('zip', custrecord_lir_zipcode);

	    //commit subrecord and line item
	    subrecord.commit();
	    NS_record.commitLineItem('addressbook');
		
	    nlapiLogExecution('DEBUG', 'create lead ' + custrecord_lir_companyname);
	    var cus_id = nlapiSubmitRecord(NS_record, false, true);
	    nlapiLogExecution('AUDIT', 'created lead ' + custrecord_lir_companyname, cus_id);
	    
	    // add the new customer id to the lead record
	    record.setFieldValue('custrecord_lir_customer', cus_id);
	    nlapiSubmitRecord(record, false, true);

	} else {
	    nlapiLogExecution('DEBUG', 'Adding campaign response for', customer_id);
		
	    // add campaign response
	    var new_rec = nlapiCreateRecord('campaignresponse');
	    new_rec.setFieldValue('entity', customer_id);
	    new_rec.setFieldValue('leadsource', custrecord_lir_campaign);
	    new_rec.setFieldText('campaignevent', '[Default Event]');
	    new_rec.setFieldValue('newresponsedate', nlapiDateToString(new Date(), 'date'));
	    new_rec.setFieldText('response', 'Responded');
	    nlapiSubmitRecord(new_rec);	
		
	    // add the customer id to the lead record
	    record.setFieldValue('custrecord_lir_customer', customer_id);
	    var resp_id = nlapiSubmitRecord(record);
	    nlapiLogExecution('AUDIT', 'Response id', resp_id);
	}
}

Improve your NetSuite Business Practices

My team and I have been working for over 25 years in various ERP and CRM systems, what comes forth in the NetSuite system is the power of the platform.  NetSuite offer so many features yet it allows us to invent solutions to specific client challenges.  If you have a specific NetSuite area you want to enhance, let’s have a conversation.

Marty Zigman

Holding all three official certifications, Marty is regarded as the top NetSuite expert and leads a team of senior professionals at Prolecto Resources, Inc. He is a former Deloitte & Touche CPA and has held CTO roles. For over 30 years, Marty has produced leadership in ERP, CRM and eCommerce business systems. Contact Marty to set up a conversation.

More Posts - Website - Twitter - Facebook - LinkedIn - YouTube

About Marty Zigman

Marty Zigman

Holding all three official certifications, Marty is regarded as the top NetSuite expert and leads a team of senior professionals at Prolecto Resources, Inc. He is a former Deloitte & Touche CPA and has held CTO roles. For over 30 years, Marty has produced leadership in ERP, CRM and eCommerce business systems. Contact Marty to set up a conversation.

Biography • Website • X (Twitter) • Facebook • LinkedIn • YouTube

4 thoughts on “Best Practice: NetSuite Lead Imports and Campaign Responses

  1. CARLO says:

    Dear Martin i used part of your code to integrate outside marketing campaing in netsuite. Anyhow i cannot find the field ‘newresponsedate’ and i cannot set date i want eg new_rec.setFieldValue(‘newresponsedate’,’20xx/xx/xx’);

    doesnt seem not to affect the field that looks always autocompiled with now

  2. Marty Zigman says:

    Looking at the SuiteScript record browser, the field value is “responsedate”. Also, be sure to use NetSuite Date Functions to set the value as using strings or standard JavaScript date objects can be problematic.

  3. Michelle Beutler says:

    Is there a reason you do this as a mass update rather than a map/reduce? Thanks!

  4. Marty Zigman says:

    Michelle,

    At the time of this article, 2015, we did not have map/reduce as a capacity in the platform.

    Marty

Leave a Reply

Your email address will not be published. Required fields are marked *