Category Archives: Uncategorized

I was promoted in April and then I decided to resign in June? Why ?”

During our work life, we encounter different problems, they could emerge from bad decisions, unexpected events etc. This is how life is, with ups and downs. Like everyone, I had difficult times in my work life, but this time I want to speak about it, to raise awareness, especially because as an immigrant-expat I am concerned about the rights of people like me. Some people suggested that it is better not to write about it because Linked-In is a happy-we-all-enjoy-and-celebrate social network and it could be bad for my reputation for my future work life. I think we need to value freedom of speech in our lives and continue keeping it as a value, at least Western culture should not be ashamed of it!!

It was October 2021 that I got an offer to work in Accruent and I moved in December from Portugal to the Netherlands. 

Before becoming Accruent, the company was named BlueCielo (Still in Nederland legal terms it is BlueCielo) and then it was acquired by Accruent. Accruent is an American company which also belongs to a bigger firm. When I was applying for them, I emphasized that I am Iranian and I need visa sponsorship. They asked me to go through a comprehensive background check. 

I arrived in the Netherlands in December 2021, living in a shared place on Airbnb, paid a lot of money for moving and also hired an agent to find me an apartment (A very difficult step to do in the Netherlands). I was waiting for my access (Code repo, deployment etc.) to be created to start my job, but days passed and It was not created. It was the 22nd of December, a dark cold day and I got a call from the HR manager of the Netherlands office. He told me there are some legal issues with your nationality, not from the Dutch authority’s point of view, but from the US headquarters. It was a shocking moment for me. I have heard from many of my compatriots that this has caused a lot of trouble for them. The HR manager was not happy with what happened and apologized, however asked me to join an online meeting with another manager in the US to clear some questions. 

I could understand that it was not the intention of the HR manager in the Nederland office for things to go in this direction. It was a tough meeting for me. I do not want to get into details, but if I want to describe it, you can picture it as a polite interrogation session. Keep in mind that before coming to Nederland, my background was already checked. It really hurt me, but I had more important goals and I had to make a tradeoff. I chose to stay and closed my eyes to what happened. My Dutch colleagues apologized for what happened and they even sent me a small gift. The HR manager in the Nederland office left the company some months later.

The most ridiculous thing was that after I joined, as a newcomer I had to enrol for some organisational culture courses, one of them was about “avoiding discrimination based on gender, ethnicity and nationality”. Yes … Practice what you preach!  

During the time I was working there, I made lots of improvements, which I do not want to go into details about now, but I will share part of the performance review I received from my manager in Feb 2023, for my work in 2022: 

I got promoted in April 2023 and was happy and despite that, I knew people with my expertise and skills may earn more in other companies, I wanted to grow in Accruent and I explained my path and ambitions to my managers. 

It was May 2023 and I decided to buy an apartment. After spending a lot of time and money, hiring an advisor, etc., I found an apartment but 9 days before signing the purchase agreement, I asked HR to send me the “Werkgeversverklaring” or “employer’s declaration”. Days passed and I did not receive a response. I thought it was because they recently laid off a HR employee and they are busy. I contacted them to remind them but they only sent me an invitation for a meeting. 

I had signed the purchase agreement because I had an indefinite contract with the company and from talking to everybody who has gone through the apartment buying process in the Netherlands, I have never heard that you should ask for the “employer’s declaration” before taking any step. The day I had the meeting with the new HR manager and one other person in HR in NL, they told me due to some uncertainties about the company (if it is going to restructure or something), we can not provide the document. They never answered in writing about my request, which is still a big question for me. I had to cancel the apartment purchase agreement but had to pay a considerable amount of damage because I had hired an advisor and the apartment technical inspection was done. 

This was the second time that this company hurt me. Whomever Dutch or non-Dutch person I talked to, was surprised by the HR decision. Even one of my colleagues told me “I only requested the document when we were in the stage of asking for a mortgage request”. 

I followed up on this with my direct manager so at least the company would compensate for the damage. The HR or any other person in higher hierarchies decided to impose this damage on me, only based on “maybe s”. Realistically even if they decide to close the office today, it will take at least one year to shut down the product. Even my direct manager, who was shocked by the HR decision, told me you would definitely not be on the list for layoff. However, the company preferred to have a good face in front of the mortgage companies than their employees (This is what the new HR manager told me). This is their choice. 

The trust can not be broken multiple times, it is bidirectional and If there is a third time they cause a problem for me, then I am guilty. So I decided to resign, even though I would like to stay there, continue contributing etc. I still have respect for my team members in Nederland.

Finding a new Job

But let me share my experiences with finding a new job. From the first of June 2023, I started to apply for new jobs and I changed my status on Linked In. Some recruiters contacted me, most of them were reasonable and polite. However, I strongly suggest that you apply directly to companies and put third-party recruiters as the second priority. There is a huge gap of communication, when third-party recruiters come into play, let alone that each company has its definition of senior role (the position I was applying for). 

For me, the approach of some companies for the hiring process was also an indicator of how each company sees or values your skills. Some companies do not even go through your CV to see your open-source projects, blog posts etc. They only want senior coders! Even that is debatable. 

Some companies never gave feedback for the assignment they sent to you, for one of them I spent time travelling to their office and never heard back from them. 

Another case was a ridiculous recruiter who called me on the phone and said “Can you ask your friends to delete a LinkedIn post about you being open for a new role !” The most surprising thing I have ever heard about the job-seeking process! That recruiter only had an intro conversation with me and there was no offer yet on the table! 

Last but not least, I would take this moment and say thank you to all the people who supported me in finding a new job, my previous colleagues, Paolo, Tiago, and Ines from Portugal and Jaroon from Nederland. 

Differences of living in Portugal and the Netherlands as expat

Lisbon

Leiden

For those who do not know me, I am a software developer originally from Iran. In 2018, I got a job offer to relocate to Lisbon, Portugal. The company I applied for was a consultancy company that hired people to work for their customers as nearshore developers. 

It was my first experience of visiting Europe and also immigrating to another country. Honestly, I did not even have a clear idea where on the map the Portugal is, I only knew it from their good football players. I landed in Lisbon in 2019.

I am going to pick some important topics and compare two countries from the eyes of an expat/immigrant. 

Bureaucracy

Portugal:

Well, even the Portuguese complain about how bureaucracy goes in Portugal. Honestly, it was a stressful time for me from the time I asked for a visa and it took a long time and then also heard from other people how it goes with getting the residence card. I was lucky and I could obtain the residence card in time. But some friends of mine encountered issues, waiting in the queue with uncertainty. I heard that it recently got worse, since changes are going on to restructure the immigration service.

Netherlands:

Landed in Amsterdam in December 2021, left the good weather and what you don’t want is an exhausting bureaucratic process. Things go well in the Netherlands with the procedure of asking for a residence card, quick, and very clear. I even received a guideline from the IND (immigration office) on the basic steps I need to do in the Netherlands, like how to get health insurance, driving license, etc. 

Finding accommodation 

Portugal:

I am happy that the company which relocated me, provided temporary accommodation so that I could have enough time to search and find a place to live. You probably heard how crazy it is these days to find an apartment in Lisbon, however, in 2019 it was not easy either. There are a couple of websites like “Idealista” that you can try, but at the end, a colleague of mine helped me to have a room. I was paying 550 Euros for a room, but it was in a good neighborhood. 

Price-wise, considering the minimum wage at that time which was 700 Euros, it is was not cheap. 

Netherlands:

Do you think it is easier in the Netherlands? Nope! more difficult. A packed country with 10 million more people than Portugal, high demand for housing. The moment you request to visit an apartment, it might be gone already, despite that the advertisement has just been published. I had to hire an agent to help me. It is very important to have a registered address and the company which hired me could have me registered for a short time only.

Luckily there are a couple of websites where you can try to find an apartment (or house if you earn well) and Dutch people’s skills in English make it easier to communicate and ask questions about the accomodation. 

I could find a place to live in a house which was divided into two to be rented for two people/families. A furnished home without bills, 1,350 Euros. The minimum wage in Nederland is around 1995 Euros.

People and Culture (the most interesting topic for me)

Portugal:

Friendly, kind and warm. My colleagues helped me a lot when I was onboarding and my onboarding was not only getting used to how to work in that company but also my personal life in Portugal. I am still in contact with some of them. You can find friends in Lisbon and despite that their English language level is not as good as Dutchies, for a southern European country, they are at a good level. Even if they can not communicate in English they will find a way to help you, not all of them, but it is better than some other countries which I do not need to mention. 

My colleagues invited me to have dinner with them and introduced me to their friends (Never happens with Dutch people unless there is an exception). It is even possible to find friends your age (I was 28 at that time)

Food is great and they care about the time they spend eating. Wait? Are they lazy? Nope, this is just a bias most people have about Portugal. 

They are of course not as direct as Dutchies, a culture similar to where I am coming from. 

You can find a deep culture around music, literature and poetry in Portugal. I even made a podcast episode about Fado. Worth to mention that one Iranian entrepreneur moved to Portugal to found her business after she listened to my podcast.

Learning Portuguese is muito difícil (very difficult). Unfortunately, I spent 70% of my stay in Lisbon during the Covid lockdown and I only could get up to A1 level. However, this is not an easy language at all. 

Are they racist? I had some experiences but I can not generalize. 

Netherlands:

You know all the jokes about how people are in northern Europe. When it comes to the Netherlands, you have to consider some exceptions. Their high level of speaking English, having immigrants and other nationalities there for a long time and being famous for sea trading for centuries, make it easy to communicate with them. They smile at you in the street or say “Goede morgen”, even neighbors with older age, try to have small talk with you. This is not such a common thing in Lisbon. 

However, good luck finding a Dutch friend. I asked many of them “why it is difficult to do so”, some of them said that at your age (33 Now) Dutchies have already established their friendship and it is only easier for younger people. On the other hand, some say Dutch people never take you to their circle. 

Disappointed? It is not always like that. I have a friend from the badminton club I go, he is 30 years older than me and he has invited me to his place, spent time in the Saturday market with me and helped me to learn the language. 

In fact, older people are more patient and talk to you. 

Dutch are famous for being direct and that is completely true and it takes time to get used to it. Sometimes you can not distinguish if they are being rude or direct only, but in most cases, they are just direct which I appreciate. 

Important to know individualistic culture is dominant here and Calvinism has influenced their way of living.

Let’s not talk about food culture. It is “Vervelend” (In Dutch means boring), but it has its benefits for them. Saving time and healthy. But with all fried foods, at least I do not think it is healthy. 

Learning Dutch is not easy as well, they also know that, but for me, it is easier than Portuguese probably because it is a Germanic language and is not that far from English. 

Are they racist? I have not seen it so far, may be very slightly or implicit, but we all in some way have bias about others.

Health and insurance 

Portugal

With your contribution to tax and national security, you have access to public healthcare in Portugal for somehow free. However, finding a family doctor (General practitioner) is almost impossible in Lisbon. Asking for an appointment means you have to go to the clinic early in the morning, wait long hours for your turn and then ask for an appointment which comes one month(s) later. Their level of English makes it harder especially if the doctor is not young. 

However, there is a private health sector. It is faster and getting appointments is not hard. They have a good web or mobile application to help you with that and there they can communicate well in English. Insurance is not expensive and most of them also include dental care as well.

I am not a specialist to talk about the quality of their level of diagnosing or curing, but I did not have a good experience. 

Good to mention that Portugal was one of the countries that did well coping with COVID-19.

Netherlands

There is no public sector. Actually It is a bit strange for me the way it works. You should be registered with a health insurance and at least pay 130 Euros per month (without dental and physiotherapy included). Then there is personal risk, which means up to some value (like 385 Euros per year) you have to pay from your pocket for medical costs, then it becomes almost free (Get surprised to have to pay for some medications that insurance does not support).

It is not easy to find a general practitioner, but you can manage it, especially because they speak English. For emergency cases you can visit the doctor that day, however, when it comes to diagnosis, even Dutch people make jokes about their doctors. I have also heard that due to the low level of diagnosis, people have got cancer.

However, when I had serious issues, it was difficult to convince my GP to refer me to a specialist. Some people say this strongly depends on your GP, because they are always afraid of insurance companies (Capitalism). 

Public Transport 

Portugal:

The price of public transport in Lisbon is amazing. You pay 40 Euros and you can use Bus, metro, ferry and tram. They are on time although sometimes buses can be late. 

You can also have a yearly bicycle subscription (was 23 Euros at that time per year), which many of them are electric and make it easier to pass the high hills of Lisbon.

At the time I was there, they were extending bicycle roads but still far behind the Netherlands, especially because of the structure of the city. 

Netherlands:

Expensive! Although the companies pay (part of) for your commute to the office, for your personal usage it is not cheap. From the city that I live to the office, I have to pay 17 Euros for a round trip. It is all private sector (although the NS railway system is half private). It is sometimes cheaper to use your own car and this is very surprising when you see how much Dutch people care about the environment (they really do) but the public transport is insanely expensive. 

On the other hand, public transport quality is good and on time, although recently (people say after COVID), the trains have delays sometimes.

Do I have to mention how good the streets and roads are for bicycle riders? You really enjoy riding bicycles and commuting with them.

Supermarket

Overall the supermarket shopping was cheaper in Portugal than Nederland the time I was living in Lisbon, but nowadays I hear from Portuguese who visit Nederland or come here to work, some items in supermarkets are more expensive in Portugal than in Netherlands. Considering the fact that Netherlands is very good in agriculture and is known to be an exporter of vegetables, while Portugal is known for its wine and fish (Except Bacalhau which comes from Norway), it is easy to guess which items are cheaper. However, the variety of supermarkets and their price ranges make it easier to find different things (ingredients from different countries) in the Netherlands.

Entertainment and Sport

Portugal is famous for its beautiful beaches and mountains so you have options there. However, when it comes to indoor sports, if we exclude gyms, there are not many options compared to the Netherlands and I think people also do not demand it that much. Anyhow, in Netherlands people are interested in indoor sports activities (especially because of rainy and windy weather). It does not matter if you live in a village or a big city, there is always something close to you so do can not make excuses. Overall , I think Dutchies care a lot about their health, besides they cycle a lot. Here the old people go to sport clubs, but this is not something you can see in Portugal. 

When it comes to entertainment as well, in my opinion, you have a lot more options in Netherlands. Forget about festivals. I am not a fan, but watching theater, and comedy shows in English is a great option I have here. Although in terms of price Netherlands is more expensive than Portugal. 

Moreover, in terms of entertainment infrastructure, it is by far easier to access them in Nederland than in Portugal, especially if you do not live in big cities like Lisbon or Porto, you do not have that many choices.

Salary and Job

Portugal:

For a software developer you can earn more than many other jobs if you are hired by a Portuguese company. But most of them are consultant company and this what I did not like at the end, although I had a great experience working for INSCALE. Working as consultant highly depends on the client your are assigned to. However last time I was in Portugal (January 2023) I see a insane price rise for housing in Lisbon, despite that average salary is now higher (1044 EUR per month) it is still difficult to live in Lisbon. Should I move to another city ? I think from what explained above it would not be easy.

Good to know that you do not necessarily need to be hired by a Portuguese company and can work as digital nomad and be self employed.

Netherlands:

One motivation for me to move to the Netherlands besides my personal ones, was higher salary, 30% ruling and many possibilities to work directly with companies and not as consultant. The average salary in Netherlands is ( €2,855 per month). However you do not have the option to work as digital nomad until you get permanent residence (unless you are European citizen) card and can be self employed.

Finally …

Not a long topic to have a headline for, but there are more job opportunities in the Netherlands than Portugal, although for expats there are more options to get work visas in Portugal than the Netherlands. You can also see people immigrating from Portugal to the Netherlands for work, despite that weather in the Netherlands is horrible. Most of the time it is rainy or dark, not as much as in Scandinavian countries, but still for people like me it is annoying. But if the weather is good, it is really beautiful. 

Now we come to the end. I would not like to go into details about comparing life costs because you can easily find them on the internet. I hope that what I shared was useful for you and do not forget that everybody sees things from what he/she has experienced. I admit that I might be biased, but this is how humans are. 

How to use Docker, EngineX and Redis to load balanace aspnet core

Load-balancing is one of those topics in system architecture that has not been easy ever since the scaling the application became a concern for solution architectures. I have always wanted to implemented a load balanced aspnet application in project that I was experiencing, either as developer or team leader.

I never give up about learning the topic and recently I read some good articles. After I could run the suggested solutions, I though be me it is not a bad idea to compile those article into a vide tutorial. There you go :

Load-balance aspcore applications using Docker, Redis and Nginx

How to create a regular backup job for SQL Server Express

Having a regular backup of your database is vital. In SQL Server, there is a feature called “Agent services” that help you create a regular job to clean up the database, do some operations periodically or backup your database. But if you use SQL express, this feature is not available there. So how can you create a backup which runs in an interval during the day?

First, you need a backup script. I found one on the internet (sorry I forgot the source) and changed it a little bit.  Here is the script :

DECLARE @path VARCHAR(500)
DECLARE @name VARCHAR(500)
DECLARE @pathwithname VARCHAR(500)
DECLARE @time DATETIME
DECLARE @year VARCHAR(4)
DECLARE @month VARCHAR(2)
DECLARE @day VARCHAR(2)
DECLARE @hour VARCHAR(2)
DECLARE @minute VARCHAR(2)
DECLARE @second VARCHAR(2)

-- 1. Getting the time values

SELECT @time   = GETDATE()
SELECT @year   = (SELECT CONVERT(VARCHAR(4), DATEPART(yy, @time)))
SELECT @month  = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(mm,@time),'00')))
SELECT @day    = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(dd,@time),'00')))
SELECT @hour   = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(hh,@time),'00')))
SELECT @minute = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(mi,@time),'00')))
SELECT @second = (SELECT CONVERT(VARCHAR(2), FORMAT(DATEPART(ss,@time),'00')))

-- 2. Defining the filename format

SELECT @name ='Backup' + '_' + @year + @month + @day + @hour + @minute + @second

SET @pathwithname = @name + '.bak'

-- 3. Run the Back up script 

BACKUP DATABASE [DatabaseNameToBackUp] TO  DISK = @pathwithname WITH  RETAINDAYS = 10, NOFORMAT, NOINIT,  NAME = N'PodcastDatabase-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO

What the script does, is that it creates a backup for a database you want, but for naming the back up file, it uses the current date time and appends them to the file name.

To run and see if it works, you can run the following command in CMD :

"\....\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\SQLCMD.EXE" -S server\sqlexpress -i "C:\backup.sql"

So the tool which we need here is “SQLCMD” and it is located under Tools\binn folder in the installation path of SQL server express. It requires two parameters, the SQL server instance, and the path of the script to run.

The next step would be run it automatically. Run the “Task Scheduler” application in windows and click on the “Create a basic Task”. Define a name for and and go to next step.

Now you need to setup the trigger condition, daily, weekly or etc.

When you reach to action step, choose “Start Program” and click next. In the dialog box, write the path to “SQLCMD” and in “Add Argument” section, write

-S server\sqlexpress -i "C:\backup.sql"

That is it !

Real-time collaboration in Visual studio

Almost all of us know about pair programming benefits. To name a few benefits I can say greater resiliency, fewer mistakes and bugs, Increased code quality and faster training. However it has its own downsides. For instance, working on a single initiative may seem like a waste of valuable resources. In addition, The ideal amount of time to spend pair programming seems to be around 2 to 2.5 hours. Moreover it is not always possible to do pair programming because these days the ability to work remotely made it easier for developers to work from where ever they want.

However by the feature introduced by Microsoft which is called Visual Studio Live Share, the costs and downsides of the pair programming may decrease. If you have the experience of editing of a document in Google drive with other people in real-time, you know how effective it could be. Therefore by using the Visual Studio Live Share you can collaborate with others in real-time. In fact it allows you to instantly and securely share your current project, and then as needed, share debugging sessions, terminal instances, localhost web apps, voice calls, and more.

Screenshot of Visual Studio Live Share, showing participants in a collaboration session

Create Pie Chart For Dynamics CRM using HighCharsts

Dashboards and KPI`s are those tools that every manager wants from a Business software like CRM, ERP and etc.

In a company that I develop Dynamics CRM for their based on their requirements, I was asked to create a charts for the marketing dashboard. Default chart tool in Dynamics CRM helps you easily create chat using wizard but it has drawbacks, and one the main drawbacks is that filtering the data to be displayed in chart is not as easy as creating the chart.

So after lots of search and try, I selected Highcharts to use in dashboard. In the following, I explain a sample, that shows a pie chart by lead source.

Note: All the codes here work for Dynamics CRM 2011, but it also works for 2013.

Here is the code:

<html lang="en"><head>
			<link id="sharedaddy-css" href="new_pikaday.css" rel="stylesheet" type="text/css" media="all">
	<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
    <script src="new_jquery1.6.min.js" type="text/javascript"></script>
	<script src="new_sdk.rest.js" type="text/javascript"></script>
	<script src="new_json2.js" type="text/javascript"></script>
	<script src="new_sdk.metadata.js" type="text/javascript"></script>
	<script src="new_highcharts.js" type="text/javascript"></script>
	<script src="new_moment.js" type="text/javascript"></script>
	<script src="new_pikaday.js" type="text/javascript"></script>
	<script src="new_custom_reports_common.js" type="text/javascript"></script>
	<script type="text/javascript">
		var teamusers;
		function LeadSourceDataClass()
		{
			this.Name = '';
			this.Items = [];
		}
		
		function LeadSourceDataClassItem(title, code)
		{
			this.Title = title;
			this.Code = code;
			this.Data = 0;
		}
			
		LeadSourceDataClass.prototype.reSet = function(){
			this.Items = [];
		};
				
		LeadSourceDataClass.prototype.AddToItem = function(code){
			$.each(this.Items, function(index, item)
			{
				if(item.Code == code)
				{
					item.Data += 1;
					return false;
				}
			})
		};	
		var dataObj = new LeadSourceDataClass();
		
		function generateChart()
		{
			dataObj.reSet();
			var filter = getFilter();
			var options = "$select=LeadId,LeadSourceCode&$filter=" + filter + "&$top=" + Helper.XRM.CustomReports.MaxRecords;
			SDK.Metadata.RetrieveAttribute("Lead", "LeadSourceCode", "00000000-0000-0000-0000-000000000000", true, function (result) {
				for (var i = 0; i < result.OptionSet.Options.length; i++) {
					var text = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
					var value = result.OptionSet.Options[i].Value;
					dataObj.Items.push(new LeadSourceDataClassItem(text, value));
				}
				SDK.REST.retrieveMultipleRecords("Lead", options, retrieveLeads, function (error) { console.log(error); }, retrieveLeadsCompleted);
			}, function (error) { console.log(error); })
		}
			
		function retrieveLeads(data)
		{
			$.each(data,function(index, item)
			{
				if(item.LeadSourceCode)
					if(item.LeadSourceCode.Value)
						dataObj.AddToItem(item.LeadSourceCode.Value);
			})
		}
			
		function retrieveLeadsCompleted()
		{
			var data = [];
			$.each(dataObj.Items, function(index, item)
			{
				data.push([item.Title, item.Data]);
			});
 			var series = [
				{
					type: 'pie',
					name: '',//name,
					data: data
				}
			];
			Helper.XRM.CustomReports.createPieChart('#chartcontainer', 'Leads by Source (Pie)', series, chartClickEvent, chartTooltipFunction);
		}
		
		function chartTooltipFunction()
		{
			return this.key + ': ' + this.y;
		}
		
		function chartClickEvent(event) 
		{
			
		}
		
		function getFilter()
		{
			var filter = "";
			
			
			
			
			if($('#fromPicker').val())
				filter += " and CreatedOn ge datetime'" + $('#fromPicker').val() + "T00:00:00Z'";
		    if($('#toPicker').val())
				filter += " and CreatedOn le datetime'" + $('#toPicker').val()   + "T23:59:59Z'";
			if($('#usersSelect').val())
				filter += " and CreatedBy/Id eq guid'" + $('#usersSelect').val() + "'";
			if (filter.substr(0, 5) == " and ")
				filter = filter.substr(5);
			return filter;
		}
		
		$(document).ready(function(){
			Helper.XRM.CustomReports.createDatePicker('fromPicker');
			
			Helper.XRM.CustomReports.createDatePicker('toPicker');
			
			
			$('#generateBtn').click(generateChart)
			
			
			
		});
	</script>
</head>
<body>
<div id="contentwrapper">
<div id="content" style="height: 62%;">
<div id="chartcontainer"></div>
</div>
<div id="filters">

				<a id="viewRecords" href="http://google.com" target="_blank">View Records</a>

<hr>

<table class="filtersTbl">
<thead>
<tr>
<th style="width: 25%;"></th>
<th style="width: 25%;"></th>
<th style="width: 25%;"></th>
<th style="width: 25%;"></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableLabel">From</td>
<td><input id="fromPicker" type="text"></td>
<td class="tableLabel">To</td>
<td><input id="toPicker" type="text"></td>
</tr>
<tr>
<td></td>
<td><input name="generateBtn" id="generateBtn" type="button" value="Generate"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body></html>

So let’s explain each part separately.

You see that there are bunch of scripts and a CSS file in the first. You  can add web resources to Dynamics CRM using Customization section of main settings, so I skip the part.

I use pickaday library to make it easier for user to select the date range from a calendar. To interact with Dynamics API, I use these libraries : ClientGlobalContext.js.aspx, sdk.rest.js, json2.js, sdk.metadata.js. And the most important one, is Highchart js lib that I included in my file.

In the body of the file, I have some html elements that help user fill in the filtering data such as Creation Date range.

But the main part is in script I wrote.

LeadSourceDataClass, LeadSourceDataClassItem are helper objects to hold data I retrieve from Dynamics API. LeadSourceDataClassItem contains the title of Lead Source and its Numerical Code, as in Dynamics, Option Set field types, have a title and a corresponding numerical code.

In $(document).ready method, I setup some code and configuration. The helper method XRM.CustomReports.createDatePicker … initialize and setup a field to be Calendar type. $(‘#generateBtn’).click(generateChart) Bind the click event to “generateBtn’” element.

In generateChart method, first we call Dynamics API to retrieve Lead metadata, which in this case we only wants list of defined items of Lead Source options set.  We pass each record in the form of LeadSourceDataClassItem, and save it to dataObj. After reading all options ends, we pass a method named to be called. This is the method:

SDK.REST.retrieveMultipleRecords(“Lead”, options, retrieveLeads, function (error) { console.log(error); }, retrieveLeadsCompleted)

It first method accept the Entity you want to query, second accepts the filtering for the query, third is the success call back for each loop, and the last one is called when all the loops are finished being read.

But what I mean by each loop, in above? Using Dynamics CRM API, you cannot read all items of requested Entity, but you have to read it 1000 by 1000.

In retrieveLeads method, I read each lead and if it has value for Lead source, It is being added to list. The method AddToItem, check to which Lead Source it belongs and add it to corresponding list.

I missed to explain how options variable, which we use t filter data initiated. We use a helper method called getFilter, that read Selected Date vales from date pickers and creates the filtering string according to OData standards.

In retrieveLeadsCompleted mehod, we reduce our data to be show in Pie chart. By reduce I mean, reading each Lead Source title, and sum of its data, in this case count of items. Finally I use a helper method to show charts by using Highcharts API.

Here is the helper js file:

var Helper = Helper || {};
Helper.XRM = Helper.XRM || {};
Helper.XRM.CustomReports = Helper.XRM.CustomReports || {};

Helper.XRM.CustomReports.MaxRecords = 100000;

//OptionSet Filter
Helper.XRM.CustomReports.createOptionSetSelect = function (EntityLogicalName, AttributeLogicalName, itemToAppend, addEmptyValue){
	SDK.Metadata.RetrieveAttribute(EntityLogicalName, AttributeLogicalName, "00000000-0000-0000-0000-000000000000", true, function (result) {
			if (addEmptyValue)
			    itemToAppend.append('
<option value="null">' + '(Empty)' + '</option>');
			for (var i = 0; i < result.OptionSet.Options.length; i++) {
				var text = result.OptionSet.Options[i].Label.LocalizedLabels[0].Label;
				var value = result.OptionSet.Options[i].Value;
				itemToAppend.append('
<option value=' + value + '>' + text + '</option>');
			}
		},
		function (error) { console.log(error); }
	);
}
//End OptionSet Filter
//Create Pie Chart
Helper.XRM.CustomReports.createPieChart = function (chartcontainers, title, series, clickevent, tooltipfunction)
{
	$(chartcontainers).highcharts({
		chart: {
			type: 'pie',
		},
        credits: {
            enabled: false,
        },
		exporting: {
			enabled: false,
		},
		plotOptions: {
			pie: {
				allowPointSelect: true,
				cursor: 'pointer',
				dataLabels: {
					enabled: true,
					format: '<b>{point.name}</b>: {point.percentage:.1f} %',
					style: {
						color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black',
					},
				},
				point: {
					events: {
						click: clickevent,
					},
				},
			},
		},
		series: series,
		title: {
			text: title,
		},
		tooltip: {
			formatter: tooltipfunction,
		},
	});
}
//End Create Pie Chart	

//Create A Date Picker
Helper.XRM.CustomReports.createDatePicker = function (controlname)
{
	new Pikaday({
        field: document.getElementById(controlname),
        firstDay: 1,
        format: 'YYYY-MM-DD',
        minDate: new Date('2000-01-01'),
        maxDate: new Date('2020-12-31'),
        yearRange: [2000, 2020]
	});
}
//End Create A Date Picker
//Date Calculation
Helper.XRM.CustomReports.getDefaultStartDate = function()
{
	var firstOfThisMonth = moment();
	firstOfThisMonth.set('month', moment().month());
	firstOfThisMonth.set('date', 1);
	return firstOfThisMonth.subtract(6, 'months').format("YYYY-MM-DD");
}
Helper.XRM.CustomReports.getDefaultEndDate = function()
{
	var firstOfThisMonth = moment();
	firstOfThisMonth.set('month', moment().month());
	firstOfThisMonth.set('date', 1);
	return firstOfThisMonth.subtract(1, 'days').format("YYYY-MM-DD");
}
//End Date Calculation

This is the final look of chart in  a dashboard:

dashboard

Best Regards

What am I gonna post here ?

I am a software developer, and mainly I would post about my experience with software developing, but that would not be all, I would also post about life events, my thought ….

I was  blogging in wordpress in other blog which I created when I entered university, but it has been a year that I dont update it any more. This blog in persian and contains lots of post about all most anything in IT world and was managed by me and my classmates at university.