Thursday, October 18, 2012

Dynamics CRM 2011 JavaScript “Access is Denied” Error with OData call

Dynamics CRM 2011 JavaScript “Access is Denied” Error with OData call
In CRM 2011 on load of JS users geting ""Access is Denied" error if they have OData call
when they use the Xrm.Page.context.getServerUrl();

Use the below JS
document.location.protocol + "//" + document.location.host + "/" + Xrm.Page.context.getOrgUniqueName();

Tuesday, June 12, 2012

CRM 2011 User does not have send-as privilege



CRM 2011 User does not have send-as privilege

When you have workflows in CRM 2011 that create e-mails for other users, like say, send an e-mail from the person who last modified an account to the owner of the account, you’re probably going to end up with e-mails staying in Draft.
When you want to send the e-mail afterwards you’re greeted with a nice: “User does not have send-as privilege.” (ErrorCode: -2147203059) exception.
When you look up the privilege, it’s nowhere to be found in the UI.
You can however set it (as suggested on the Microsoft Forum) in the Personal Settings.


The downside, you only get this option when you have the System Administrator role and no other.
When looking in the database, there is actually a prvSendAsUser privilege, so after assigning it to a general role that all users get like this:
AddPrivilegesRoleRequest addPrivilegesRequest = new AddPrivilegesRoleRequest
{
RoleId = new Guid(generalroleid),
Privileges = new[]
{
// Grant prvSendAsUser privilege.
new RolePrivilege
{
PrivilegeId = new Guid("6FD3EB4F-66E3-4587-B4AB-C064F03AD783"),
Depth = PrivilegeDepth.Global
}
}
};
service.Execute(addPrivilegesRequest);
If you afterwards have a look at the user’s privileges in the database with this query:
SELECT p.name
FROM SystemUser u
JOIN filteredSystemUserRoles sur ON sur.systemuserid = u.systemuserid
JOIN RolePrivileges rp ON rp.roleid = sur.roleid
JOIN FilteredPrivilege p ON p.privilegeid = rp.PrivilegeId
You’ll see that the user has in fact got the prvSendAsUser role.
But when you try to send an e-mail the problem stays the same.
The solution however is very simple, check for this privilege is not done in through privileges, despite what the exception makes you suggest, but is checked in the user settings.
Running an easy update query will fix this for you:
UPDATE UserSettings
SET IsSendAsAllowed = 1
WHERE IsSendAsAllowed = 0
Logical, no; but does it work, yes

Monday, May 7, 2012

CRM2011 oData: Retrieve Lookup and String field values using JS and REST Endpoints


CRM2011 oData: Retrieve Lookup, String field values using JS and REST Endpoints 

// JScript source code
function lookupvalidation() {
    var TechExpert = new Array();
    TechExpert = Xrm.Page.getAttribute("msft_technicalexpertiseid").getValue();

    if (TechExpert != null) {
        var name = TechExpert[0].name;
        var uniqueid = TechExpert[0].id;
        var entType = TechExpert[0].entityType;

        //Required ODataQuery
        var context = parent.Xrm.Page.context;
        var serverUrl = context.getServerUrl();
        var odataSelect = serverUrl + "/xrmservices/2011/OrganizationData.svc/msft_technologySet?$select=msft_CategoryId,msft_PandL&$filter=msft_technologyId eq guid'"
+ uniqueid + "'";
        //  alert(odataSelect);

        $.ajax({
            type: "GET",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            url: odataSelect,
            beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
            success: function (data, textStatus, XmlHttpRequest) {

                // Multiple Entities retrieval
                ProcessReturnedEntities(data.d.results);

            },
            error: function (XmlHttpRequest, textStatus, errorThrown) { alert('OData Select Failed: ' + odataSelect); }
        });

    }

}

function ProcessReturnedEntities(ManyEntities) {
    // var AwardCategory = new Array();
    //AwardCategory = ManyEntities[0].msft_CategoryId;  

    var id = ManyEntities[0].msft_CategoryId.Id;
    var name = ManyEntities[0].msft_CategoryId.Name;
    var entityType = ManyEntities[0].msft_CategoryId.LogicalName;

    var AwardCategory = new Array();
    AwardCategory[0] = new Object();
    AwardCategory[0].id = id;
    AwardCategory[0].name = name;
    AwardCategory[0].entityType = entityType;

    var PL = ManyEntities[0].msft_PandL;

    //Assign AwardCategory based on Technical Experitise
     if (AwardCategory != null)
     Xrm.Page.getAttribute("msft_awardcategoryid").setValue(AwardCategory);


    //Assign Product&Language based on Technical Expertise
    if (PL != null)
        Xrm.Page.getAttribute("msft_pl").setValue(PL);

}

Wednesday, May 2, 2012


CRM2011-MultiForm: Display default form based on the Optionset/Lookup field values on the form.



  var programlookup = new Array();
    programlookup = Xrm.Page.getAttribute("msft_programid").getValue();

    if (programlookup != null)
    {

        var name = programlookup[0].name;
        var guid = programlookup[0].id;
        var entType = programlookup[0].entityType;
        // alert(Xrm.Page.ui.formSelector.getCurrentItem().getLabel());

        if (Xrm.Page.ui.formSelector.getCurrentItem() != null)
        {
            var formlabel = Xrm.Page.ui.formSelector.getCurrentItem().getLabel();
            if (formlabel != name)
            {
                var items = Xrm.Page.ui.formSelector.items.get();
                for (var i in items)
                {
                    var item = items[i];
                    var itemId = item.getId();
                    var itemLabel = item.getLabel()

                    if (itemLabel == name)
                    {
                        var attributes = Xrm.Page.data.entity.attributes.get();
                        for (var j in attributes)
                            attributes[j].setSubmitMode("never");
                        item.navigate();
                    }

                }
            }
        }
    }

Disadvantages: 
1. Performance(Form will load twice if last opened form is not same as field value)
2. On load page will blink
3. Make optionset/lookup field readonly so that user can't change the values

Plugin: Revoke sharing permissions to all USERS/TEAMS associated to a record

Plugin: Revoke sharing permissions to all USERS/TEAMS associated to a record


              public void Execute(IServiceProvider serviceProvider)

        {
            try
            {
                IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                service = factory.CreateOrganizationService(context.UserId);

                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    Entity entity = (Entity)context.InputParameters["Target"];

                    string _contact = entity.LogicalName;
                    Guid _contactid = entity.Id;

                    if (entity.LogicalName == "contact")
                    {
                        RetrieveSharedPrincipalsAndAccessRequest retrieveSharedRequest = new RetrieveSharedPrincipalsAndAccessRequest()
                    {
                        Target = new EntityReference(context.PrimaryEntityName, context.PrimaryEntityId)

                    };
                        RetrieveSharedPrincipalsAndAccessResponse retrieveSharedResponse = (RetrieveSharedPrincipalsAndAccessResponse)service.Execute(retrieveSharedRequest);
                        RevokeAccessRequest revokeRequest = new RevokeAccessRequest();
                        revokeRequest.Target = new EntityReference(_contact, _contactid);

                        foreach (PrincipalAccess principal in retrieveSharedResponse.PrincipalAccesses)
                        {
                            revokeRequest.Revokee = principal.Principal;
                            service.Execute(revokeRequest);
                        }


                    }
                }
            }


Note: Please test before using this code