locked
Self-referential connections RRS feed

  • Question

  • We are using Dynamics CRM 2011. We are using the Contact entity for two types of contacts: 1) what you might call "regular" contacts = people with whom we might do business, and 2) Agents. I set up a custom field called Contact Type with two options to store and display which of these a given Contact record is.  I also set up two Connection Roles, one for each of the things above.

    I added a subgrid to the Contact entity form for "regular" Contacts and it displays Active Connections. I can click Connect, Add Connection to a Contact, via the ribbon, and new connections appear in the grid for that Contact record.

    What I need to do is find a way to limit Connections from Regular Contacts only to Agent Contacts and vice versa. That is, we don't want this kind of connection from Agent to Agent or from regular to regular. There's an N:N relationship between regular Contacts and Agents.

    How can I prevent the user from creating a connection between two Contacts with the same Contact Type? Can the  "Add Connection" process be intercepted in order to check the value of Contact Type, and possibly cancel the action?

    Thank you.

    \

    Monday, September 10, 2012 6:23 PM

Answers

  • I would think you might also be able to prevent the Connection from being created using a plugin on the Create message of the Connection entity. From the plugin you could return a message back to the user indicating why the Connection cannot be made. 

    Jason Lattimer

    • Proposed as answer by David L. Carr Wednesday, September 12, 2012 3:59 AM
    • Marked as answer by MeProgrammer Thursday, September 13, 2012 1:58 PM
    Tuesday, September 11, 2012 1:04 PM
    Moderator
  • Hi, the JavaScript would need to run on Load of your intercept entity. You would also want to add one additional check into the JavaScript to make sure the lookups are only cleared when you create a new record, and not when you are opening an existing record.

    Add the code into a javascript web resource, and then on your intercept entity add an event handler to the Form OnLoad event calling the Javacript function from your web resource

    Updated code including create check:

    //JavaScript Example to clear the other contact type
    function clearOtherContactType() {
        var isCreateForm = Xrm.Page.ui.getFormType() == 1;
        if (isCreateForm) {
            var contactType = Xrm.Page.getAttribute("new_contacttypecode").getValue();
            var agentField = Xrm.Page.getAttribute("new_agentid");
            var regularContactField = Xrm.Page.getAttribute("new_regularcontactid");
            var typeAgent = 100000000;
            var typeRegularContact = 100000001;
    
            if (contactType != typeAgent) {
                agentField.setValue(null);
            }
            if (contactType != typeRegularContact) {
                regularContactField.setValue(null);
            }
        }
    }

    Hope that helps!

    -Paul

    • Marked as answer by MeProgrammer Thursday, September 13, 2012 1:57 PM
    Wednesday, September 12, 2012 6:16 AM

All replies

  • Since this is a N:N relationship you need to create a workflow to handle your business logic.

    If it had been a 1:N relationship from agents to regular contacts, then you could have used the default functionality of filtered lookup.


    Rune Daub Senior Consultant - Dynateam CRM http://www.xrmmanagement.com

    • Proposed as answer by RuneDaub Monday, September 10, 2012 8:02 PM
    Monday, September 10, 2012 8:02 PM
  • Thanks for responding, Rune Daub.

    I created a workflow a little while ago that checked for

    1) Connected From: Contact Type = regular AND Connected To: Contact Type = regular, Change Record Status to Conenction Inactive (because there were a very few options)

    2) Connected From: Contact Type = Agent AND Connected To: Contact Type = Agent, Change Record Status to Conenction Inactive (because there were a very few options)

    I activated and tested the workflow and, although the workflow status was success, the Connections do not seem to have been set to Inactive.

    This was my first workflow. Where might I have made a mistake?

    Monday, September 10, 2012 8:28 PM
  • Maybe you could consider using a custom (manual) N:N relationship, instead of using the out-of-the-box Connections.

    In case you are unfamiliar with manual N:N relationships, this is basically a link between 2 entities, with an intercept entity in the middle that stores the ID of both records being connected. This results in a grid view being added to each entity (in this case both grids would be on the contact). The relationship would look something like this:

    Contacts (Agents) --- 1:N ---> Agent Connections <--- 1:N --- Contacts (Regular)

    The intercept entity (call this whatever you want) would have 2 lookups (both to contact). One for the Agent, and one for the Regular contact. You can then filter each lookup using Agent and Regular Contact views, so you can only select an Agent in the Agent lookup, and only a Regular contact in the Regular Contact lookup.

    This will work good (in theory), however there is one small catch. When you create a record from a parent, that parent is prefilled into all lookups of the parent entity type. This means when you add an Agent Connection, the contact will be set into both contact lookups. To solve this however you could map through your Contact Type into a hidden field on the intercept entity, and using a bit of javascript check: if the contact type is agent, clear the regular contact lookup, otherwise if the contact type is regular contact, clear the agent lookup.

    //JavaScript Example to clear the other contact type
    function clearOtherContactType() {
        var contactType = Xrm.Page.getAttribute("new_contacttypecode").getValue();
        var agentField = Xrm.Page.getAttribute("new_agentid");
        var regularContactField = Xrm.Page.getAttribute("new_regularcontactid");
        var typeAgent = 100000000;
        var typeRegularContact = 100000001;
    
        if (contactType != typeAgent) {
            agentField.setValue(null);
        }
        if (contactType != typeRegularContact) {
            regularContactField.setValue(null);
        }
    }

    This is just an idea, let me know if you need any help. It sounds complex, but it really should be quite simple to set up. Of course, this would mean the relationship between Contacts and Agents would not be captured under the standard 'connections', as it will be contained in it's own relationship, allowing you to control this more effectively.

    Hope that helps!

    -Paul

    Tuesday, September 11, 2012 6:31 AM
  • I would think you might also be able to prevent the Connection from being created using a plugin on the Create message of the Connection entity. From the plugin you could return a message back to the user indicating why the Connection cannot be made. 

    Jason Lattimer

    • Proposed as answer by David L. Carr Wednesday, September 12, 2012 3:59 AM
    • Marked as answer by MeProgrammer Thursday, September 13, 2012 1:58 PM
    Tuesday, September 11, 2012 1:04 PM
    Moderator
  • Thank you, Jason. I will research that idea.
    Tuesday, September 11, 2012 9:38 PM
  • Thank you, Paul. On what event would that jscript run?
    Tuesday, September 11, 2012 9:39 PM
  • Hi, the JavaScript would need to run on Load of your intercept entity. You would also want to add one additional check into the JavaScript to make sure the lookups are only cleared when you create a new record, and not when you are opening an existing record.

    Add the code into a javascript web resource, and then on your intercept entity add an event handler to the Form OnLoad event calling the Javacript function from your web resource

    Updated code including create check:

    //JavaScript Example to clear the other contact type
    function clearOtherContactType() {
        var isCreateForm = Xrm.Page.ui.getFormType() == 1;
        if (isCreateForm) {
            var contactType = Xrm.Page.getAttribute("new_contacttypecode").getValue();
            var agentField = Xrm.Page.getAttribute("new_agentid");
            var regularContactField = Xrm.Page.getAttribute("new_regularcontactid");
            var typeAgent = 100000000;
            var typeRegularContact = 100000001;
    
            if (contactType != typeAgent) {
                agentField.setValue(null);
            }
            if (contactType != typeRegularContact) {
                regularContactField.setValue(null);
            }
        }
    }

    Hope that helps!

    -Paul

    • Marked as answer by MeProgrammer Thursday, September 13, 2012 1:57 PM
    Wednesday, September 12, 2012 6:16 AM