CRM 2011 Customer Portal: Allowing Contact Access to Multiple Accounts

In my previous implementation blog I discussed our need for our “Contractors” in our system as contacts to have access to multiple accounts through the Customer Portal.  With the eService portal our solution was to continually reassign the contacts to different accounts as they worked through cases.  This was not an ideal solution. Also with setting the account level permissions when you adjusted a contacts account assignment you were allowing other contacts of that account to view information they maybe should not have access to.

The new customer portal has this wonderful Case Access Permission which appeared to allow multiple account access, but under further review of the code I found this was not the case.

In fact the only thing that really seemed to matter was the account the contact was assigned to and the permissions set on the case access permissions level.  The code would look for a parent account assigned and then based on the permission level bring back cases for all contacts under that account or only cases for that user.  On the view cases page there is a drop down for My, Company, All.

var casesByCustomer = string.Equals(CustomerFilter.Text, "My", StringComparison.InvariantCulture)
? casesByStatus.Where(c => c.CustomerId.Id == Contact.ContactId)
: string.Equals(CustomerFilter.Text, "My Company's", StringComparison.InvariantCulture)
? casesByStatus.Where(c => c.CustomerId.Id != Contact.ContactId)
: casesByStatus;

as you can see this filters you cases, then the cases that are the companies and not yours, and then all cases.  My assumption was My company would return the cases for your assigned account, and all would bring back the cases assigned to any case access permissions you have.  Well I also noticed that when you are assigning the case access permissions the account was only a recommended setting, which told me it is probably not really looked at in the code.  I was correct.

So I end up on the CaseAccess.cs page.

Our process for entering a case is set contact and then the account is automatically set in a new_account field we added.  With that being said, we always have a contactid in the customerid field in our incidents table.

I reworked the code in the GetCasesByCustomer function to access the case access permission bring back the account id for each set of permissions and then bring back all cases that have the accountid listed in our new_accountid field.  This does two things, this actually ensures that the account cases that come back are actually account cases and not cases for a contact that has now suddenly been reassigned to a new account and it allows us to bring back cases from other accounts.

I removed this code which we did not need.  Our customerid will never return an account.  And this code actually ends up returning cases we do not want.  I want only the cases that have the account listed in our new_account field to show up in the list based on the permissions.

var findAccounts =
from a in context.CreateQuery("account")
where a.GetAttributeValue<Guid?>("accountid") == customerId
select a;
var account = findAccounts.FirstOrDefault();
if (account == null) return result;
var contacts = account.GetRelatedEntities(context, "contact_customer_accounts");
foreach (var contact in contacts)
{
result.AddRange(GetCasesByCustomer(context, contact.GetAttributeValue<Guid?>("contactid")));
}

I added this code:

IEnumerable allcaseaccess;
//use linq to pull back accountid's from adx_caseaccess
allcaseaccess = from aa in context.CreateQuery("adx_caseaccess")
where aa.GetAttributeValue<Guid>("adx_contactid") == Contact.GetAttributeValue<Guid?>("contactid")
select aa;
//loop through accounts
foreach (var access in allcaseaccess)
{
//pull cases based on accountid matching our new_accountid
var findcases =
from c in context.CreateQuery("incident")
where c.GetAttributeValue<Guid?>("new_accountid") == access.GetAttributeValue<Guid>("adx_accountid")
select c;
//list of cases to existing results
result.AddRange(findcases);
}

This is great, but you will need to add the account column to the view so the contact/consultant can see what account the case belongs to That is done inside CRM in the “Cases Web View” columns.

Now on the createCase.aspx we will need to add the ability to set the account on the form.

Add a field to form

<asp:DropDownList ID="ddlAccount" runat="server" />

then in the code behind we will need to populate that with the accounts this contact has access to.

var allcaseaccess = from aa in ServiceContext.CreateQuery("adx_caseaccess")
where aa.GetAttributeValue<Guid?>("adx_contactid") == Contact.GetAttributeValue("contactid")
select aa;
foreach (var access in allcaseaccess)
{
var accountname = from aa in ServiceContext.CreateQuery("account")
where aa.GetAttributeValue<Guid?>("accountid") == access.GetAttributeValue("adx_accountid")
select aa.GetAttributeValue("name");
ddlAccount.Items.Add(new ListItem(accountname.FirstOrDefault().ToString(), access.GetAttributeValue<Guid?>("adx_accountid").ToString()));
}

This code is added in the page_load just before the if (isPostBack) return;  this will populate the dropdown with the appropriate Text/Value pairs.

Then in the CreateButton_Click function you will need to add the code to set the account in the creation of the case.  Now accounts are technically an entity even though all it appears to need is the GUID of the account. You have to take the GUID you are handed and ask for the actual account entity reference.

EntityReference selectedaccounts = new EntityReference("account", new Guid(ddlAccount.SelectedValue));

and then add the account id to the properties to for the create incident.

var incident = new Incident
{
Title = TitleTextBox.Text,
PriorityCode = int.Parse(PriorityCode.SelectedValue),
CaseTypeCode = int.Parse(CaseType.SelectedValue),
SubjectId = subject.ToEntityReference(),
CustomerId = Contact.ToEntityReference(),
Description = Description.Text,
New_MaintContract = TargetDate.Text,
CaseOriginCode = 3,
<span style="color: #ff0000;">new_accountid = selectedaccounts,</span>
Adx_CreatedByUsername = Contact.FullName,
Adx_CreatedByIPAddress = Request.UserHostAddress
};

This is how the final create case should look

In this case the contact has access to two accounts.  Kentrox and Kentrox MEA.

Other things I should mention.  We did alter the mapping of the relationship between cases and accounts to use the new_account field we created to have the appropriate cases display in the list on an account level.

About dorothyjarry

Super Dots
This entry was posted in CRM, CRM 2011, Customer Portal, Dynamics. Bookmark the permalink.

16 Responses to CRM 2011 Customer Portal: Allowing Contact Access to Multiple Accounts

  1. I’m no longer positive where you are getting your info, but good topic. I needs to spend some time learning more or figuring out more. Thanks for excellent information I was on the lookout for this information for my mission.-

    Like

  2. Tanja Savant says:

    Where is that stated in the bill?

    Like

  3. Very first Off, let me commend your clearness on this matter. I’m not an expert on this subject, but soon after studying your post, my knowing has engineered considerably. Make sure you let me to grab your rss feed to remain in contact with any forthcoming updates. Good occupation and can offer you it on to acquaintances and my readers.I would wish to thank you for your efforts you have manufactured in composing this short article. I’m going for the identical ideal perform from you in the future too. The truth is your fanciful composing talents has prompted me to start my very own weblog now. In fact the blogging is spreading its wings quickly. Your create up is really a good instance of it.

    Like

  4. Considerably, the article is in reality the greatest on this noteworthy topic. I agree with your conclusions and also definitely will eagerly look forward to your next updates. Saying thanks can not just be sufficient, for the excellent clarity in your writing. I will without delay grab your rss feed to stay privy of any kind of updates. Pleasant work and also much success in your business dealings!

    Like

  5. Jeremy says:

    While trying to create a case, I receive the following error. I made some changes to get it to build the project, but i can’t seem to figure out why this is failing here.

    Exception Details: System.InvalidCastException: Specified cast is not valid.

    Source Error:

    Line 26: select aa.GetAttributeValue(“name”);
    Line 27:
    Line 28: ddlAccount.Items.Add(new ListItem(accountname.FirstOrDefault().ToString(), access.GetAttributeValue(“adx_accountid”).ToString()));
    Line 29: }
    Line 30:

    Like

    • dorothyjarry says:

      I am happy to help. because we are converting these to strings it really doesnt make since that it would give you an invalid cast error. I am going to ask some questions and I hope this doesnt feel like the tech support person asking if you have rebooted your computer.

      have you added the case access with account permission for the contact you are logging in as? Instead of looking at the traditional account the contact is assigned to it looks at the accounts the contact has access to in the Account access permission.

      Dorothy

      Like

      • Jeremy says:

        Thank you for the reply,

        I’ve assigned them all rights in the “Case Access Permissions” under the “Common” section while modifying the contact. This is a test instance at the moment so I have the sample data installed and assigned them access to two of the sample accounts. I’ve also done this to the “Account Access Permissions” section just to see if it would help.

        If I remove all of the rights in the “Case Access Permissions”, the page loads just fine. Unlike your tutorial though, I am not making use of the new_accountid. But I don’t see that being used in this query so I doubt that as a problem. I haven’t completed the last step of modifying the CreateButton_Click function yet either.

        The rest of the pages after doing some modifications to them work great. I can see multiple accounts cases. The reason I had to modify the code is it was failing to build. I added things like and changed the code in GetCasesByCustomer to instead of using IEnumerable to use var. After those changes the build in Visual Studio succeed.

        This is a setup on a Claims Based/IFD CRM 2011 running on Windows 2008 R2.

        Like

      • dorothyjarry says:

        I can explain the new_accountid and the relevance. In our case entry we look for the name of the person calling in under contacts and then it automatically fills in the appropriate account in the new_accountid field. Because of this we always have a contactid in the customerid field inside of cases. this will impact the getcasesbycustomer returns. the important thing here is that the customerid in cases is always a contact. I am not sure how it would affect the code if it was an accountid, it would probably just not come back in the list. Also for Ienumberable you may have needed to add a reference, I just cant remember which one it is off the top of my head, but if using var is working great. I hope I understood correctly that you have the code working at this point?

        Like

      • Jeremy says:

        The code is still not functioning on the create case page. I am receiving the errors still.

        As a test I split them up
        var test = accountname.FirstOrDefault();
        ddlAccount.Items.Add(test.ToString());

        The error is reporting on the first line in this case. Same error though.

        Like

      • dorothyjarry says:

        I really hate to make you wait till monday, but I am going to have to say I am done with my work week for this week. If you can send me all of the code from this page that would be great and I will try to take a look this weekend. I want to see what all you have. Also try putting a break point and see what you are getting returned. that might help identify the issue. It is hard to debug when not seeing all of the code.

        Dorothy

        Like

      • Jeremy says:

        I was able to fix this finally. I needed to adjust the select a..GetAttributeValue to have a great than sign, then string and then the less than sign after it. Your WordPress blog is trimming off anything that looks like HTML it appears.

        Like

      • dorothyjarry says:

        So glad you were able to get this working. So the casting in your situation appears to need to be a String not a GUID. I will take a look at the code and make sure nothing is getting loped off.

        I just took a look at the code and your are correct it is removing some of the tags. I will get that updated. thank you so much for trying to use the code and when you had an issue working with me 😀

        thanks,
        Dorothy

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s