Cross Instance Script Configuration - Part 2

In part 2 of Cross Instance Script Configuration, we are going to dive into the implementation.  Our design criteria centers on the following objectives.

  1. Create a module that can determine the instance in which it is running.  And, also allow access to any instance configuration.
  2. Ensure all instances contain the same configuration settings.
We are going to implement this as a JavaScript Class.

In order to accomplish this, we will use the N/url module to allow us access to the running instance host name. 

We will start off by creating a new module that will hold our class.  The constructor will accept one optional parameter.  If this parameter is passed, the values returned will be the values from the matching environment.  If passed, and the value is not found, and exception will be thrown.  If the parameter is not passed, the current executing environment is used.

				
					    return class Config {
        'use strict';

        /**
         * Creates an instance of the Config class.
         * @param {string} overrideEnvironment - Name of the environment for which to get the config.  Null = Current Running Instance
         * @returns {object} instance of Config
         */
        constructor(overrideEnvironment = '') {
            let environmentOverride = overrideEnvironment.toLowerCase();
            let environment = '';
            this.departments = {
                SALES: '',
                FINANCE_AND_ACCOUNTING: ''
            };
            this.defaults = {
                DEFAULT_ENVIRONMENT: '',
                DEFAULT_SUBSIDIARY: '',
                DEFAULT_LOCATION: '',
                DEFAULT_DEPARTMENT: '',
                DEFAULT_CURRENCY: '',

                GL_ACCOUNTS: {
                    UNDEPOSITED_FUNDS: '',
                    AR_ACCOUNT: '',
                    SHORT_TERM_TAX_LIABILITY: '',
                    TAXES_SALES_USE_TAX: ''
                },
            };            
        }
    }
				
			

After the configuration properties are defined, we add the logic to set the environment property.  This property will hold the name of the environment for which to return the settings.

Keeping each environment section settings in the same order will make configuration updates much easier!

				
					    return class Config {
        'use strict';

        /**
         * Creates an instance of the Config class.
         * @param {string} overrideEnvironment - Name of the environment for which to get the config.  Null = Current Running Instance
         * @returns {object} instance of Config
         */
        constructor(overrideEnvironment = '') {
            let environmentOverride = overrideEnvironment.toLowerCase();
            let environment = '';
            this.departments = {
                SALES: '',
                FINANCE_AND_ACCOUNTING: ''
            };
            this.defaults = {
                DEFAULT_ENVIRONMENT: '',
                DEFAULT_SUBSIDIARY: '',
                DEFAULT_LOCATION: '',
                DEFAULT_DEPARTMENT: '',
                DEFAULT_CURRENCY: '',

                GL_ACCOUNTS: {
                    UNDEPOSITED_FUNDS: '',
                    AR_ACCOUNT: '',
                    SHORT_TERM_TAX_LIABILITY: '',
                    TAXES_SALES_USE_TAX: ''
                },
            };
            
            if (this.isNullOrWhitespace(environmentOverride)) {
                let host = url.resolveDomain({hostType: url.HostType.APPLICATION}).toLowerCase();

                if (this.startsWith(host, 'tstdrv00000')) {
                    environment = 'development';
                } else if (this.startsWith(host, 'tstdrv000001')) {
                    environment = 'dev1';
                } else if (this.contains(host, '1234567-sb1')) {
                    environment = 'staging';
                } else if (this.contains(host, '1234567-sb2')) {
                    environment = 'sb2';
                } else {
                    environment = 'production';
                }
            } else {
                environmentOverride = environmentOverride.toLowerCase();
                if (environmentOverride === 'development') {
                    environment = 'development';
                } else if (environmentOverride === 'dev1') {
                    environment = 'dev1';
                } else if (this.contains(environmentOverride, 'staging')) {
                    environment = 'staging';
                } else if (environmentOverride === 'sb2') {
                    environment = 'sb2';
                } else {
                    environment = 'production';
                }
            }
            
            // Add logic to return the config settings for the environment property
        }
    }
    
				
			

Below this we will add the logic to use the settings for the selected environment.

				
					        if (environment === 'development') {
            this.departments = {
                SALES: '33',
                FINANCE_AND_ACCOUNTING: '75'
            };        
            this.defaults = {
                DEFAULT_ENVIRONMENT: '1',
                DEFAULT_SUBSIDIARY: '1',
                DEFAULT_LOCATION: '1',
                DEFAULT_DEPARTMENT: '4',
                DEFAULT_CURRENCY: '1',

                GL_ACCOUNTS: {
                    UNDEPOSITED_FUNDS: '179',
                    AR_ACCOUNT: '14',
                    SHORT_TERM_TAX_LIABILITY: '54',
                    TAXES_SALES_USE_TAX: '77'
                },
            };
        } else if (environment === 'dev1') {
            this.departments = {
                SALES: '22',
                FINANCE_AND_ACCOUNTING: '352'
            };
            this.defaults = {
                DEFAULT_ENVIRONMENT: '1',
                DEFAULT_SUBSIDIARY: '1',
                DEFAULT_LOCATION: '1',
                DEFAULT_DEPARTMENT: '44',
                DEFAULT_CURRENCY: '1',

                GL_ACCOUNTS: {
                    UNDEPOSITED_FUNDS: '70',
                    AR_ACCOUNT: '155',
                    SHORT_TERM_TAX_LIABILITY: '54',
                    TAXES_SALES_USE_TAX: '76'
                },
            };        
        } else if (environment === 'staging') {
            this.departments = {
                SALES: '55',
                FINANCE_AND_ACCOUNTING: '683'
            };
            this.defaults = {
                DEFAULT_ENVIRONMENT: '1',
                DEFAULT_SUBSIDIARY: '1',
                DEFAULT_LOCATION: '1',
                DEFAULT_DEPARTMENT: '44',
                DEFAULT_CURRENCY: '1',

                GL_ACCOUNTS: {
                    UNDEPOSITED_FUNDS: '79',
                    AR_ACCOUNT: '145',
                    SHORT_TERM_TAX_LIABILITY: '254',
                    TAXES_SALES_USE_TAX: '7'
                },
            };        
        } else if (environment === 'sb2') {
            this.departments = {
                SALES: '55',
                FINANCE_AND_ACCOUNTING: '683'
            };        
            this.defaults = {
                DEFAULT_ENVIRONMENT: '',
                DEFAULT_SUBSIDIARY: '',
                DEFAULT_LOCATION: '',
                DEFAULT_DEPARTMENT: '',
                DEFAULT_CURRENCY: '',

                GL_ACCOUNTS: {
                    UNDEPOSITED_FUNDS: '',
                    AR_ACCOUNT: '',
                    SHORT_TERM_TAX_LIABILITY: '',
                    TAXES_SALES_USE_TAX: ''
                },
            };        
        } else if (environment === 'production') {
            this.departments = {
                SALES: '55',
                FINANCE_AND_ACCOUNTING: '683'
            };
            this.defaults = {
                DEFAULT_ENVIRONMENT: '1',
                DEFAULT_SUBSIDIARY: '1',
                DEFAULT_LOCATION: '1',
                DEFAULT_DEPARTMENT: '44',
                DEFAULT_CURRENCY: '1',

                GL_ACCOUNTS: {
                    UNDEPOSITED_FUNDS: '79',
                    AR_ACCOUNT: '145',
                    SHORT_TERM_TAX_LIABILITY: '254',
                    TAXES_SALES_USE_TAX: '7'
                },
            };        
        } else {
            throw new Error(`Environment ${environment} was not found.`);
        }
        

				
			

Properties can hold any JavaScript objects.  Even Maps!

				
					                this.defaults.DEFAULT_CURRENCY_LIST = new Map([
                    ['1', { INTERNAL_ID: '1', ISO_CODE: 'USD', NAME: 'USA', SYMBOL: '$' }],
                    ['2', { INTERNAL_ID: '2', ISO_CODE: 'GBP', NAME: 'British pound', SYMBOL: '£' }],
                    ['3', { INTERNAL_ID: '3', ISO_CODE: 'CAD', NAME: 'Canadian Dollar', SYMBOL: '$' }],
                    ['4', { INTERNAL_ID: '4', ISO_CODE: 'EUR', NAME: 'Euro', SYMBOL: '€' }],
                    ['USD', { INTERNAL_ID: '1', ISO_CODE: 'USD', NAME: 'USA', SYMBOL: '$' }],
                    ['GBP', { INTERNAL_ID: '2', ISO_CODE: 'GBP', NAME: 'British pound', SYMBOL: '£' }],
                    ['CAD', { INTERNAL_ID: '3', ISO_CODE: 'CAD', NAME: 'Canadian Dollar', SYMBOL: '$' }],
                    ['EUR', { INTERNAL_ID: '4', ISO_CODE: 'EUR', NAME: 'Euro', SYMBOL: '€' }]
                ]);
				
			

I hope this article will help you in managing multiple Netsuite instances.  Let me know what you think!

Leave a Reply

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