fredag 9 september 2016

Dynamics CRM online learning path

I haven't fiddled much with a new CRM online for a while now and when I started a trial recently I nearly popped a vein in my head. There was a help flyout from the right side of the screen that kept popping out and I couldn't find a way to get rid of it.

There was an easy way though, on your personal settings menu under the cog you have an option saying "opt out of learning path

Pretty straight foward but if you don't know it's there you could easily have an anurism :).
This seems to be online only since we don't have it in our own on prem CRM.

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se  

tisdag 30 augusti 2016

Send email from workflow gives User does not have send-as privilege error

Yes, I know, it's been a while but this is at least something new here.
I've been fiddling with email sending from workflow this week and when I was done, or at least thought I was done, and handed it over to testing I was slightly confused when all emails created ended up in status of Draft.

I had no idea what was going on. I started by looking at the trace logs of the server and found this

Process:CrmAsyncService |Organization:673c5996-a1fa-e311-93ed-00155d0a831d |Thread:   14 |Category: Exception |User: f1b2fe83-133c-47ab-8bc7-081c14c88fea |Level: Error |ReqId: bd557cc3-49d1-4fea-97c8-be0b1ada06f7 | CrmException..ctor  ilOffset = 0x7

Yes, that is very informative don't you think. The thing is it works when I do it but when my colleague, and in this case Boss, tries to do the same procedure nothing happens after the email is created.
The user in this case is the user SYSTEM which makes it even more confusing.

I finally found this thread: https://community.dynamics.com/crm/f/117/t/90680 in which it says to enable “Allow other Microsoft Dynamics CRM users to send e-mail on your behalf" in the settings. The file part here is the cog which opens the menu with the personal settings. This has to be enabled for the user that owns the workflow.

**EDIT**
It turns out that this is not the solution, but rather a coincident that it actually works. When you have a workflow creating emails for you you will need to turn on the "allow other Microsoft Dynamics CRM users to sen e-mail on your behalf" for every user that will use the workflow. Probably because the workflow is run by a service account in CRM, but I really can't say.

Good luck out there!

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se  
 

tisdag 25 augusti 2015

Mapping from opportunity through quote to salesorder

I've run into this issue a couple of times now so I thought it might be a good thing to collect what I've found about this issue. If you noticed that the order of the lines from an opportunity isn't copied from opportunity to quote and then on to salesorder. 

This probly ranks among the sort-of-supported, but it's not any SQL hacks involved so I think it's sort of kosher. 
All info is taken from https://community.dynamics.com/crm/f/117/t/140108 which in turn points to a bllog. This is a  summary of that.

First, run the following SQL command on your organisation db:
SELECT  EntityMapId
FROM    EntityMapBase
WHERE   TargetEntityName='quotedetail' AND SourceEntityName='opportunityproduct'
That will give you a guid to a mapping page which is interesting. When you want to do the same thing on quote to order mapping, change the target to "salesorderdetail" and the source to "quotedetail"

Now we use the guid provided by the nice database in the following URL: http://[x]/Tools/SystemCustomization/Relationships/Mappings/mappingList.aspx?mappingId=[y]. Change [x] to serverurl and organisation (myserver/testorg/) and the [y] to the guid just found in the database

This opens a mapping page where you can insert mapping from sequencenumber to sequencenumber and the products will be in the same order in both records.
I'm pretty much posting this to make it easier for me to find, maybe it's good for someone else too. Again, I haven't found out how you did this, just to make sure.

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se  
 

fredag 14 augusti 2015

Exchange rates per record, or any color you like

Since I started working with Dynamics CRM the "issue" of one exchange rate per currency has come up a couple of times. How do you handle it, when do you update, what do you do if you want to... 
A customer of ours wanted to have an exchange rate per record so how can you fix that and still be able to use the rest of the functionality.

This is by no means THE solution but it is one. I was fiddling around a bit with CRM when I got the problem. Could I write directly to the base currency, was there any other way around the issue, should we use some other field?

I started looking on the web for solutions and I found this short blog http://www.crmsoftwareblog.com/2012/11/dynamics-crm-2011-multiple-exchange-rates-for-currencies/ which pointed be in the direction of the RetrieveExchangeRate message. Having no idea, I had a look in the plugin registration and yes, there was indeed still such a message



















(Yes, I'm still using the 2011 plugin registration tool, it works and you can store multiple connections...)

So, having found this message and having no idea how to use it, I didn't find anything about it in the SDK either, so I started out with a pretty empty plugin which was called by the message which I step debugged in VS to see what was going on.

It would prove to be fired before everything else and the calling object was present as context.ParentContext. After that quick test I started getting stuff together. So, this is what I did:

IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
            Entity parentTarget = ((Entity)context.ParentContext.InputParameters["Target"]);
            IPluginExecutionContext parentContext = context.ParentContext;


The usual suspects, set stuff up.

if (parentTarget.LogicalName == "crmk_testentity")
            {


Run the code only when we are interested of the result. Now you can do pretty much what you want, in my case we had the exchange rate in a parent object so I had to fetch that, it could also be the case that the currency was the base currency and the plugin didn't need to do anything. This meant I needed to fetch the currency and the wanted exchange rate. 

The magic happens with the output from the RetrieveExchangeRate plugin,  
context.OutputParameters["ExchangeRate"] = exch; 

"exch" is a decimal and you can set it to whatever you want and then CRM behaves as if it just retrieved the exchange rate from the system. Since we're using a plugin message and not doing anything realy naughty, more than pretty much a man in the middle attack on the system itself, this should be supported.

Happy coding

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se  
 

onsdag 8 juli 2015

Company Name not available in lead views

I was editing system views for a customer today and had some issues with the company name field on the lead system views.

It seems that this is a bug which has been reported to Microsoft connect, so please upvote this. https://connect.microsoft.com/dynamicssuggestions/feedbackdetail/view/955886/cannot-add-company-name-column-in-existing-standard-view-in-lead-entity

I found this in CRM 2013 but it seems that it's an issue in CRM 2015 as well. Here's a thread where I found the connect issue; https://community.dynamics.com/crm/f/117/p/122564/405479#405479

Please vote on connect so we get rid of these mighty annoying bugs.

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se

tisdag 7 juli 2015

Part two of the time zone tombola

So, I did actually keep the "6 months timeframe" that I promised in the last part, just over two months is a bit longer than I planned this though. So how did I go on with our time zone issue?

The main idea is that we use the CRM time fields to keep track of stuff in UTC time. Those fields will always show the user when the meeting takes place in the time zone you have set in CRM.














As you can see in the picture I have set up two time blocks, "local meeting time" and "my time". The local meeting time is the time when the meeting takes place at the actual site. If we woul
d have a meeting in London, and this is my CRM running CET there would be a difference of one hour between the two where "my time" would be one hour ahead.

As you can see I also locked the datetime fields in my time so all editing happens in "local time".

Now on to JS madness.

Onload of the appointment form I fetch the starttime and endtime of the appointmen, if those aren't set I set them as new Date(), which I then make sure is on the hour of half hour. I also fetch the duration field, which is a tricky bastard I might add, and the custom timezone field.

The endtime is set as starttime plus duration if there are no values for start and endtime on the form.

Now things got a bit trickier, and here's why I don't like time zones. I use the same way that CRM uses the timezones for the script part so I set up a timezone setting array which looks something like this:
localSettings = [0, 10, 5, 0, 2, 3, 5, 0, 1, -60];

So, this is slightly greek but this is a settings array for UTC. The first element is timezone bias, which is 0 for UTC. To make it slightly worse it's negative for CET so you take the time i CET and add the bias to end up in UTC.
The second element is standard month, which is the month in which standard time is starting, no worries, well I might mention that January is 0 in JS. 
The third element is standard day, which could be a date but it isn't  since you change back to standard time on the fourth saturday after the fifth moon after midsommer, ish. That is which number of day this is, in this case the fifth time the day appears in a month.
The fourth element is standard day of week, which means which day we are lookin at, and since 0 is the first day of the week, it's a sunday.
The fifth element, standard hour, is what time of day you return the clock one hour. Which in this case means that in UTC you return the clock one hour at two in the morning.
 The following four elements are the same for DST and the final element is daylight bias, which again is negative.
I also fetch the users timezone settings from CRM to calculate UTC time.

With this info I calculate when DST starts and ends using the following code:
 var GetDst = function (inyear, month, day, dayofweek, hour,tzBias) {

    if (tzBias == 0)
        return new Date(2011, 1, 1, 12, 0, 0, 0);

    var returnDate = new Date(inyear, (month - 1), 1, hour);
    var testDate = new Date(inyear, (month - 1), 1, hour);
    var firstDayOfMonth = new Date(inyear, (month - 1), 1);
    var firstDay = firstDayOfMonth.getDay();

    if (firstDay != dayofweek) {
        if (dayofweek == 0)
            testDate.setDate(testDate.getDate() + (7 - firstDay));
        else
            testDate.setDate(testDate.getDate() + (dayofweek - firstDay));
    }

    testDate.setDate(testDate.getDate() + ((day-1) * 7));
    if(testDate.getMonth() != (month - 1))
    {
        testDate.setDate(testDate.getDate() - 7);
    }
    return testDate;
}


Here the inputs are the year from the appointment, in the first case I want DST start time for the year the appointment is happening, month, day, dayofweek and tzbias are from the settings array

First I set a date of the year, DST start month, the first day of that month and the hour that stuff happens. I alse set up en exact copy of that date. 
I the proceed with finding out which day of the week the first day of the month is and compare that to the daylight saving start day and if the don't match I find when the first "change day" of the month happens (say first sunday).
After this I apply the number of weeks that should be added and check if we're still in the same month, if not, remove one week. SIMPLE

The time presented in "My time" is set up by UTC time plus timezone difference and DST difference so to get UTC time from the form I convert that time with the info about 
I then check if the time we get out of CRM is within DST and apply the changes to get to UTC time. 

This is done since I can never be sure that the computer's timezone setting is the same as CRM settings so I need to calculate the time in the form based on the CRM settings, yes that made me feel a bit sick too.

After I've calculated what the "my time" times are in UTC time I can then apply the timezone info on that data and I know when the meeting is taking place at the local office.

What I also do is set the submitmode to never if it's anything else than a create form. You will also need onchange scripts that sets the submitmodes to relevant values when you change an appointment.

The duration field isn't really propagated in a way you would think when you change it so that has to be made dirty with code to be sent, very annoying and a source of errors I might add.

I hope this makes some sence. It's a bit tricky and I had to work quite hard to get it right. What started out as a "Oh, we just take whatever time CRM is giving us and add an hour and we're home free" ended up in a couple of hundred lines of scripts and a little less plugin code to handle the saves.

So as my commanding officers said after an order or information speech. Any questions, too late, dismissed!

Seriously, if you would stumble upon this and have similar issues, give me a holler and I'll try to help. I'm thinking of talking about the backend code sometime later, maybe in another two months :)

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se

onsdag 24 juni 2015

Email Configuration button missing

No biggie, and quite documented but I'd like to point this out anyway. 

If you're not having any email configuration button in the settings area, then you have probably upgraded from CRM 2011 and the button isn't part of the sitemap. The solution is to add the following to you sitemap right aftert the <SubArea ID="nav_audit"...> tag,

<SubArea Id="nav_social" ResourceId="Social_SubArea_Title" DescriptionResourceId="Social_SubArea_Description" Icon="/_imgs/area/16_social.png" Url="/tools/social/social_area.aspx" AvailableOffline="false" />

It's pretty logic that you should add the social nav to get email configuration. Read more at
http://blogs.msdn.com/b/emeadcrmsupport/archive/2014/03/07/dynamics-crm-2013-email-configuration-tab-is-missing-from-the-settings.aspx

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se