Home » Deeper in to NetSuite » How to Achieve Entity Relationship in NetSuite?

How to Achieve Entity Relationship in NetSuite?

NetSuite allows a single entity record, as witnessed by its internalid, to be more than one of these specific types.  

It suggests that an entity is holding more than one role in transactional constructs.  This frequently comes up in many business models.  For instance in any business that has a Trade-In Business Model where a customer can first sell an item to that business and then behalf of that sold amount could buy other item from the same business.

When we have a single entity referencing transactions of different types (such as both revenue and costs), our reporting becomes more powerful.

Entity Relationship in NetSuite Form User Interface?

Navigate to any Entity Record I.e. Customer/Vendor

In the provided screenshot, it is evident that the selected Entity Record has two assigned roles: Vendor and Contact. If there is a need to assign additional roles, you can use the plus (+) icon. Upon clicking the plus icon, a modal window titled “Other Relationships” will appear.

For example, if you wish to add an extra role, such as “Partner,” for the selected entity, you can simply select “Partner” from the options in the modal window and click save. Upon returning to the entity record and inspecting its relationships, you will find that the Partner relationship has been successfully added, as illustrated in the referenced screenshot.

From Client Script:
Basically when we create the relationship on Any Entity it doesn’t make changes/update anything in existing record but make request to Another URL in order to create a Relationship. 

For Instance,

/app/common/entity/company.nl?e=T&fromtype=vendor&target=s_relation:otherrelationships&label=Other+Relationships&id=280528&toType=customer

In above URL, relationship of customer is being added over vendor entity

However, form backend there was some limitations
Above URL Was accessible with client script but was not accessible from Backend scripts. 

From Backend Script:

We Learned about another Way,
Navigate to , List -> Mass Update -> Saved Mass Update

and Set Filter on Entities with Contact

After clicking the “Submit Selected” button at the top-right, it will initiate a task in the backend to add a duplicate relationship on the primary entity and subsequently delete that duplicated relationship.

We have incorporated this approach into our backend script to achieve entity relationships.

For example, if you wish to create an entity record with both roles, such as Customer and Vendor, from background scripts, you need to first create separate Customer and Vendor records with identical details.

From the records created above, you must specify which record will be the Master record. The Master Record will have a relationship added to the other record, and the other one will be deleted during the duplicate merge operation.

In the `linkEntitiesToEachOther` method, we perform the merge of duplicates and create a relationship by triggering a task based on given parameters. This method eventually returns the ID of the task that was just triggered for the purpose of entity relationship and runs in the background.

I pass the task ID to this method and introduce a delay until the relationship is created because I want to ensure that subsequent actions are performed only after the relationship is established.

addSynchronousDelayUnlessRelationshipTaskCreates

I’ve added the snippets that’ll help you understand the definition of function.

const nsVendorInternalId = this.upsertEntity(record.Type.VENDOR, entityObj);
        const nsCustomerInternalId = this.upsertEntity(record.Type.CUSTOMER, entityObj, entitySearchObj.entityInternalId);
        const entityLinkTaskId = this.linkEntitiesToEachOther('customer', nsVendorInternalId, nsCustomerInternalId);
        this.addSynchronousDelayUnlessRelationshipTaskCompletes(entityLinkTaskId);



/**
   * 
   * @param {string} masterEntity
   * @param {integer} nsVendorId
   * @param {integer} nsCustomerId
   */
  linkEntitiesToEachOther(masterEntity, nsVendorId, nsCustomerId) {
    const LOG_TITLE = `${LOG_FILE} => linkEntitiesToEachOther`;
    try {
      const entityLinkTask = task.create({taskType: task.TaskType.ENTITY_DEDUPLICATION});
      entityLinkTask.entityType = (masterEntity == 'vendor') 
      ? task.DedupeEntityType.CUSTOMER
      : task.DedupeEntityType.VENDOR;

      entityLinkTask.dedupeMode = task.DedupeMode.MERGE;
      entityLinkTask.masterSelectionMode = task.MasterSelectionMode.SELECT_BY_ID;
      entityLinkTask.masterRecordId = (masterEntity == 'vendor') ? nsVendorId : nsCustomerId
      entityLinkTask.recordIds = (masterEntity == 'vendor') ? [nsCustomerId] : [nsVendorId];
      const entityLinkTaskId = entityLinkTask.submit();
      return entityLinkTaskId;
    } catch (error) {
      log.error(`ERROR: ${LOG_TITLE}`, error);
      throw error;
    }
  },


  /**
   * 
   * @param {*} taskId 
   */
  addSynchronousDelayUnlessRelationshipTaskCompletes(taskId) {
    const taskStatus = task.checkStatus({taskId});
    // add 3 seconds delay syncronouly unless task status completes
    while(taskStatus.status != task.TaskStatus.COMPLETE) {
      const milliseconds = 2000;
      const date = new Date();
      date.setMilliseconds(date.getMilliseconds() + milliseconds);
      while(new Date() < date){}
    }

    log.debug('linkEntitiesToEach Task Completed', 'Task Completed');
    log.debug('taskStatus.status', taskStatus.status);
  },

About the Author

About the Author

Ubaid Raza
Senior Software Engineer - Folio3

Ubaid Raza is an experience NetSuite Developer, Who loves coding, solving problems and learning new technologies apart from that enjoy watching sports and exploring new places and cultures

Get In Touch With Our Experts


    NetSuite allows a single entity record, as witnessed by its internalid, to be more than one of these specific types.  

    It suggests that an entity is holding more than one role in transactional constructs.  This frequently comes up in many business models.  For instance in any business that has a Trade-In Business Model where a customer can first sell an item to that business and then behalf of that sold amount could buy other item from the same business.

    When we have a single entity referencing transactions of different types (such as both revenue and costs), our reporting becomes more powerful.

    Entity Relationship in NetSuite Form User Interface?

    Navigate to any Entity Record I.e. Customer/Vendor

    In the provided screenshot, it is evident that the selected Entity Record has two assigned roles: Vendor and Contact. If there is a need to assign additional roles, you can use the plus (+) icon. Upon clicking the plus icon, a modal window titled “Other Relationships” will appear.

    For example, if you wish to add an extra role, such as “Partner,” for the selected entity, you can simply select “Partner” from the options in the modal window and click save. Upon returning to the entity record and inspecting its relationships, you will find that the Partner relationship has been successfully added, as illustrated in the referenced screenshot.

    From Client Script:
    Basically when we create the relationship on Any Entity it doesn’t make changes/update anything in existing record but make request to Another URL in order to create a Relationship. 

    For Instance,

    /app/common/entity/company.nl?e=T&fromtype=vendor&target=s_relation:otherrelationships&label=Other+Relationships&id=280528&toType=customer

    In above URL, relationship of customer is being added over vendor entity

    However, form backend there was some limitations
    Above URL Was accessible with client script but was not accessible from Backend scripts. 

    From Backend Script:

    We Learned about another Way,
    Navigate to , List -> Mass Update -> Saved Mass Update

    and Set Filter on Entities with Contact

    After clicking the “Submit Selected” button at the top-right, it will initiate a task in the backend to add a duplicate relationship on the primary entity and subsequently delete that duplicated relationship.

    We have incorporated this approach into our backend script to achieve entity relationships.

    For example, if you wish to create an entity record with both roles, such as Customer and Vendor, from background scripts, you need to first create separate Customer and Vendor records with identical details.

    From the records created above, you must specify which record will be the Master record. The Master Record will have a relationship added to the other record, and the other one will be deleted during the duplicate merge operation.

    In the `linkEntitiesToEachOther` method, we perform the merge of duplicates and create a relationship by triggering a task based on given parameters. This method eventually returns the ID of the task that was just triggered for the purpose of entity relationship and runs in the background.

    I pass the task ID to this method and introduce a delay until the relationship is created because I want to ensure that subsequent actions are performed only after the relationship is established.

    addSynchronousDelayUnlessRelationshipTaskCreates

    I’ve added the snippets that’ll help you understand the definition of function.

    const nsVendorInternalId = this.upsertEntity(record.Type.VENDOR, entityObj);
            const nsCustomerInternalId = this.upsertEntity(record.Type.CUSTOMER, entityObj, entitySearchObj.entityInternalId);
            const entityLinkTaskId = this.linkEntitiesToEachOther('customer', nsVendorInternalId, nsCustomerInternalId);
            this.addSynchronousDelayUnlessRelationshipTaskCompletes(entityLinkTaskId);
    
    
    
    /**
       * 
       * @param {string} masterEntity
       * @param {integer} nsVendorId
       * @param {integer} nsCustomerId
       */
      linkEntitiesToEachOther(masterEntity, nsVendorId, nsCustomerId) {
        const LOG_TITLE = `${LOG_FILE} => linkEntitiesToEachOther`;
        try {
          const entityLinkTask = task.create({taskType: task.TaskType.ENTITY_DEDUPLICATION});
          entityLinkTask.entityType = (masterEntity == 'vendor') 
          ? task.DedupeEntityType.CUSTOMER
          : task.DedupeEntityType.VENDOR;
    
          entityLinkTask.dedupeMode = task.DedupeMode.MERGE;
          entityLinkTask.masterSelectionMode = task.MasterSelectionMode.SELECT_BY_ID;
          entityLinkTask.masterRecordId = (masterEntity == 'vendor') ? nsVendorId : nsCustomerId
          entityLinkTask.recordIds = (masterEntity == 'vendor') ? [nsCustomerId] : [nsVendorId];
          const entityLinkTaskId = entityLinkTask.submit();
          return entityLinkTaskId;
        } catch (error) {
          log.error(`ERROR: ${LOG_TITLE}`, error);
          throw error;
        }
      },
    
    
      /**
       * 
       * @param {*} taskId 
       */
      addSynchronousDelayUnlessRelationshipTaskCompletes(taskId) {
        const taskStatus = task.checkStatus({taskId});
        // add 3 seconds delay syncronouly unless task status completes
        while(taskStatus.status != task.TaskStatus.COMPLETE) {
          const milliseconds = 2000;
          const date = new Date();
          date.setMilliseconds(date.getMilliseconds() + milliseconds);
          while(new Date() < date){}
        }
    
        log.debug('linkEntitiesToEach Task Completed', 'Task Completed');
        log.debug('taskStatus.status', taskStatus.status);
      },
    

    About the Author

    About the Author

    Ubaid Raza
    Senior Software Engineer - Folio3

    Ubaid Raza is an experience NetSuite Developer, Who loves coding, solving problems and learning new technologies apart from that enjoy watching sports and exploring new places and cultures

    Get In Touch With Our Experts

      I have read and agree to the Privacy Policy of Folio3
      I agree to be contacted by Phone or Email by Folio3

      Get in touch with the

      Award-Winning

      End-to-end NetSuite Servicing Agency

      Tell us how may we assist you!