Skip to main content

Notifications

Customer experience | Sales, Customer Insights,...
Suggested answer

How to trigger a workflow without saving

Posted on by 55

Hi, 

I want some fields to be auto-populated when I insert a value in another field. My situation: when I create an incident in Customer Service and insert the Account i the lookup field, I want other 2 fields to be populated with values coming from the same fields but in Account entity. In order to do that, I created a workflow that, when I create an incident and insert the account field, it updates the incident with other 2 fields with the value taken from the same 2 fields in Account. This is working but only if I save the incident record, but I would like to get this working without the need to save (before saving). Is there a way to do that?

Thank you!

  • pietro.sacchi Profile Picture
    pietro.sacchi 25 on at
    RE: How to trigger a workflow without saving

    This is my final script:

    function setAssetsInfo(context){
    	//config
    
        var EntLogicalNameKey = "just_matricola";    //campo chiave per interrogare entità padre 
    
    
        //campi da settare nell'entità corrente
        var  entField1LogicalName = "customerid";
        var  entField2LogicalName = "productid";
        var  entField3LogicalName = "just_utentefinale_caso";
    
    
    
    	var parentEntityName = "msdyn_customerasset";  //Entità parent da interrogare
            var parentEntityLogicalNameKey="msdyn_customerassetid" //unique identifier entità padre
    	var parentEntFields = "_msdyn_account_value,_msdyn_product_value,_just_utentefinale_value";
    	
    	var formContext = context.getFormContext();
    	var parentId = formContext.getAttribute(EntLogicalNameKey).getValue();
    	if(!parentId)
    		return;
    	parentId = parentId[0].id.replace(/[{|}]/g,"");
    
    	var query =`?$select=${parentEntFields}&$filter=${parentEntityLogicalNameKey} eq ${parentId}`; // 
    	Xrm.WebApi.retrieveMultipleRecords(parentEntityName,query).then(
            function(result){
                var fields = parentEntFields.split(",");
    
    // DEFINIZIONE DEI CAMPI IN LETTURA SU ENTITA PADRE
                var res1 = formattValues(result,fields[0],true);
                var res2 = formattValues(result,fields[1],true);
                var res3 = formattValues(result,fields[2],true);
    //aggiungere un numero di righe che equivale ai campi da tirare su. mettere true se trattasi di lookup.altrimenti mettere false NB: vengono presi sequenzialmente i campi della variabile parentEntFields 
    //FINE LETTURA ENTITA PADRE
     debugger;
    //SCRITTURA ENTITA CORRENTE
    
                setField(formContext.getAttribute(entField1LogicalName),res1);  // aggiungere sequenzialmente i campi da popolare
                setField(formContext.getAttribute(entField2LogicalName),res2);
                setField(formContext.getAttribute(entField3LogicalName),res3);
     
    //FINE SCRITTURA ENITITA CORRENTE
            },
            function(err){
                console.log(err);
            }
        );
    }
     
    function formattValues(result,fieldLogicalName,isLookUp = false){
    	var value = result.entities[0] || null;
    	if(value){
    		if(!isLookUp)	
    			value = value[fieldLogicalName];
    		else
    			value = setLookUp(value,fieldLogicalName)
    	}	
    	return value;
    }
    function setLookUp(objectResponse,fieldLogicalName){
    	var lookupValue = [];
    	var value = {};
    	value.id = objectResponse[fieldLogicalName]; 
    	value.name = objectResponse[fieldLogicalName "@OData.Community.Display.V1.FormattedValue"];
    	value.entityType = objectResponse[fieldLogicalName "@Microsoft.Dynamics.CRM.lookuplogicalname"];
    	if(value.id != null && value.entityType != undefined ) // i managed the null value here
    	{
    	lookupValue.push(value);
    	return lookupValue;
    	}
    	
    }
    
    function setField(control,value){
    	if(control)
    		control.setValue(value);
    	
    }

  • PabloCRP Profile Picture
    PabloCRP 1,086 on at
    RE: How to trigger a workflow without saving

    Hi, we could validate that edge case with

    //...
    
    var fields = parentEntFields.split(",");
    setLookUpFieldHelper(result,fields[0],entField1LogicalName);
    setLookUpFieldHelper(result,fields[1],entField2LogicalName);
    setLookUpFieldHelper(result,fields[2],entField3LogicalName);
    //....
    //...
    
    //place this function after setField function
    
    function setLookUpFieldHelper(result,fieldNameQuery,targetField){
        if(result[fieldNameQuery]){
            var res = formattValues(result,fieldNameQuery,true);
            setField(formContext.getAttribute(targetField),res);
        }
    }

    regards

  • pietro.sacchi Profile Picture
    pietro.sacchi 25 on at
    RE: How to trigger a workflow without saving

    :(

  • pietro.sacchi Profile Picture
    pietro.sacchi 25 on at
    RE: How to trigger a workflow without saving

    I have only one problem: this script works only if all 3 parent fields  (_just_utentefinale_value,_msdyn_account_value,_msdyn_product_value) are populated.  if one of these are null , the script doesn't start...

  • pietro.sacchi Profile Picture
    pietro.sacchi 25 on at
    RE: How to trigger a workflow without saving

    hi pablo,  i modified the script again and now works flawlessly ,

    My "parent" entity was customer assets (msdyn_customerasset) 

     

    function setAssetsInfo(context){
    	//config
    
        var EntLogicalNameKey = "just_matricola";    //campo chiave per interrogare entità padre 
    
    
        var  entField1LogicalName = "just_utentefinale_caso";    //campi da settare nell'entità corrente
        var  entField2LogicalName = "customerid";
        var  entField3LogicalName = "productid";
    
    
    
    	var parentEntityName = "msdyn_customerasset";  //Entità parent da interrogare
            var parentEntityLogicalNameKey="msdyn_customerassetid" //unique identifier entità padre
    	var parentEntFields = "_just_utentefinale_value,_msdyn_account_value,_msdyn_product_value"; //elenco di campi da recuperare . se lookup aggiungere trattino e value in fondo
    
    	
    	
    	var formContext = context.getFormContext();
    	var parentId = formContext.getAttribute(EntLogicalNameKey).getValue();
    	if(!parentId)
    		return;
    	parentId = parentId[0].id.replace(/[{|}]/g,"");
    
    	var query =`?$select=${parentEntFields}&$filter=${parentEntityLogicalNameKey} eq ${parentId}`; // use string literas `` 
    	Xrm.WebApi.retrieveMultipleRecords(parentEntityName,query).then(
            function(result){
                var fields = parentEntFields.split(",");
                var res1 = formattValues(result,fields[0],true);
                var res2 = formattValues(result,fields[1],true);
                var res3 = formattValues(result,fields[2],true); //aggiungere un numero di righe che equivale ai campi da tirare su. mettere true se trattasi di lookup.altrimenti mettere false
                setField(formContext.getAttribute(entField1LogicalName),res1);  //aggiungere sequenzialmente i campi da popolare 
                setField(formContext.getAttribute(entField2LogicalName),res2);
                setField(formContext.getAttribute(entField3LogicalName),res3);
            },
            function(err){
                console.log(err);
            }
        );
    }
    
    function formattValues(result,fieldLogicalName,isLookUp = false){
    	var value = result.entities[0] || null;
    	if(value){
    		if(!isLookUp)	
    			value =  value[fieldLogicalName];
    		else
    			value = setLookUp(value,fieldLogicalName)
    	}	
    	return value;
    }
    function setLookUp(objectResponse,fieldLogicalName){
    	var lookupValue = [];
    	var value = {};
    	value.id = objectResponse[fieldLogicalName]; 
    	value.name = objectResponse[fieldLogicalName "@OData.Community.Display.V1.FormattedValue"];
    	value.entityType = objectResponse[fieldLogicalName "@Microsoft.Dynamics.CRM.lookuplogicalname"];
    	lookupValue.push(value);
    	return lookupValue;
    }
    
    function setField(control,value){
    	if(control)
    		control.setValue(value);
    	
    }

    thx again 

  • PabloCRP Profile Picture
    PabloCRP 1,086 on at
    RE: How to trigger a workflow without saving

    Hi, I did some changes to the code

    function setAssetsInfo(context){
    	//config
        var  entField1LogicalName = "just_utentefinale_caso";
        var  entField2LogicalName = "customerid";
        var  entField3LogicalName = "productid";
    	
    	var parentEntFields = "_just_utentefinale_value,_msdyn_account_value,_msdyn_product_value";//if this in account are lookups the write them like this
    	var EntLogicalNameKey = "just_matricola";
    	
    	var formContext = context.getFormContext();
    	var parentId = formContext.getAttribute(EntLogicalNameKey).getValue();
    	if(!parentId)
    		return;
    	parentId = parentId[0].id.replace(/[{|}]/g,"");
        var entityName = "account";
    	var query =`?$select=${parentEntFields}&$filter=accountid eq ${parentId}`; // use string literas `` instead of single quotes '.. if you are looking for an Account entity, should be accountid the key to lookup,shouldn't it?
    	Xrm.WebApi.retrieveMultipleRecords(entityName,query).then(
            function(result){
                var fields = parentEntFields.split(",");
                var res1 = formattValues(result,fields[0],true);
                var res2 = formattValues(result,fields[1],true);
                var res3 = formattValues(result,fields[2],true);
                setField(formContext.getAttribute(entField1LogicalName),res1);
                setField(formContext.getAttribute(entField2LogicalName),res2);
                setField(formContext.getAttribute(entField3LogicalName),res3);
            },
            function(err){
                console.log(err);
            }
        );
    }
    
    function formattValues(result,fieldLogicalName,isLookUp = false){
    	var value = result.entities[0] || null;
    	if(value){
    		if(!isLookUp)	
    			value =  value[fieldLogicalName];
    		else
    			value = setLookUp(value,fieldLogicalName)
    	}	
    	return value;
    }
    function setLookUp(objectResponse,fieldLogicalName){
    	var lookupValue = [];
    	var value = {};
    	value.id = objectResponse[fieldLogicalName]; 
    	value.name = objectResponse[fieldLogicalName "@OData.Community.Display.V1.FormattedValue"];
    	value.entityType = objectResponse[fieldLogicalName "@Microsoft.Dynamics.CRM.lookuplogicalname"];
    	lookupValue.push(value);
    	return lookupValue;
    }
    
    function setField(control,value){
    	if(control)
    		control.setValue(value);
    	
    }

    regards.

  • pietro.sacchi Profile Picture
    pietro.sacchi 25 on at
    RE: How to trigger a workflow without saving

    HI 

    i tried to run a modified version of script : 

    function setAssetsInfo(context){
    	//config
        var  entField1LogicalName = "just_utentefinale_caso";
        var  entField2LogicalName = "customerid";
        var  entField3LogicalName = "productid";
    	
    	var parentEntFields = "just_utentefinale,msdyn_account,msdyn_product"; //e.g accountfield1,accountfield2
    	var EntLogicalNameKey = "just_matricola"; //I'm assuming the Case Account the field is  'parentId'
    	
    	var formContext = context.getFormContext();
    	var parentId = formContext.getAttribute(EntLogicalNameKey).getValue();
    	if(!parentId)
    		return;
    	parentId = parentId[0].id.replace(/[{|}]/g,"");
    	var query = '?$select=${parentEntFields}&$filter=msdyn_customerassetid eq ${parentId}';
    	Xrm.WebApi.retrieveMultipleRecords(
    	function(result){
    		var fields = parentEntFields.split(",");
    		var res1 = formattValues(result,fields[0],true);//pass true if its a lookup
    		var res2 = formattValues(result,fields[1],true);//it's prepared to support lookup values
    		var res3 = formattValues(result,fields[2],true);
    		setField(formContext.getAttribute(entField1LogicalName),res1);
    		setField(formContext.getAttribute(entField2LogicalName),res2);
    		setField(formContext.getAttribute(entField3LogicalName),res3);
    	},
    	function(err){
    		console.log(err);
    	});
    }
    
    function formattValues(result,fieldLogicalName,isLookUp = false){
    	var value = result.entities[0] || null;
    	if(value){
    		if(!isLookUp)	
    			value =  value[fieldLogicalName];
    		else
    			value = setLookUp(value,fieldLogicalName)
    	}	
    	return value;
    }
    function setLookUp(objectResponse,fieldLogicalName){
    	var lookupValue = [];
    	var value = {};
    	value.id = objectResponse[fieldLogicalName]; 
    	value.name = objectResponse[fieldLogicalName "@OData.Community.Display.V1.FormattedValue"];
    	value.entityType = objectResponse[fieldLogicalName "@Microsoft.Dynamics.CRM.lookuplogicalname"];
    	lookupValue.push(value);
    	return lookupValue;
    }
    
    function setField(control,value){
    	if(control)
    		control.setValue(value);
    	
    }

    But when i trigger the on-change event (field Just_matricola) the system raise me an exception: 

    UciError: Value should be of type: string: Parameter Name: entityType
        
    
    Dettagli errore:
    Nome evento: onchange
    Nome funzione: setAssetsInfo
    Nome risorsa Web XML: just_retrieve_data_from_parent
    Nome soluzione: Active
    Nome editore: DefaultPublisher

    What is wrong?

    Thx , Regards

    Pietro

  • Suggested answer
    PabloCRP Profile Picture
    PabloCRP 1,086 on at
    RE: How to trigger a workflow without saving

    Hi, yeah I agree with Guido Preite

    You should write a custom webresource JavaScript and listening in OnChange event in the Incidet Form in the field Account.

    here an configurable example how it could be done note: It also could be improve to handle n fields but for the sake of the task you need, it could work

    function setAccountInfo(context){
    	//config
    	var caseField1LogicalName = "THE NAME OF YOUR FIELD ON CASE";//e.g: new_field1
    	var caseField2LogicalName = "THE NAME OF YOUR FIELD ON CASE";//e.g: new_field2
    	var accountFields = "ALSO LOGICAL NAME ACCOUNT FIELD SEPARATED BY COMMA"; //e.g accountfield1,accountfield2, if is a lookup the fortmat will be _FIELDNAME_value e.g _new_accountfield_value
    	var customerLogicalName = "customerid"; //I'm assuming the Case Account the field is  'customerid'
    	
    	var formContext = context.getFormContext();
    	var customerId = formContext.getAttribute(customerLogicalName).getValue();
    	if(!customerId)
    		return;
    	customerId = customerId[0].id.replace(/[{|}]/g,"");
        var entityName = "account";
    	var query = `?$select=${accountFields}&$filter=accountid eq ${customerId}`;
    	Xrm.WebApi.retrieveMultipleRecords(entityName,query).then(
            function(result){
                var fields = accountFields.split(",");
                var res1 = formattValues(result,fields[0]);//pass true if its a lookup
                var res2 = formattValues(result,fields[1],true);//it's prepared to support lookup values
                setField(formContext.getAttribute(caseField1LogicalName),res1);
                setField(formContext.getAttribute(caseField2LogicalName),res2);
            },
            function(err){
                console.log(err);
            }
        );
    }
    
    function formattValues(result,fieldLogicalName,isLookUp = false){
    	var value = result.entities[0] || null;
    	if(value){
    		if(!isLookUp)	
    			value =  value[field1LogicalName];
    		else
    			value = setLookUp(value,fieldLogicalName)
    	}	
    	return value;
    }
    function setLookUp(objectResponse,fieldLogicalName){
    	var lookupValue = [];
    	var value = {};
    	value.id = objectResponse[fieldLogicalName]; 
    	value.name = objectResponse[fieldLogicalName "@OData.Community.Display.V1.FormattedValue"];
    	value.entityType = objectResponse[fieldLogicalName "@Microsoft.Dynamics.CRM.lookuplogicalname"];
    	lookupValue.push(value);
    	return lookupValue;
    }
    
    function setField(control,value){
    	if(control)
    		control.setValue(value);
    	
    }

    now you just need to add it to your form and pass the execution context to it.

    Hope it help, regards.

     if it was helpful please consider mark it as an answer 

  • Guido Preite Profile Picture
    Guido Preite 54,081 Super User 2024 Season 1 on at
    RE: How to trigger a workflow without saving

    Dear Brandon Sabat,

    what you wrote is incorrect, also real time workflows require that the record is saved in order to be triggered.

    Regarding the initial question, retrieving the related record information before the save can be done with JavaScript and the Xrm.WebApi.retrieveRecord method docs.microsoft.com/.../retrieverecord

  • Suggested answer
    RE: How to trigger a workflow without saving

    Thank you for using the Dynamics communities.  One idea that may work is the use of a Real Time workflow - blog.clickdimensions.com/.../.  The real time workflow can execute when a record changes without a user saving.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Community AMA December 12th

Join us as we continue to demystify the Dynamics 365 Contact Center

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,240 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,149 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans