CRM 2011

Już jest :) – wersja beta produktu, który naszym zdaniem spowoduje rewolucję :) Dla tych, którzy dopiero teraz słyszą o nowej wersji produktu mała informacja – produkt ten można pobrać po zarejestrowaniu się na stronie: http://offers.crmchoice.com/CRM2011Beta-Landing.

Pierwsze wrażenia z nowego CRM ? Przede wszystkim wygląd – podobnie jak poprzednia wersja – kolorystycznie oraz interfejsowo odpowiada pakietowi Office a dokładnie programowi Outlook. CRM 4 nawiązywał do Outlook 2007, nowa wersja do Outlook 2010. Wszędzie obecna jest wstążka, która stała się elementem, który opanowuje kolejne produkty MS.

Główne okno aplikacji wygląda następująco:

Nowy obraz (2)

Jako, iż zajmuję się CRM również z technicznego punktu widzenia postaram się opisać jakie zmiany zostały wprowadzone w jego wnętrzu, np. własność możliwa do ustawienia dla zespołu, integracja z Sharepoint, procesy, usługi CRM 2011, itd. Co warte wspomnienia na samym wstępie to fakt, iż produkt ten został całkowicie napisany w oparciu o .NET 4. Zatem przepływy, pluginy będziemy już tworzyć z wykorzystaniem najnowszych technik :) – jak dla mnie bomba :)

Wymagania odnośnie sprzętu oraz aplikacji wymaganych przez CRM 2011 opisał Kuba w tym poście: http://crmblog.pl/2010/09/10/dynamics-crm-2011-wymagania-sprzetowe-i-programowe/

Skróty klawiaturowe w VS 2010

Nowy obraz

Nie wiem jak Wy, ale dla mnie znajomość skrótów klawiaturowych w VS pozwala zaoszczędzić czas i spędzić go na produktywnym kodowaniu niż na “przeklikiwaniu się” poprzez kolejne elementy interfejsu VS.

Dla tych, którzy myślą podobnie :) Microsoft udostępnił listy skrótów klawiaturowych dla różnych języków, które dostępne są na stronie: http://www.microsoft.com/downloads/details.aspx?FamilyID=92CED922-D505-457A-8C9C-84036160639F&displaylang=en

Wdrożenia CRM razem z metodykami zwinnymi

Metodyki zwinne (Agile) takie jak SRUM, Crystal Clear jest  czymś co dopiero zaczyna święcić swoje sukcesy. Niemniej jednak, każdy projekt, który do tej porty realizowaliśmy dla klientów z różnych dziedzin, biznesów, prowadzony był z wykorzystaniem właśnie tych metodyk.

Dlaczego ? Odpowiedź jest prosta – każdy z nas jak za coś płaci chce móc jak najszybciej korzystać z produktu. Nie inaczej jest z klientami. Zwinne metodyki nie skupiają się na zdobyciu pełnej wiedzy na temat klienta (bo to nigdy nie jest możliwe), stworzeniu tony dokumentacji i dopiero (po kilku tygodniach programowania w edytorze tekstowym) rozpoczęciu prac mających na celu zrealizowanie tego za co klient zapłacił.

Zwinne metodyki stawiają sobie za cel bliską współpracę z klientem, starając się dostarczyć rozwiązanie kawałek po kawałku. Przy czym kawałki są uzależnione od klienta. Przykładowo w metodyce SCRUM po stronie klienta jest osoba (tzw. właściciel produktu), które zadaniem jest m.in. ustalenie ZI czyli zwrotu z inwestycji, tj. jeśli klient zapłacił za projekt to co jest dla niego najważniejsze, co należy klientowi przestawić w pierwszej kolejności, aby klient mógł tak naprawdę zacząć pracować z systemem, który jest dla niego tworzony, myśląc o ewentualnych zmianach w tym co otrzymał (o tak – zmiany możliwe są zawsze i wszędzie a nie wtedy kiedy system zostanie wdrożony na podstawie tony dokumentacji) oraz o kolejnych priorytetowych funkcjonalnościach, które chciałby mieć.

Dlaczego o tym piszę ? Dlatego, że coraz więcej firm (szczególnie klientów) zauważa zyski z zastosowania takiej metodyki – jest to super sytuacja kiedy starasz się przekonać klienta, który przyzwyczajony jest do długiego czekania i stosu dokumentów zanim zobaczy to czego oczekiwał od systemu. Teraz będzie dla nas to coraz łatwiejsze i miejmy nadzieję, że rysunki takie jak te przestaną obowiązywać :)

Wdrożenie CRM to nie wdrożenie narzędzia, bo CRM to nie jest narzędzie. Klient, do którego jedziemy nie został zapisany w KRS dzień przed naszym spotkaniem. Jego organizacja istnieje już jakiś czas, wie jak zarządzać klientami, ma strategię tego jak chce nimi zarządzać. CRM to narzędzie, którego zadaniem jest wspieranie istniejącego biznesu, wspieranie strategii pracy z klientem. Dlatego ważne jest bycie blisko klienta i szybkiego reagowania na jego potrzeby, aby nie doprowadzić do powstania karuzeli z rysunku :)

Oj będzie się działo na rynku CRM :) – co ja mówię – już się dzieje – tylko, że nie wszyscy to widzą – bo mają stos dokumentacji do napisania/przeczytania/zweryfikowania/zaimplementowania (jak zwał tak zwał :) ).

CRM 4.0 Outlook Client – proces synchronizacji

Czy zastanawialiście się co tak naprawdę dzieje się pod maską narzędzia, który integruje Outlook z CRM 4.0 ?

Na stronach Microsoft jest udostępniony dokument, który opisuje co jest synchronizowane pomiędzy CRM a Outlook – nie w postaci takiej, że “Terminy, Zadania, itp. są synchronizowane”, ale znajdziemy tam opis wszystkich atrybutów, które są brane pod uwagę w czasie synchronizacji. Nie wiem jak wam, ale dla mnie jest to bardzo cenna wiedza, której do tej pory w pełni nie posiadałem :)

Tutaj jest link do tego dokumentu: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=2d497348-0a10-40ce-8edb-b0ee85f1215e

CRM 4.0 - Znikające terminy w Outlook

W większości firm Outlook jest strategicznym narzędziem pracy handlowców. To tam rejestrowane jest to co handlowiec robi, z kim się spotyka, itd.

Po wdrożeniu CRM w organizacji zazwyczaj instalowany jest na większości komputerów dodatek do programu Outlook, który pozwala na pracę w CRM w oknie outlook, śledzenie elementów outlookowych bezpośrednio w CRM. Wśród takich elementów jest oczywiście zaproszenie na spotkanie. Jednakże z tym elementem jest bardzo dużo problemów, gdyż w CRM 4.0 nie ma czegoś takiego jak zaproszenie na spotkanie. Prześledźmy następujący scenariusz:

  1. Użytkownik CRM (nazwijmy go Organizator 1) tworzy zaproszenie na spotkanie i wysyła go do użytkownika (nazwijmy go Handlowiec 1). Zaproszenie to nie jest śledzone w CRM.
  2. Handlowiec 1 dostaje zaproszenie, wybiera opcję “Śledź w programie CRM”. Powoduje to powstanie w CRM rekordu Termin, gdzie Właścicielem jest Handlowiec 1, natomiast Organizatorem jest Organizator 1.
    1. Jeśli w CRM Handlowiec 1 miał ustawiony adres email to po otwarciu terminu w CRM w polu wymagani uczestnicy zostanie zaprezentowane wskazanie na użytkownika. W tym przypadku po przeprowadzeniu synchronizacji w programie Outlook (CRM –> Synchronizuj z CRM) termin nie zniknie z kalendarza użytkownika w Outlook
    2. Jeśli w CRM Handlowiec 1 nie miał ustawionego adresu email to po otwarciu terminu w CRM w polu wymaganie uczestniczy widoczny będzie czerwony adres email z informację, że system CRM nie był w stanie rozpoznać uczestnika. W tym przypadku po przeprowadzeniu synchronizacji termin w kalendarzu w Outlook zostanie usunięty. Jedyna możliwość przywrócenia tego terminu do kalendarza Outlook jest wykonanie operacji:
      1. Otwarcie rekordu użytkownika i uzupełnienie mu adresu email
      2. Otwarcie terminu w CRM i wskazanie jaki użytkownik krył się pod tym adresem email
      3. Przeprowadzenie ponownej synchronizacji w Outlook.

Zachęcam do przeprowadzenia testów kiedy zaproszenie jest wysyłane do większej liczby użytkowników niż jeden :). Kilka scenariuszy przeprowadził Kuba i opisał to na swoim blogu: http://crmblog.pl/2009/09/17/co-dzieje-sie-z-rekordami-po-synchronizacji-crm-outlook/

SetParent – czyli jak napisać plugin do tej wiadomości

Przy okazji rozbudowania funkcjonalności CRM4.0 potrzebowałem napisać plugin, którego zadaniem będzie wykonanie pewnej operacji w trakcie kiedy zmieni się Menedżer użytkownika.

Dla przypomnienia: Pole Menedżer jest widoczne na formatce użytkownika jednakże ustawienie jego wartości jest możliwe tylko i wyłączenie poprzez skorzystanie z funkcjonalności ukrytej w menu Akcje lub też wykonanie kodu związane z klasą SetParentSystemUserRequest:

image

Okazuje się, że narzędzie Plugin Registration Tool (PRT) nie udostępnia nam możliwości podłączenia się pod zdarzenie związane ze zmianą interesującego nas pola. Interesujące nas wiadomości nazywa się SetParent.

Nie ma jednak tego ukrytego co by odkryte może zostać i okazuje się, że w bazie danych CRM taką wiadomość można odkryć. Jak ?

Wszystkie wiadomości jakie CRM może przetwarzać są zapisane w tabeli SdkMessageBase. Jak wykonamy sobie następujące zapytanie SQL:

select * from SdkMessageBase where Name = 'SetParent'

Zobaczymy, że tabela zwróci nam jeden rekord. To co jest dla nas z tego wyniku najważniejsze to SdkMessageId. W kolejnym kroku musimy zaktualizować jedną kolumnę w tabeli SdkMessageFilterBase, aby wiadomość nam się pokazała. Całe zapytanie, które to wykonuje jest następujące:

update SdkMessageFilterBase set IsCustomProcessingStepAllowed =1 where SdkMessageId = '1ABEBB1B-EA3E-DB11-86A7-000A3A5473E8'

Jak już to będziemy mieli wykonane nie pozostaje nam nic innego jak przeładować PRT i ponownie spróbować stworzyć Step, które będzie powiązany z tą wiadomością:

image

Jak wygląda kod obsługi tej wiadomości  ? Oto przykład:


public class PreSetParent : IPlugin
{
public void Execute(IPluginExecutionContext context)
{
if (context.MessageName == "SetParent" && context.InputParameters.Properties.Contains(Attributes.UserId) && context.InputParameters.Properties.Contains(Attributes.ParentId))
{
Guid _userId = (Guid)context.InputParameters[Attributes.UserId];
Guid _parentId = (Guid)context.InputParameters[Attributes.ParentId];
}
}
}


InputParameters w IPluginExecutionContext zawiera w tym przypadku 4 właściwości. UserId oraz ParentId są odpowiednią identyfikatorem użytkownika oraz identyfikatorem Menedżera. Inne atrybuty można sobie podejrzeć debugując kod pluginu.



Rozwiązanie, które zaproponowałem jest w 100% niewspierane i korzystacie z niego na własną odpowiedzialność.

Jacy użytkownicy mają przypisaną rolę “Test” ? - Kawałek kodu dla CRM

Dzisiaj postanowiłem zamieścić prosty kawałek kodu, który pobiera użytkowników, którzy w CRM mają przypisaną wskazaną rolę, nazwijmy ją Test. Kawałek kodu metody, która dokonuje takowej eksploracji wygląda następująco:

private systemuser GetSystemUserInRole(string rolename, CrmService serv)
        {

            QueryExpression qe = new QueryExpression();
            qe.EntityName = EntityName.systemuser.ToString();
            qe.ColumnSet = new AllColumns();

            LinkEntity le = new LinkEntity();
            le.LinkFromEntityName = "systemuser";
            le.LinkFromAttributeName = "systemuserid";
            le.LinkToEntityName = "systemuserroles";
            le.LinkToAttributeName = "systemuserid";

            ConditionExpression ce = new ConditionExpression();
            ce.AttributeName = "name";
            ce.Operator = ConditionOperator.Equal;
            ce.Values = new object[] { rolename };

            LinkEntity le2 = new LinkEntity();
            le2.LinkFromEntityName = "systemuserroles";
            le2.LinkFromAttributeName = "roleid";
            le2.LinkToEntityName = EntityName.role.ToString();
            le2.LinkToAttributeName = "roleid";

            le2.LinkCriteria = new FilterExpression();
            le2.LinkCriteria.Conditions = new ConditionExpression[] { ce };

            le.LinkEntities = new LinkEntity[] { le2 };
            qe.LinkEntities = new LinkEntity[] { le };

W wyniku pobrania obiektów spełniających kryteria zapytania dostaniemy kolekcję obiektów typu systemuser, z którą wiemy już co zrobić :)