locked
CRM 4.0 programmatically deactivating a record RRS feed

  • Question

  • Hi

    I have a customized account entity with a custom Status picklist. If a user selects "Inactive" I have to deactivate the record. I tried to put the statecode field on the form and do the following:

    crmForm.all.statecode = 1; 

    But all I got on save was an error without any description or entry in the Event Viewer.

    I'd like to put a script in the forms OnSave event that would check the custom picklists selected value and, should it be "inactive", run a script to change the records status to "disabled".

    I'm also thinking about doing it in a plugin (as I already have one that runs when the entity is saved) but I'm not sure how to do it.

    Please help.
    Monday, March 2, 2009 11:47 AM

Answers

  • Did you thought tu use a workflow? In the workflow check if the picklist is "inactive". If "yes", deactivate it. It is very easy to write. The only negative: it is asynchrone.

    • Marked as answer by Grzegorz Zych Tuesday, March 3, 2009 9:21 AM
    Monday, March 2, 2009 5:53 PM
  • To make is syncronous, try writing a plugin that runs on update, post event.  It will look for your custom picklist field and if it is set to a given value then it will deactivate the account.

    Hope this helps.

    -Andrew Zimmer

    if (context.InputParameters.Properties.Contains("Target") &&
         context.InputParameters.Properties["Target"] is DynamicEntity)
        {
                        DynamicEntity entityInput = context.InputParameters.Properties["Target"] as DynamicEntity;
                        if (entityInput.Properties.Contains("new_yourpicklistfield"))
                        {
                            Picklist list = entityInput.Properties["new_yourpicklistfield"] as Picklist;
                            if (list != null && list.Value == ???)
                            {
                                service = context.CreateCrmService(true);
                                SetStateAccountRequest req = new SetStateAccountRequest();
                                // way to pull guid for update
                                req.EntityId = ((Key)((DynamicEntity)context.InputParameters[ParameterName.Target]).Properties["accountid"]).Value;
                                // Set to inactive
                                req.AccountState = AccountState.Inactive;
                                req.AccountStatus = 2;
                                SetStateAccountResponse response = service.Execute(req) as SetStateAccountResponse;
                            }
                        }

        }

    Monday, March 2, 2009 6:54 PM
  • 1. You could also do the same thing with a Work Flow, checking on your attribute.
    2. Or ... You could use this function on form save; checking on your attribute.
     
    function deactivateaccount()
    {
       var sId = crmForm.ObjectId; sId = sId.replace("{",""); sId = sId.replace("}","");
       var sEntityName = "account"; var sState = "inactive"; var iStatus = "-1"
     
       if (sId == null) return false;
     
       var authenticationHeader = GenerateAuthenticationHeader();
       var xml = "<?xml version='1.0' encoding='utf-8'?>" +
       "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
       " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
       " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+ authenticationHeader;
       xml += "<soap:Body><Execute xmlns='http://schemas.microsoft.com/crm/2007/WebServices'><Request xsi:type='SetStateDynamicEntityRequest'>";
       xml += "<Entity><Id xmlns='http://schemas.microsoft.com/crm/2006/CoreTypes'>" + sId + "</Id>";
       xml += "<Name xmlns='http://schemas.microsoft.com/crm/2006/CoreTypes'>" + sEntityName + "</Name></Entity>";
       xml += "<State>" + sState + "</State>";
       xml += "<Status>" + iStatus + "</Status>";
       xml += "</Request></Execute></soap:Body></soap:Envelope>";
       var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
       xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
       xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
       xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
       xHReq.setRequestHeader("Content-Length", xml.length);
       xHReq.send(xml);
       var resultXml = xHReq.responseXML;
       var errorCount = resultXml.selectNodes('//error').length;
       if (errorCount != 0)
       { var msg = resultXml.selectSingleNode('//description').nodeTypedValue; alert(msg); return false;}
       else{return true; }
    }
    • Marked as answer by Grzegorz Zych Tuesday, March 3, 2009 9:21 AM
    Monday, March 2, 2009 8:52 PM

All replies

  • Did you thought tu use a workflow? In the workflow check if the picklist is "inactive". If "yes", deactivate it. It is very easy to write. The only negative: it is asynchrone.

    • Marked as answer by Grzegorz Zych Tuesday, March 3, 2009 9:21 AM
    Monday, March 2, 2009 5:53 PM
  • To make is syncronous, try writing a plugin that runs on update, post event.  It will look for your custom picklist field and if it is set to a given value then it will deactivate the account.

    Hope this helps.

    -Andrew Zimmer

    if (context.InputParameters.Properties.Contains("Target") &&
         context.InputParameters.Properties["Target"] is DynamicEntity)
        {
                        DynamicEntity entityInput = context.InputParameters.Properties["Target"] as DynamicEntity;
                        if (entityInput.Properties.Contains("new_yourpicklistfield"))
                        {
                            Picklist list = entityInput.Properties["new_yourpicklistfield"] as Picklist;
                            if (list != null && list.Value == ???)
                            {
                                service = context.CreateCrmService(true);
                                SetStateAccountRequest req = new SetStateAccountRequest();
                                // way to pull guid for update
                                req.EntityId = ((Key)((DynamicEntity)context.InputParameters[ParameterName.Target]).Properties["accountid"]).Value;
                                // Set to inactive
                                req.AccountState = AccountState.Inactive;
                                req.AccountStatus = 2;
                                SetStateAccountResponse response = service.Execute(req) as SetStateAccountResponse;
                            }
                        }

        }

    Monday, March 2, 2009 6:54 PM
  • 1. You could also do the same thing with a Work Flow, checking on your attribute.
    2. Or ... You could use this function on form save; checking on your attribute.
     
    function deactivateaccount()
    {
       var sId = crmForm.ObjectId; sId = sId.replace("{",""); sId = sId.replace("}","");
       var sEntityName = "account"; var sState = "inactive"; var iStatus = "-1"
     
       if (sId == null) return false;
     
       var authenticationHeader = GenerateAuthenticationHeader();
       var xml = "<?xml version='1.0' encoding='utf-8'?>" +
       "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
       " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
       " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+ authenticationHeader;
       xml += "<soap:Body><Execute xmlns='http://schemas.microsoft.com/crm/2007/WebServices'><Request xsi:type='SetStateDynamicEntityRequest'>";
       xml += "<Entity><Id xmlns='http://schemas.microsoft.com/crm/2006/CoreTypes'>" + sId + "</Id>";
       xml += "<Name xmlns='http://schemas.microsoft.com/crm/2006/CoreTypes'>" + sEntityName + "</Name></Entity>";
       xml += "<State>" + sState + "</State>";
       xml += "<Status>" + iStatus + "</Status>";
       xml += "</Request></Execute></soap:Body></soap:Envelope>";
       var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
       xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
       xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
       xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
       xHReq.setRequestHeader("Content-Length", xml.length);
       xHReq.send(xml);
       var resultXml = xHReq.responseXML;
       var errorCount = resultXml.selectNodes('//error').length;
       if (errorCount != 0)
       { var msg = resultXml.selectSingleNode('//description').nodeTypedValue; alert(msg); return false;}
       else{return true; }
    }
    • Marked as answer by Grzegorz Zych Tuesday, March 3, 2009 9:21 AM
    Monday, March 2, 2009 8:52 PM
  • Thanks for all the awsome answers.

    I decided to go for a workflow, since it's the easiest to create.

    I have one question though: when I open a disabled account some picklists are still active - I can click them and select a value. Since a disabled account doesn't have a save button it's not really a big problem, but it looks weird and I'm afraid it'll confuse the users.
    Is this a bug in CRM, or simply a rendering problem (I'm using Virtual Desktop to connect to the CRM machine and I noticed similar problems when I hide sections in Javascript)?

    Also sometimes the workflow doesn't seem to catch the change - I select 'Inactive', save, but there is no reaction.
    Tuesday, March 3, 2009 9:20 AM
  • Hey Andrew,

    I liked your approach for changing states of the record.

    But It is giving me error on the last line

    " SetStateAccountResponse response = service.Execute(req) as SetStateAccountResponse; "

     

    Error Trace:

     

    Error: Server was unable to process request.

    Error Number: 0x80040216

    Error Message: An unexpected error occurred.

    Source File: Not available

    Line Number: Not available

     

    SoapException: Server was unable to process request.]

       at StateChange.StateChange.Execute(IPluginExecutionContext context) in C:\Documents and Settings\raksheet.koradia\My Documents\Visual Studio 2008\Projects\StateChange\StateChange\StateChange.cs:line 49

     

     

     

    Tuesday, November 30, 2010 9:25 AM