Tag Archive for: Dynamics og Power Platform

GDPR – Klikk på Dimensjoner

Bli klar for GDPR før ferien med ClickDimensions

Tidlig i mai kom ClickDimensions ut med en oppdatering som heter 9.2.0 eller GDPR-oppdateringen. I dette innlegget vil jeg skrive litt om hvilke nye funksjoner i denne oppdateringen som hjelper deg med å følge GDPR-regelverket.

GDPR

Ikke hørt om GDPR? –Datatilsynet skriver: «EUs forordning for personvern, The General Data Protection Regulation (GDPR), blir norsk lov i 2018. Det betyr at vi får nye regler for personvern i Norge. Det nye regelverket gir virksomheter nye plikter og enkeltpersoner nye rettigheter.» Les deres veileder. (https://www.datatilsynet.no/regelverk-og-skjema/veiledere/hva-betyr/)

Påmeldingslister og sider for påmelding

Du har fem nyhetsbrev og en kunde er påmeldt alle fem, men ønsker å melde seg av 1 av dem, da er det ganske upraktisk å kun ha en funksjon som melder kunden av alt. Global avmelding er upraktisk, men er ofte brukt. Skal du følge GDPR må abonnentene dine ha muligheter til å melde seg av nyhetsbrev og annen informasjon, men hvorfor ikke spørre kunden hva de ønsker å melde seg av. Når de klikker i en lenke fra en e-post vet ClickDimensions informasjon om abonnenten og kan fylle ut info, slik at abonnenten bare oppdaterer sin informasjon, de slipper å fylle ut alt selv.
Funksjonen for å ha abonnementslister har ClickDimensions hatt lenge, men nå kan du også benytte disse listene for SMS-utsendelser.

data table
Bilde 1: Påmeldingslister

Du kan selvsagt også lage egne sider hvor abonnenter kan melde seg på, som du kan legge på dine nettsider, eller som lenke i signaturen din i e-posten. Samme type sider benyttes for avmelding, husk da alltid å gi tilbudet om å melde seg av alt.

data
Bilde 2: Sider for påmelding

Opt-in subscription management

Tidligere ble alle e-poster du ønsket, bortsett fra de som hadde meldt seg av, sendt. Denne løsningen følger ikke GDPR. ClickDimensions sitt svar er å lage en ny versjon som kun sender e-post til de som aktivt har meldt seg på abonnement. Når du aktiverer denne funksjonen vil det kun sendes ut e-post til dem som har gitt et aktivt samtykke – helt i tråd med GDPR.

Subscriptions
Bilde 3: Opt-in subscription management

Kampanjeautomatisering

Alle påmeldinger og avmeldinger blir selvsagt automatisk oppdatert med kampanjeautomatiseringen. Husk å endre denne etter at du har skiftet til opt-in subscription management slik at den er knyttet opp til riktig påmeldingslister og e-postutsendelser.

flowchart
Bilde 4: Kampanjeautomatisering

Transaksjonsbaserte utsendelser

Når du har slått på opt-in subscription management vil kun e-poster bli sendt til dem som har meldt seg på, men hva om du skal sende en automatisk bekreftelse på f.eks. påmelding til kurs, eller en evaluering? Da bruker du det nye feltet transaksjonsbasert utsendelse.

table
Bilde 5: Transaksjonsbaserte utsendelser

Hurtigutsendelser

Når du har slått på opt-in subscription management vil kun e-poster bli sendt til dem som har meldt seg på, men hva om du skal sende en automatisk bekreftelse på f.eks. påmelding til kurs, eller en evaluering? Da bruker du det nye feltet transaksjonsbasert utsendelse.

data table
Bilde 6: Hurtigutsendelser

Oppdater sporingen på hjemmesiden Med ClickDimensions kan du spore trafikk fra din hjemmeside, med den nye metoden fra sist oppdatering kan kundene velge å ikke bli sporet. Man må klikke ok, eller klikke at man ikke ønsker å bli sporet.

confirmation
Bilde 7: Sporing på web

Trenger du bistand til å forstå GDPR og få en bedre kontroll på ClickDimensions og markedsføring?
Ta kontakt med Knut Skogvold på telefon 90 09 50 88 eller e-post for en uforpliktende dialog om muligheter

Microsoft Teams - FirstPlugin

Writing your first plugin in less than 1 hour

Dynamics 365 – Customer engagement

Before you start, you should know that I am not a developer. I can’t answer questions about development directly. This is intended for functional consultants that want to be able to make simple plugins without any developer knowledge.

Scenario:

FirstPlugin1

I have an opportunity with a custom product table connected. I need the value of the product lines to synchronously sum up to the Opportunity when I hit save. Pretty much the same you would expect when you use the out of the box product entity.

Prerequisites:

Create a new trial for Dynamics 365 (https://trials.dynamics.com/ ). There are several ways to do this, but the link should work fine. Then download the Community Edition of Visual Studio (free in most cases, but be sure to read the license requirements). https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15 Under the installation just click next next etc. The first time you need to perform a choice is here:

FirstPlugin2

Make sure you choose the .net desktop checkbox. Then continue to click next next and wait until you are done.
Next create a folder on c:/ I created one called D365Tools

FirstPlugin3

Now open PowerShell and navigate to folder
Then open the URL: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/download-tools-nuget
Navigate to ths script part futher down the page, and copy the whole text. Use the Copy button in the top right corner

FirstPlugin5

Paste the whole script to PowerShell (below is just a part of the code). Hit enter and let it finish.

FirstPlugin6

When it is done, your folder should look like this:
We will be using the PluginRegistration and CoreTools later. Just in case, we will download the SDK framework 4.6.2 developer pack:
https://www.microsoft.com/net/download/visual-studio-sdks

FirstPlugin8

Just hit next next until done.

Visual Studio

FirstPlugin9
FirstPlugin10

We are now ready to open visual studio and start a new project.
Make sure you choose Class Library (.Net Framework), and then choose the .net 4.6.2 in the bottom left. I have chosen a path in my documents for storing the code. Just choose any location you want.
Now copy paste the following code:

using System;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;
using CrmEarlyBound;
using System.Linq;
using Microsoft.Xrm.Sdk.Client;
namespace SumProduktLinjer
{
public class SumProduktlinjer : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
OrganizationServiceContext orgContext = new OrganizationServiceContext(service);
//This will give us the chance to log information to CRM so we can see what happens in the plugin
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
//This will check to see that a plugin has fired on an entity. This is where we end up on create and update.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
//Getting the actual entity. DO NOT CHANGE THE Image name here if you follow the guide.
Entity ProductLinePostImage = (Entity)context.PostEntityImages["Image"];
//Then i just check if the entity has a field called "ncg_salgsmulighetid" relationship to oppty you don't need this
if (ProductLinePostImage.Attributes.ContainsKey("ncg_salgsmulighetid"))
{
//Creating reference to the oppty
EntityReference ParentOpptyRefPost = (EntityReference)ProductLinePostImage.Attributes["ncg_salgsmulighetid"];
//Calling the search for product lines while expecting a decimal (total value) as return.
Decimal TotalProductLines = ProductLinesFetch(ParentOpptyRefPost, orgContext, tracingService);
//the same way you use alerts in javascript, you can use tracing service below.
//tracingService.Trace(TotalProduktLines);
//or
//tracingService.Trace("Totalprislinjer fra Fetch: {0}", TotalProduktLinjer);
//Convert the desimal to a Money field
Money TotalproduktlinjerMoney = new Money(TotalProductLines);
//Create a new entity "object" in CRM. Use the GUID from the Post Image. And then use the total Money variable
//to update the estimated value of the opportunity you want to update.
Entity ParentOpptyUpdate = new Entity("opportunity");
ParentOpptyUpdate.Id = ParentOpptyRefPost.Id;
ParentOpptyUpdate.Attributes["estimatedvalue"] = TotalproduktlinjerMoney;
//When done defining what to update, we trigger the actual update to the parent
service.Update(ParentOpptyUpdate);
}
}else
{
//This code will run when you delete a product line. Same check here to see if field exists
Entity PreProduktLinjer = (Entity)context.PreEntityImages["Image"];
if (PreProduktLinjer.Attributes.ContainsKey("ncg_salgsmulighetid"))
{
//Creating a reference to the parent "opportunity"
EntityReference ParentOpptyRefPre = (EntityReference)PreProduktLinjer.Attributes["ncg_salgsmulighetid"];
//Calling the search for product lines while expecting a decimal (total value) as return.
Decimal TotalProduktLinjer = ProductLinesFetch(ParentOpptyRefPre, orgContext, tracingService);
//Converting the result from our search to the Money we need.
Money TotalproduktlinjerMoney = new Money(TotalProduktLinjer);
//Create a new entity "object" in CRM. Use the GUID from the Post Image. And then use the total Money variable
//to update the estimated value of the opportunity you want to update.
Entity ParentOpptyUpdate = new Entity("opportunity");
ParentOpptyUpdate.Id = ParentOpptyRefPre.Id;
ParentOpptyUpdate.Attributes["estimatedvalue"] = TotalproduktlinjerMoney;
//When done defining what to update, we trigger the actual update to the parent
service.Update(ParentOpptyUpdate);
}
}
}
//This is the search function.
public Decimal ProductLinesFetch(EntityReference OpportunityRef, OrganizationServiceContext orgContext, ITracingService trace)
{
Decimal SumProductLines = 0;
//A lot like the advanced find. We start out by saying we are searching for the product line eneity.
//Then we say that filter is where product line opporutunity GUID is the one we want to update against.
IQueryable ProductLineQuery = orgContext.CreateQuery();
List listOfProductLines = ProductLineQuery.Where(p => p.ncg_SalgsmulighetId.Id == OpportunityRef.Id).ToList();
//then we loop through and add all of the lines to the SumProductLines before we return it.
foreach (var productLine in listOfProductLines)
{
SumProductLines += productLine.ncg_Pris.Value;
}
return SumProductLines;
}
}

Next, we add a reference to the SDK. Navigate to the folder we created and ran the PowerShell Script

FirstPlugin11
FirstPlugin12

Open browse
Find your folder for CoreTools and then choose the Microsoft.Xrm.Sdk.dll

FirstPlugin13
FirstPlugin14

Click OK, and you should now see lots of the RED errors disappear.
Next thing we need to do is add something called ProxyClasses. I am not sure how to explain this, but it is a list of all fields and available options on each entity we are working with.

XRMToolbox

Download XRM toolbox if you don’t already have it.
https://www.xrmtoolbox.com/ Install the Early Bound Generator

FirstPlugin15

Connect to the organization and open the Early Bound Generator. We only need 2 entities, so move all of the other ones over to the right.

FirstPlugin16

Click create entities

FirstPlugin17

Then open the option set.
Click “Create OptionSets”

FirstPlugin18

Open the file location by choosing the option set relative path browse button.

FirstPlugin19

Copy these files into a folder you call ProxyClasses in your project.
Add the folder ProxyClasses to the project

FirstPlugin22

There should not be any more red errors in your code. If you have followed this correctly, it should all be ok.

FirstPlugin23

Editing the code

Now we must edit the code. What you need to replace is the names of fields and entities if you are not using the same names as me. Look for the “ncg_salgsmulighetid”. This is the lookup on my custom product table linking to the opportunity.
Then we need to fix the query.

FirstPlugin24

Here you have to change the “ncg_produktlinje” to the entity you created as a child to oppty, and the “p.ncg_salgsmulighetId.Id”. It might be case sensitive here, so try and use the Schema name in the config.

FirstPlugin25

Getting confused? Don’t worry, it makes perfect sense once you know what to look for? Just remember that I chose to use a new entity called “ncg_produktlinje”, and you will probably name it something else. The rest is just changing out the lookup value to opportunity from the child entity.
Now that the code has been done, there is one last thing we need to do before installing to Dynamics 365

FirstPlugin26

Open properties in the project
Choose Signing

FirstPlugin27
FirstPlugin28

Choose sign the assembly and new. Write something and choose a password. Click OK when you are done.
Now we can build the solution (right click on project or hit F6)

FirstPlugin29

In the bottom of the screen you should see something like this:

FirstPlugin30

Registering the plugin

Open the tools you downloaded earlier in the guide

FirstPlugin31

Create a new connection and connect to your CRM system. In the list of organizations. Choose the one you have created the entities for.

FirstPlugin32
FirstPlugin32

Browse

FirstPlugin34

Now locate the plugin you created as .dll file. Open your project in file explorer, and you will find a bin/Debug folder. Here you should find the DLL. In my case it was “SumProduktLinjer.dll”.

FirstPlugin35

Now hit register plugin. When done, click close. You can now refresh the view to see the plugin.
The next thing we need to do is register steps and images for Create/Update/Delete. The step is a definition of when it should fire, and the image is a definition of what the product line looks like before or after the actual save to the database. If you don’t understand what I mean, just copy what I do.
Create:

FirstPlugin36
FirstPlugin37

Register the step, and then we create an Image

FirstPlugin38
FirstPlugin39

Make sure you choose Post Image, because on the create there is no Pre. The record doesn’t exist yet. If you wonder why I call it image here? It is because our code refers to this as image.

FirstPlugin40

Now we have to do the same for Update and Delete.

FirstPlugin41
FirstPlugin42
FirstPlugin43
FirstPlugin44

IMPORTANT Delete command does not use post image. Only PRE image

FirstPlugin45

The reason is that there is nothing there after the delete. Therefore, we have to see what the value was before the delete was done in the database.
The result should be something like this:

FirstPlugin46

3 steps and 3 images.

The final result

Create new opportunity and hit save. Now add a new product from the new product subgrid

FirstPlugin47

(this is quick create in Norwegian)

FirstPlugin48

After you save, refresh the opportunity

FirstPlugin49

In the upper right-hand corner (Estimated revenue) is now 100 nok? NB!! Remember that there is a setting for opportunity that is either system calculated, or user defined for Estimated Revenue. Make sure it is user defined.
If you get any other errors, you need to look at the attribute names in your code. Make sure they are 100% correct, and that they might be case sensitive in the query.
Congratulations. You have now created the first plugin.

GDPR Cookie Consent with Real Cookie Banner