Name

global.generateCodeForTreePath

Description

No description available

Script

var generateCodeForTreePath = Class.create();
generateCodeForTreePath.prototype = {
  initialize: function() {
  	this.AVAILABLE_CHARACTERS = "!#$&()*+,-.0123456789:;<?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]`}|{~";
  		this.AVAILABLE_CHARACTERS_LENGTH = this.AVAILABLE_CHARACTERS.length;
  		this.SYSTEM_PROPERTY_NAME = 'com.snc.cs_base.last.generated.code.tree.path';
  	},
  	
  	generateCode: function(code) {
  		var mutexName = 'sn_customerservice_generateaccountcode_lock';
  		var mutex = new GlideMutex(mutexName, mutexName);
  		mutex.setSpinWait(100);
  		mutex.setMaxSpins(1000);
  		var newCode;
  		if (mutex.get()) {
  			try{
  				newCode = this._generateCodeHelper();
  			}
  			finally {
  				mutex.release();
  			}
  		}
  		return newCode;
  		
  	},
  	_generateCodeHelper: function (code) {
  		var existingCode = code || this.getLastUsedCode();
  		var fI1 = 0;
  		var fI2 = 0;
  		var fI3 = 0;
  		var fI4 = -1;
  		var newCode;
  		
  		if(existingCode) {
  			fI1 = this.AVAILABLE_CHARACTERS.indexOf(existingCode[0]);
  			fI2 = this.AVAILABLE_CHARACTERS.indexOf(existingCode[1]);
  			fI3 = this.AVAILABLE_CHARACTERS.indexOf(existingCode[2]);
  			fI4 = this.AVAILABLE_CHARACTERS.indexOf(existingCode[3]);
  		}
  		
  		
  		if (fI4 < this.AVAILABLE_CHARACTERS_LENGTH - 1) {
  			fI4++;
  		} else {
  			fI4 = 0;
  			if (fI3 < this.AVAILABLE_CHARACTERS_LENGTH - 1) {
  				fI3++;
  			} else {
  				fI3 = 0;
  				if (fI2 < this.AVAILABLE_CHARACTERS_LENGTH - 1) {
  					fI2++;
  				} else {
  					fI2 = 0;
  					if (fI1 < this.AVAILABLE_CHARACTERS_LENGTH - 1) {
  						fI1++;
  					} else {
  						//reset
  						fI1 = 0;
  						fI2 = 0;
  						fI3 = 0;
  						fI4 = 0;
  					}
  				}
  			}
  		}
  		newCode = this.AVAILABLE_CHARACTERS.charAt(fI1)+this.AVAILABLE_CHARACTERS.charAt(fI2)+this.AVAILABLE_CHARACTERS.charAt(fI3)+this.AVAILABLE_CHARACTERS.charAt(fI4);
  		this.setLastUsedCode(newCode);
  		return newCode.toString();
  	},
  	
  	getLastUsedCode: function(code) {
  		//why not use gs.setProperty/getProperty?
  		var value = '';
  		var gr = new GlideRecord("sys_properties");
  		gr.addQuery("name", this.SYSTEM_PROPERTY_NAME);
  		gr.query();
  		if (!gr.next()) {
  			//if property NOT found get the code from last created account record
  			var acc = new GlideRecord("customer_account");
  			acc.setLimit(1);
  			acc.orderByDesc("sys_created_on");
  			acc.query();
  			if(acc.next())
  				value = acc.getValue("account_code");
  		} else {
  			value = gr.getValue("value");
  		}
  		return value;
  	},
  	
  	setLastUsedCode: function(code) {
  		var gr = new GlideRecord("sys_properties");
  		gr.addQuery("name", this.SYSTEM_PROPERTY_NAME);
  		gr.query();
  		if (gr.next()) {
  			gr.setValue("value", code);
  			gr.setWorkflow(false);
  			gr.update();
  		} else {
  			//create property with same sys_id
  			gr.initialize();
  			gr.setNewGuidValue("897fdf73c3311200e94a9f2974d3aeda");
  			gr.suffix = this.SYSTEM_PROPERTY_NAME;
  			gr.name = this.SYSTEM_PROPERTY_NAME;
  			gr.description = 'Code used to generate next account code';
  			gr.type = 'string';
  			gr.value = code;
  			gr.write_roles = 'sn_customerservice_manager';
  			gr.read_roles = 'sn_customerservice_manager';
  			gr.setWorkflow(false);
  			gr.insert();
  		}
  	},
  	
  	updateAccountPath: function(id) {
  		gs.info("Update account path called for : " + id);
  		var account = this.getAccount(id);
  		if (!account.isValid())
  			return;
  		
  		gs.info("Update account path called for : " + account.name);
  		var code = this.generateCode();
  		var path = code;
  		account.account_code = code;
  		if(!gs.nil(account.account_parent)) {
  			var  acctParent = this.getAccount(account.getValue('account_parent'));
  			if (!gs.nil(acctParent.getValue('account_path')))
  				path = acctParent.getValue('account_path') + "/" + code;
  		}
  		account.account_path = path;
  		gs.info("New Code and Path  : " + account.getDisplayValue() +" , is : " +  code + " / " + path);
  		account.update();
  		
  		//update child paths
  		code = this.updateChildPath(account.sys_id, code, path);
  		gs.info("Update property with latest code : " + code);
  		if (!gs.nil(code))
  			this.setLastUsedCode(code);
  		
  		return code;
  	},
  	
  	updateChildPath: function(parent_id, parent_code, parent_path) {
  		gs.info("UpdateChildPath called with parent : " + parent_id +" / " + parent_code +" / " + parent_path);
  		var code = parent_code;
  		var path = null;
  		var gr = new GlideRecord("customer_account");
  		gr.addQuery("account_parent", parent_id);
  		gr.orderBy('sys_created_on');
  		gr.query();
  		while(gr.next()) {
  			gs.info("Update account path called for : " + gr.getDisplayValue());
  			code = this.generateCode(code);
  			path = code;
  			if (!gs.nil(parent_path))
  				path = parent_path + '/' + code;
  			gr.account_code = code;
  			gr.account_path = path;
  			gr.update();
  			
  			gs.info("New Code and Path : " + gr.getDisplayValue() +" , is : " +  code +" / " + path);
  			code = this.updateChildPath(gr.sys_id, code, path);
  		}
  		return code;
  	},
  	
  	getAccount: function(id) {
  		var gr = new GlideRecord('customer_account');
  		gr.get(id);
  		return gr;
  	},
  	
  	type: 'generateCodeForTreePath'
  };

Sys ID

1947b353eb3302003e97afcef106fe8b

Offical Documentation

Official Docs: