CRM Yazılım Deneyimleri

Crm 2011 ile gelen yeni özelliklerden biri Field Level Security‘dir. 4.0′da Javascript ve Ajax ile yaptığımız alan bazlı güvenlik uzun süredir bekleniyordu. Crm 2011 ile gelen bu özellik sadece yeni açtığımız alanlar için yapılabilmektedir. Sistem alanları için bu özellik kullanılamamaktadır. Tabii bu özelliğin kullanılması için System Admin rolüne sahip olmaması gerekiyor. Sistemin oluşturduğu ve değiştirilemeyen System Administrator Field Level Security ayarı yeni yarattığımız Field Level Security ayarını ezmektedir.

Firma(account) üzerindeki VIP Customer(new_vipcustomer) alanı için alan bazlı güvenlik yapmaya çalışalım. Fatma Uzunöz kullanıcısı Ceo-Business Manager rolüne sahiptir.

Eklenen yeni alanın Field Level Security özelliğini Enabled olarak seçmemiz gerekir. Enabled ettiğimizde alanın labelının yanında anahtar simgesi gelmektedir.

fieldlevelsecurity

Settings–>Customizations bölümünden yeni bir Field Level Security kuralı belirleyeceğimiz ekran gelmektedir.
fieldlevelsecurity

Field Level SecurityEnabled olan tüm alanlar burada listelenecektir. VIPCustomer kaydını açıyoruz ve buradan hangi işlemleri yapabileceğini belirleyebiliyoruz.

Read,Update,Create işlemleri için kısıtlama yapabiliyoruz. Eğer bu alan için hiç bir işlem yapmasın istiyorsak üçünü de No seçmemiz gerekir.

fieldlevelsecurity

Read,Update,Create işlemlerinin hiçbirine yetkisi olmayan kullanıcı alanı aşağıdaki şekilde görür.
fieldlevelsecurity

Sadece Read okuma hakkı vermek istediğimizde Allow Read alanını Yes yapmamız gerekir.
fieldlevelsecurity

Sadece Read okuma hakkı olan kullanıcı kayıdı açtığında alanın değerini görür ancak değiştiremez.
fieldlevelsecurity

Read,Update için Yes Create için No seçelim.

fieldlevelsecurity

Read, Update hakkı olup Create hakkı olmadığında varolan bir kayıdı açtığında VIP Customer üzerinde var olan bilgiyi okuma, değiştirme işlemlerini yapabilmektedir.
fieldlevelsecurity

Read, Update hakkı olup Create hakkı olmadığı için Yeni bir Firma oluşturduğunda VIP Customer üzerinde bir değişiklik yapamayacaktır.
fieldlevelsecurity

Read, Update, Create hakkını Yes olarak belirleyelim.

fieldlevelsecurity

Read, Update, Create hakkı olan kullanıcı VIP Customer alanı üzerinde tüm değişiklikleri yapabilir.

fieldlevelsecurity

Crm 4.0′da iki kayıt arasında N:N ilişki kurarak işlemler yapabiliriz. Mesela bir Eğitim(new_egitim) birden fazla Katılımcısı(systemuser) ve bir Katılımcının birden fazla Eğitime katıldığını düşünelim. Burada Eğitim(new_egitim) ile Katılımcı(systemuser) arasında N:N ilişki kurmamız gerekiyor. N:N ilişki sistemde ayrı bir tablo olarak tutulmaktadır. Burada new_new_egitim_systemuser adında bir tablo oluştuğunu veritabanından görebilirsiniz. Bazı durumlarda N:N ilişki kurulan bu kayıtlar oluştuğunda işlem yapmamız gerekebilir. Eğitime bir katılımcı eklediğimizde eğitim üzerindeki Katılımcı Varmı? bit alanı true yapan ve Eğitime ekli Katılımcı kaydı silindiğinde de Katılımcı Var mı? bit alanını false yapan kodu yazmayı deneyelim. Öncelikle ilk karşılaşacağımız sorun bunu yazacağımız Plugin’in mesajını Plugin Registration Tool’da göremememizdir. Bu sorunu nasıl aşacağımızı Plugin Registeration Tool’da olmayan Mesajlar ile Pluginde Nasıl İşlem Yapılır? makalesini inceleyerek öğrenebilirsiniz. N:N kayıt oluştuğunda plugin yazmak için AssociateEntities mesajını kullanmamız gerekir. N:N kayıt silindiğinde plugin yazmak için DisAssociateEntities mesajını kullanmamız gerekir. Associateentities’e ve Disassociateentities’e plugin yazmak için aşağıdaki gibi step eklememiz gerekmektedir.

Burada ekleyeceğimiz dll’e yazacağımız kod önemlidir. Çünkü step eklerken entity seçmediğimiz için (N:N tablo adı entity olarak gözükmemektedir.) yazdığımız plugin N:N ilişki kurulan her kayıt için çalışacaktır. Kodda sadece istenilen N:N ilişkinin adı kontrol edilmelidir.

AssociateEntities ve DisAssociateEntities mesajları ile işlem yapıldığında context’ten Moniker1, Moniker2, RelationshipName, OptionalParameter nesneleri gelmektedir. Burada Eğitim üzerine Katılımcı eklerken plugin yazdığım için Moniker1 new_egitim, Moniker2 systemuser entitylerini içerir. Burada RelationshipName ile N:N ilişkinin adını kontrol ederek her N:N ilişki için çalışmasını engelleyebiliriz.

Plugin registration toolda AssociateEntities mesajı için Step eklerken aşağıdaki gibi entity seçmiyoruz.

 associateentities,disassociateentities

Plugin registration toolda DisAssociateEntities mesajı için Step eklerken aşağıdaki gibi entity seçmiyoruz.
associateentities,disassociateentities

Eğitime katılımcı eklendiğinde Eğitim üzerindeki alanı true yapan kod aşağıda şekildedir.

public void Execute(IPluginExecutionContext context)
{
if (context.InputParameters.Properties.Contains(“RelationshipName“)
&& context.InputParameters.Properties[
"RelationshipName"].ToString() == “new_new_egitim_systemuser“)
{
ICrmService _service = context.CreateCrmService(true);

Moniker egitimMoniker = (Moniker)context.InputParameters.Properties["Moniker1"];
Moniker kullaniciMoniker = (Moniker)context.InputParameters.Properties["Moniker2"];

Guid id = egitimMoniker.Id;

DynamicEntity entity = newDynamicEntity();
entity.Name = “new_egitim”;

KeyProperty idProperty = newKeyProperty(“new_egitimid”, newKey(id));
entity.Properties.Add(idProperty);

CrmBooleanProperty flagProperty = newCrmBooleanProperty();
flagProperty.Name = “new_kullanicivarmi”;
flagProperty.Value = newCrmBoolean();
flagProperty.Value.Value = true;
entity.Properties.Add(flagProperty);

_service.Update(entity);
}
}

Eğitime katılımcı ekleyelim.

associateentities,disassociateentities

Kayıt refresh edildikten sonra Katılımcı Var mı alanı Evet olarak işaretlendiğini görebilirsiniz.

associateentities,disassociateentities

Eğitime ekli katılımcı kaydı silindiğinde Eğitim üzerindeki alanı false yapan kod aşağıda şekildedir.

public void Execute(IPluginExecutionContext context)
{
if (context.InputParameters.Properties.Contains(“RelationshipName“)
&& context.InputParameters.Properties["RelationshipName"].ToString() == “new_new_egitim_systemuser”)
{

ICrmService _service = context.CreateCrmService(true);

Moniker egitimMoniker = (Moniker)context.InputParameters.Properties["Moniker1"];

Moniker kullaniciMoniker = (Moniker)context.InputParameters.Properties["Moniker2"];

Guid id = egitimMoniker.Id;

DynamicEntity entity = new DynamicEntity();

entity.Name = “new_egitim”;

KeyProperty idProperty = new KeyProperty(“new_egitimid”, new Key(id));
entity.Properties.Add(idProperty);

CrmBooleanProperty flagProperty = new CrmBooleanProperty();
flagProperty.Name = “new_kullanicivarmi”;
flagProperty.Value = new CrmBoolean();
flagProperty.Value.Value = false;

entity.Properties.Add(flagProperty);

_service.Update(entity);
}
}

Kayıt refresh edildikten sonra Katılımcı Var mı alanı Hayır olarak işaretlendiğini görebilirsiniz.

associateentities,disassociateentities

Partnerlara sunulan Crm 2011 Virtual HardDisk(vhd) ile nasıl Virtual Machine(vmc) hazırlayacağımızı inceleyeceğiz. Öncelikle verilen linkten indirilen zip soyaları yine aynı linkten indirilen exe ile birleştirilip vhd dosyasını oluşturuyoruz. Bu arada  Crm 2011 vpc hazırlamak biraz zahmet gerektiriyor. i5 işlemcili, 3Gb ram 64 bit laptopta iyi bir performansla çalıştığını söylemeyeceğim. Vpc için 1.400′ün üzerinde ram ayarı yapılması çalışma için daha sağlıklı olacaktır.

Windows 2008(64 bit) işletim sistemi ile virtual pc hazırlamak için programı aşağıdaki linkten indirmeniz gerekiyor.

http://www.virtualbox.org/wiki/Downloads  virtualbox programını indiriyoruz. Exe’yi çalıştıralım.

Ekrana Sanal Makina Oluşturma Sihirbazı gelmektedir. İleri ile devam ediyoruz.

VirtualBox

Vpc2mize bir ad veriyoruz ve hangi işletim sistemi ile çalışacağını belirliyoruz. Crm 2011 için 64 bit Windows 2008 server gerekiyor.

VirtualBox

Vpc için bilgisayarda ayrılabilecek ram düzeyini belirliyoruz.

VirtualBox

Crm 2011′in partnerlara vermiş olduğu linkten indirdiğimiz vhd dosyasının konumu belirtiyoruz.

VirtualBox

VirtualBox varsayıkan olarak  Vhd’yi SataController olarak ayarlar ancak Hyper-V Ide controller Vhd oluşturduğu için aşağıdaki düzeltmeyi yapmamız gerekiyor.

Ayrıntılı bilgi için: http://www.avanadeblog.com/xrm/2011/06/how-to-run-the-dynamics-crm-2011-virtual-machine-on-virtualbox-.html

Sata Controller vhd’yi seçip remove ediyoruz.

VirtualBox

Kaldırdığımız Vhd’yi aşağıdaki gibi Ide Controller olarak ekliyoruz.

VirtualBox

Bu ekranda vhd dosyamızın yerini bir kez daha gösteriyoruz.

VirtualBox

Tüm ayarlardan sonra Vpc’yi başlattığımda aşağıdaki hatayı aldım. Bunun sebebi Bios ayarlarından (System Configuration altında) Virtualization Technology’nin Disabled olması. Enabled olarak değiştirdiğimde ve Vpc’yi yeniden başlattığımda hiç bir sorun olmadan Virtual Machine açıldı. bu adımlardan sonra Crm 2011 Vpc artık kullanıma hazır…

VT-x/AMD-V hardware acceleration has been enabled, but is not operational

Crm’de her varlığın her olayında plugin yazmamız mümkün değildir. Aşağıda sık kullanılan varlıklar yazılabilecek plugin mesajlarının listesi bulunmaktadır. Liste çok uzun olduğu için burada bir kısmına yer verilmiştir.

Daha detaylı bilgiyi sdk\tools\message-entity support for plug-ins.xlsx dosyasından alabilirsiniz.

Crm 2011 için SDK’yi http://www.microsoft.com/downloads/en/details.aspx?familyid=420f0f05-c226-4194-b7e1-f23ceaa83b69 linkinden indirebilirsiniz.

Varlık

Adı

Mesaj

İkinci Varlık Adı

Account RetrieveMultiple
Account RetrievePrincipalAccess
Account RetrieveSharedPrincipalsAndAccess
Account RevokeAccess
Account SetState
Account SetStateDynamicEntity
Account Update
ActivityParty RetrieveMultiple
Annotation Retrieve
Annotation RetrieveMultiple
Annotation RetrievePrincipalAccess
Annotation RetrieveSharedPrincipalsAndAccess
Annotation RevokeAccess
Annotation Update
Appointment Assign
Appointment Book
Appointment Create
Appointment CreateException
Appointment Delete
Appointment GrantAccess
Appointment Handle
Appointment ModifyAccess
Appointment Reschedule
Appointment Retrieve
Appointment RetrieveMultiple
Appointment RetrievePrincipalAccess
Appointment RetrieveSharedPrincipalsAndAccess
Appointment RevokeAccess
Appointment Route
Appointment SetState
Appointment SetStateDynamicEntity
Appointment Update
Campaign AddItem
Campaign Assign
Campaign Create
Campaign Delete
Campaign GrantAccess
Campaign ModifyAccess
Campaign RemoveItem
Campaign Retrieve
Campaign RetrieveMultiple
Campaign RetrievePrincipalAccess
Campaign RetrieveSharedPrincipalsAndAccess
Campaign RevokeAccess
Campaign SetState
Campaign SetStateDynamicEntity
Campaign Update
CampaignActivity AddItem
CampaignActivity Assign
CampaignActivity Create
CampaignActivity Delete
CampaignActivity GrantAccess
CampaignActivity Handle
CampaignActivity ModifyAccess
CampaignActivity RemoveItem
CampaignActivity Retrieve
CampaignActivity RetrieveMultiple
CampaignActivity RetrievePrincipalAccess
CampaignActivity RetrieveSharedPrincipalsAndAccess
CampaignActivity RevokeAccess
CampaignActivity Route
CampaignActivity SetState
CampaignActivity SetStateDynamicEntity
CampaignActivity Update
CampaignResponse Assign
CampaignResponse Create
CampaignResponse Delete
CampaignResponse GrantAccess
CampaignResponse Handle
CampaignResponse ModifyAccess
CampaignResponse Retrieve
CampaignResponse RetrieveMultiple
CampaignResponse RetrievePrincipalAccess
CampaignResponse RetrieveSharedPrincipalsAndAccess
CampaignResponse RevokeAccess
CampaignResponse Route
CampaignResponse SetState
CampaignResponse SetStateDynamicEntity
CampaignResponse Update
Competitor Create
Competitor Delete
Competitor Retrieve
Competitor RetrieveMultiple
Competitor Update
Connection Assign
Connection Create
Connection Delete
Connection GrantAccess
Connection ModifyAccess
Connection Retrieve
Connection RetrieveMultiple
Connection RetrievePrincipalAccess
Connection RetrieveSharedPrincipalsAndAccess
Connection RevokeAccess
Connection SetState
Connection SetStateDynamicEntity
Connection Update
Contact Assign
Contact Create
Contact Delete
Contact GrantAccess
Contact Merge
Contact ModifyAccess
Contact Retrieve
Contact RetrieveMultiple
Contact RetrievePrincipalAccess
Contact RetrieveSharedPrincipalsAndAccess
Contact RevokeAccess
Contact SetState
Contact SetStateDynamicEntity
Contact Update
Contract Assign
Contract Cancel
Contract Clone
Contract Create
Contract Delete
Contract GrantAccess
Contract ModifyAccess
Contract Retrieve
Contract RetrieveMultiple
Contract RetrievePrincipalAccess
Contract RetrieveSharedPrincipalsAndAccess
Contract RevokeAccess
Contract SetState
Contract SetStateDynamicEntity
Contract Update
CustomerRelationship Assign
CustomerRelationship Create
CustomerRelationship Delete
CustomerRelationship GrantAccess
CustomerRelationship ModifyAccess
CustomerRelationship Retrieve
CustomerRelationship RetrieveMultiple
CustomerRelationship RetrievePrincipalAccess
CustomerRelationship RetrieveSharedPrincipalsAndAccess
CustomerRelationship RevokeAccess
CustomerRelationship Update
Email Assign
Email BackgroundSend
Email CheckIncoming
Email CheckPromote
Email Create
Email Delete
Email DeliverIncoming
Email DeliverPromote
Email DetachFromQueue
Email GrantAccess
Email Handle
Email ModifyAccess
Email Retrieve
Email RetrieveMultiple
Email RetrievePrincipalAccess
Email RetrieveSharedPrincipalsAndAccess
Email RevokeAccess
Email Route
Email Send
Email SendFromTemplate
Email SetState
Email SetStateDynamicEntity
Email Update
Fax Assign
Fax Create
Fax Delete
Fax GrantAccess
Fax Handle
Fax ModifyAccess
Fax Retrieve
Fax RetrieveMultiple
Fax RetrievePrincipalAccess
Fax RetrieveSharedPrincipalsAndAccess
Fax RevokeAccess
Fax Route
Fax Send
Fax SetState
Fax SetStateDynamicEntity
Fax Update
Incident Assign
Incident Close
Incident Create
Incident Delete
Incident GrantAccess
Incident Handle
Incident ModifyAccess
Incident Retrieve
Incident RetrieveMultiple
Incident RetrievePrincipalAccess
Incident RetrieveSharedPrincipalsAndAccess
Incident RevokeAccess
Incident Route
Incident SetState
Incident SetStateDynamicEntity
Incident Update
Invoice Assign
Invoice Create
Invoice Delete
Invoice GrantAccess
Invoice LockInvoicePricing
Invoice ModifyAccess
Invoice RemoveRelated Contact
Invoice Retrieve
Invoice RetrieveMultiple
Invoice RetrievePrincipalAccess
Invoice RetrieveSharedPrincipalsAndAccess
Invoice RevokeAccess
Invoice SetRelated Contact
Invoice SetState
Invoice SetStateDynamicEntity
Invoice Update
InvoiceDetail Create
InvoiceDetail Delete
InvoiceDetail Retrieve
InvoiceDetail RetrieveMultiple
InvoiceDetail Update
Lead Assign
Lead Create
Lead Delete
Lead GrantAccess
Lead Merge
Lead ModifyAccess
Lead QualifyLead
Lead RemoveRelated Account
Lead RemoveRelated Contact
Lead Retrieve
Lead RetrieveMultiple
Lead RetrievePrincipalAccess
Lead RetrieveSharedPrincipalsAndAccess
Lead RevokeAccess
Lead SetRelated Account
Lead SetRelated Contact
Lead SetState
Lead SetStateDynamicEntity
Lead Update
Letter Assign
Letter Create
Letter Delete
Letter GrantAccess
Letter Handle
Letter ModifyAccess
Letter Retrieve
Letter RetrieveMultiple
Letter RetrievePrincipalAccess
Letter RetrieveSharedPrincipalsAndAccess
Letter RevokeAccess
Letter Route
Letter SetState
Letter SetStateDynamicEntity
Letter Update
new_customentity Assign
new_customentity Create
new_customentity Delete
new_customentity GrantAccess
new_customentity ModifyAccess
new_customentity Retrieve
new_customentity RetrieveMultiple
new_customentity RetrievePrincipalAccess
new_customentity RetrieveSharedPrincipalsAndAccess
new_customentity RevokeAccess
new_customentity SetState
new_customentity SetStateDynamicEntity
new_customentity Update
Opportunity Assign
Opportunity Create
Opportunity Delete
Opportunity GrantAccess
Opportunity Lose
Opportunity ModifyAccess
Opportunity RemoveRelated Account
Opportunity RemoveRelated Contact
Opportunity RemoveRelated Competitor
Opportunity Retrieve
Opportunity RetrieveMultiple
Opportunity RetrievePrincipalAccess
Opportunity RetrieveSharedPrincipalsAndAccess
Opportunity RevokeAccess
Opportunity SetRelated Account
Opportunity SetRelated Contact
Opportunity SetRelated Competitor
Opportunity SetState
Opportunity SetStateDynamicEntity
Opportunity Update
Opportunity Win
OpportunityClose Assign
OpportunityClose Create
OpportunityClose Delete
OpportunityClose GrantAccess
OpportunityClose ModifyAccess
OpportunityClose Retrieve
OpportunityClose RetrieveMultiple
OpportunityClose RetrievePrincipalAccess
OpportunityClose RetrieveSharedPrincipalsAndAccess
OpportunityClose RevokeAccess
OpportunityClose SetState
OpportunityClose SetStateDynamicEntity
OpportunityClose Update
OpportunityProduct Create
OpportunityProduct Delete
OpportunityProduct Retrieve
OpportunityProduct RetrieveMultiple
OpportunityProduct Update
PhoneCall Assign
PhoneCall Create
PhoneCall Delete
PhoneCall GrantAccess
PhoneCall Handle
PhoneCall ModifyAccess
PhoneCall Retrieve
PhoneCall RetrieveMultiple
PhoneCall RetrievePrincipalAccess
PhoneCall RetrieveSharedPrincipalsAndAccess
PhoneCall RevokeAccess
PhoneCall Route
PhoneCall SetState
PhoneCall SetStateDynamicEntity
PhoneCall Update
Product AddProductToKit
Product Create
Product Delete
Product RemoveRelated Lead
Product RemoveRelated Competitor
Product Retrieve
Product RetrieveMultiple
Product SetRelated Lead
Product SetRelated Competitor
Product SetState
Product SetStateDynamicEntity
Product Update
Queue Assign
Queue Create
Queue Delete
Queue GrantAccess
Queue ModifyAccess
Queue Retrieve
Queue RetrieveMultiple
Queue RetrievePrincipalAccess
Queue RetrieveSharedPrincipalsAndAccess
Queue RevokeAccess
Queue SetState
Queue SetStateDynamicEntity
Queue Update
Quote Assign
Quote Close
Quote Create
Quote Delete
Quote GrantAccess
Quote ModifyAccess
Quote RemoveRelated Contact
Quote Retrieve
Quote RetrieveMultiple
Quote RetrievePrincipalAccess
Quote RetrieveSharedPrincipalsAndAccess
Quote RevokeAccess
Quote SetRelated Contact
Quote SetState
Quote SetStateDynamicEntity
Quote Update
Quote Win
QuoteClose Assign
QuoteClose Create
QuoteClose Delete
QuoteClose GrantAccess
QuoteClose ModifyAccess
QuoteClose Retrieve
QuoteClose RetrieveMultiple
QuoteClose RetrievePrincipalAccess
QuoteClose RetrieveSharedPrincipalsAndAccess
QuoteClose RevokeAccess
QuoteClose SetState
QuoteClose SetStateDynamicEntity
QuoteClose Update
QuoteDetail Create
QuoteDetail Delete
QuoteDetail Retrieve
QuoteDetail RetrieveMultiple
QuoteDetail Update
SalesOrder Assign
SalesOrder Cancel
SalesOrder Create
SalesOrder Delete
SalesOrder GrantAccess
SalesOrder LockSalesOrderPricing
SalesOrder ModifyAccess
SalesOrder RemoveRelated Contact
SalesOrder Retrieve
SalesOrder RetrieveMultiple
SalesOrder RetrievePrincipalAccess
SalesOrder RetrieveSharedPrincipalsAndAccess
SalesOrder RevokeAccess
SalesOrder SetRelated Contact
SalesOrder SetState
SalesOrder SetStateDynamicEntity
SalesOrder Update
SalesOrderDetail Create
SalesOrderDetail Delete
SalesOrderDetail Retrieve
SalesOrderDetail RetrieveMultiple
SalesOrderDetail Update
ServiceAppointment Assign
ServiceAppointment Book
ServiceAppointment Create
ServiceAppointment Delete
ServiceAppointment GrantAccess
ServiceAppointment Handle
ServiceAppointment ModifyAccess
ServiceAppointment Reschedule
ServiceAppointment Retrieve
ServiceAppointment RetrieveMultiple
ServiceAppointment RetrievePrincipalAccess
ServiceAppointment RetrieveSharedPrincipalsAndAccess
ServiceAppointment RevokeAccess
ServiceAppointment Route
ServiceAppointment SetState
ServiceAppointment SetStateDynamicEntity
ServiceAppointment Update
SystemUser Create
SystemUser SetState
SystemUser SetStateDynamicEntity
SystemUser Update
Task Assign
Task Create
Task Delete
Task GrantAccess
Task Handle
Task ModifyAccess
Task Retrieve
Task RetrieveMultiple
Task RetrievePrincipalAccess
Task RetrieveSharedPrincipalsAndAccess
Task RevokeAccess
Task Route
Task SetState
Task SetStateDynamicEntity
Task Update
Team AddMembers
Team Create
Team RemoveMembers
Team Retrieve
Team RetrieveMultiple
Team Update
Territory Create
Territory Delete
Territory Retrieve
Territory RetrieveMultiple
Territory Update
UserSettings RetrieveMultiple

Crm’de Fırsat(Opportunity) kayıtlarını program ile Kazanıldı-Kaybedildi olarak nasıl değiştireceğimizi inceleyelim. Aşağıda Blue Company şirketine açılan bir fırsat kaydının ekran görüntüsü var. Burada statusu kayıt açık(open) ‘tır.

opportunityclose

Belirli koşullar ya da belirli kişilerin bu işlemi yapmasını istediğimizde ya da başka bir durumda kodla bu işlemi yapabiliriz.

Burada Setstate mesajını kullanmamaktayız. WinOpportunityRequest ve LoseopportunityRequest mesajlarını kullanıyoruz.

Aşağıda Crm servise bağlantı için gereken kod bulunmaktadır.

public CrmService _service;

public void ConnectService()
{
try
{

_service = new CrmService();

_service.Url = “http://localhost/MSCrmServices/2007/CrmService.asmx“;

_service.CrmAuthenticationTokenValue = new CrmAuthenticationToken();

_service.CrmAuthenticationTokenValue.OrganizationName = “MicrosoftCRM”;

_service.Credentials = new System.Net.NetworkCredential(“crmadmin”, password, “MyCompany”);

}
catch (SoapException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}

Fırsatı kazanıldı olarak kapatmak için aşağıdaki kodun çalışması gerekir. Fırsat kayıdı kapatıldığında sadece statecode,statuscode alanları değişmez. Ayrıca OpportunityClose kayıdı da oluşmaktadır. Kodla bu işlemi yaparken OpportunityClose oluşturmamız gerekir.

private void btnWinOpportunity_Click(object sender, EventArgs e)
{
try
{
ConnectService();

opportunityclose oc=new opportunityclose();
oc.opportunityid = new Lookup();
oc.opportunityid.Value= new Guid(“5580CFF1-AD17-DD11-BDFC-0003FF5B34CE”);
oc.opportunityid.type=EntityName.opportunity.ToString();

WinOpportunityRequest req = new WinOpportunityRequest();
req.OpportunityClose = oc;
req.Status = 3;
WinOpportunityResponse res = (WinOpportunityResponse)_service.Execute(req);

}
catch(SoapException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}

Bu işlemden sonra kayıt aşağıdaki gibi Kazanıldı olarak kapatılmış olur.

opportunityclose

Fırsatı kaybedildi olarak kapatmak için aşağıdaki kodun çalışması gerekir. Fırsat kayıdı kapatıldığında sadece statecode,statuscode alanları değişmez. Ayrıca OpportunityClose kayıdı da oluşmaktadır. Kodla bu işlemi yaparken OpportunityClose oluşturmamız gerekir.

private void btnLostOpportunity_Click(object sender, EventArgs e)
{
try
{
ConnectService();

opportunityclose oc = new opportunityclose();
oc.opportunityid = new Lookup();
oc.opportunityid.Value = new Guid(“5580CFF1-AD17-DD11-BDFC-0003FF5B34CE”);
oc.opportunityid.type = EntityName.opportunity.ToString();

LoseOpportunityRequest req = new LoseOpportunityRequest();
req.OpportunityClose = oc;
req.Status = 4;
LoseOpportunityResponse res = (LoseOpportunityResponse)_service.Execute(req);

}
catch (SoapException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}

Bu işlemden sonra kayıt aşağıdaki gibi Kaybedildi olarak kapatılmış olur.

opportunityclose

Sistemde bir hata olduğunda ilk bakacağımız yerlerden biri Eventviewer’dır.

Administrative Tools–>Event Viewer‘a tıklayarak ya da

Komut satırına (Win+R ile açılır.) eventvwr.msc yazılırak aşağıdaki ekranı görebilirsiniz.

Loglarda warning,error, gibi tüm akyıltarı görürüz. Bu da aradığımız kayıtları bulmamızı zorlaştırabilir. Filtreleme için Filter Current Log dememiz gerekir. Aşağıdaki ekran karşınıza çıkacaktır. Burada sadece error tipinde ve MSCRMAsyncService, MSCRMCallout, MSCRMDeletionService, MSCRMEmail servislerinde bir hata oluşan kayıtları görmek için filtreleme yapıyoruz.

eventviewer

Bu kayıtları kaydetmek için Save All Event As ile kaydetmemiz gerekiyor. Kaydedeceğimiz lokasyonu belirliyoruz.

eventviewer

Kaydettiğimiz log dosyasını başka bir zaman ya da başka bir makinada açmak isteyebiliriz. Bunu için Open Saved Log‘ a basarız.

eventviewer

Dosyanın kayıtlı olduğu lokasyondan log dosyası seçilir.

eventviewer

Log dosyasını görmek istediğimiz node’u seçeriz. Burada defaultta gelen EventViewer –>Saved Logs altında ErrorLog adı ile varolan log dosyasını açıyoruz. İstersek New Folder ile Saved Logs ya da EventViewer altına yeni klasör açıp onun altına da kaydedilmiş logları ekleyebiliriz.

eventviewer

Kaydettiğimiz Log dosyasını aşağıdaki gibi yeniden açmış oluyoruz.

eventviewer

Programdaki ihtiyaca göre runtime’da ekranın tasarlanmasını isteyebiliriz. Kullanıcının gireceği değerlere göre formu tasarlamamız gerekebilir. Mesela Kullanıcının gireceği banka hesap sayısına göre formda veri giriş kontrollerinin oluşması gerekebilir. Aşağıda kullanıcının gireceği sayı kadar label ve textbox oluşturan kod bulunmaktadır. Burada label ve textboxların herbirini oluştururken Id değerinin unique olması gerektiğini unutmamak gerekir. Bu da txtHesapno1,txtHesapno2 şeklinde arttırarak sağlanır.

Label için boyutunun default değil biraz daha büyük olmasını istediğim için FontFamily ve Font kullandım. Dilerseniz bu satırları silip Label’ın kendi özellikleriyle de işlem yapabilir ya da fontfamily, fontsize değerlerini değiştirebilirsiniz.

Size, Location ve Point kullanılarak label ve textboxların panel üzerindeki konumlarının nasıl olacağı belirlenmiştir. Height değeri her kontrol için arttrılımış böylece kontrollerin üst üste gelme sorunu engellenmiştir. Mesela Label için uzunluk değeri 400 verilmiş ve konum olarak 60,0 a yerleştirilmesi sağlanmıştır. Dolayısıyla Textbox’ın location 400+60=460′tan daha büyük bir değer verilmiştir. Burada 470 kullanılmıştır.

private void btnTamam_Click(object sender, EventArgs e)

{

int sayi = Convert.ToInt32(txtCount.Text);

for (int i = 1; i <= sayi ; i++)

{

Label lbl = newLabel();

int j = i + 1;

lbl.Name = “lblCount” + j;

lbl.Text = i+“. Hesap Numaras : “;

FontFamily ff = newFontFamily(“Microsoft Sans Serif”);

Font f = newFont(ff, 10);

lbl.Font = f;

Size sz = newSize(60, 0);

Point p = newPoint(sz);

p.Y = sz.Height + (25 * i);

lbl.Location = p;

lbl.Size = newSize(400, 20);

panel1.Controls.Add(lbl);

TextBox tx = newTextBox();

tx.Name = “txtHesapno” + j;

Size sz2 = newSize(470, 0);

Point p2 = newPoint(sz2);

p2.Y = sz2.Height + (25 * i);

tx.Location = p2;

tx.Size = newSize(132, 22);

panel1.Controls.Add(tx);

}

}

Veri Al butonu ile dinamik olarak oluşturulan kontrollerine girilen bilgilerin nasıl alınacağı hakkında küçük bir örnek verdim. Burada panel içerisine kontrolleri oluşturmuştuk. Bu yüzden foreach ile paneldeki tüm textboxları bulup .Text ile içerisinde bilgi alınıp yanyana string olarak yeni bir alana yazılmıştır. Kontroller is Textbox ile textbox mı label mı ya da başka bir kontrol mü olduğu belirlenir. as Textbox ile de bu kontrolü Textboxa cast etmiş oluyoruz.

privatevoid btnVeriAl_Click(object sender, EventArgs e)

{

string s = string.Empty;

foreach (var control in panel1.Controls)

{

if (control isTextBox)

{

TextBox txt = control asTextBox;

s += Convert.ToString(txt.Text) +” – “;

}

}

//En sondaki ” – ” 3 karakteri siler.

s=s.Remove(s.LastIndexOf(‘-’)-1,3);

txtResult.Text = s;

}

Projelerimizde yük paylaşımı ya da yedek sistem için Cluster kullanabiliriz. Burada kullanıcı tek bir makina olarak görmesine karşın arkada çift makina işlem görmektedir. Sql’i Cluster olarak kurduğumuzda restart etmek için nasıl adımlar izlenmesi gerektiğini açklayacağım. Cluster Sql ile serverlardan biri yetkinliğini yitirdiğinde diğerinin otomatik olarak çalışması amaçlanmıştır. Sql ile işlem yaparken restart etme ihtiyacı duyabiliriz. Bu durumda Cluster kurulan Sql Server’ın restart işlemi bildiğimiz yöntemler aşağıda görüldüğü gibi SSMS‘dan olmamaktadır. Restart disabled‘tır.

clustersqlrestart

Administrative Tools–>Failover Cluster Manager‘dan restart etmemiz gerekir. Bu özellik Windows 2008 ile otomatik kurulmadığı için Add Feature ile yüklenmesi gerekir.

clustersqlrestart

Failover Cluster Manager‘da Sql Server’ı sağ klik ile aşağıdaki popup açılır. Öncelikle Take … offline ile Sql’i kapatmamız gerekir.

failoverclustermanager

Kapattığımız Sql Server’ı Bring … online ile başlatmamız gerekir.

failoverclustermanager

Bu işlemlerden sonra Sql’i restart etmiş oluyoruz.

Yaptığımız raporlar yüklü data çekiyorsa veritabanını yoracağı için diğer işlemleri engelleyecektir. Crm için custom yazılan raporları genelde Report Server’a deploy ederiz. Ancak raporların görüntülenmediği, diğer işlemleri engellediği yönünde sorunlarla karşılaşırız. İmkan varsa rapor sunucusunun farklı bir makina olarak ayarlanması bir çözüm performansı ciddi artıtracağı gibi biraz masraflı olabilir. Alternatif yollardan aşağıdaki ekran görüntüsü http://reports dan yapılan bir ayarla aynı parametredelerde  çekilen raporlar için bir çözümdür. Farklı parametrelerde yine cache alacağı için raporun ilk çalışması uzun sürer. Aşağıdaki ayar ile dakika cinsinden alınan raporun cache tutulması ile aynı parametrelerle raporu çeken diğer kullanıcılar için bekleme süresini kısaltır.

reportcaching

 

reportcaching

crm 4.0′da kodla kuyruğa atama işlemi nasıl yapılacağını inceleyim. Kuyruğa atama işlemi Crm arayüzünden ve kodla yapılabilmektedir. İki şekilde yapılıdğında kayıdın ownerid(sahip) alanın kuyruk olmadığını daha önce assign edilen kullanıcı olarak kaldığı ancak Navbarda Kuyruk lardan bakıldığında ilgili kayıdın listelendiğini görürsünüz. Burada Crm ownerid alanını systemuser olarak kullanmaktadır. Başka bir entity ile değiştiremiyoruz. Ancak QueueItem tablosunda istenen kayıdın kuyruğa atandığındaki kayıtları tutulmaktadır. Crm kuyruğa atama işlemi yapıldığında kayıdın güvenlik rolü işlemleri ownerı olan kullanıcı üzerinden yürür. Ama kuyruğa atandıysa QueueItem tablosunda bulunduğu için Kuyruklar bölümünde listelenir.

Aşağıda Emailin kuyruğa atanması ile ilgili ekran görüntüleri ve uygulama kodu bulunmaktadır. Console applicaitonda çalıştığı için Web Servis kullanılmıştır ve TargetQueuedEmail requesti kullanılmıştır. Plugin’de kullanılsaydı TargetQueuedDynamic kullanılması gerekirdi. 

queue

queue

CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = “MicrosoftCRM”;

CrmService service = new CrmService();
service.Url = “http://localhost:5555/mscrmservices/2007/crmservice.asmx”;
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

TargetQueuedEmail target = new TargetQueuedEmail();
target.EntityId=new Guid(“20BF764C-3E28-DD11-BDFC-0003FF5B34CE”);//EmailId

RouteRequest routeRequest = new RouteRequest();
routeRequest.RouteType = RouteType.Queue;
routeRequest.EndpointId = new Guid(“B09DD1F9-3628-DD11-BDFC-0003FF5B34CE”); //queueId
routeRequest.Target = target;
routeRequest.SourceQueueId = new Guid(“B09DD1F9-3628-DD11-BDFC-0003FF5B34CE”);//queueId
RouteResponse routeResponse = (RouteResponse)service.Execute(routeRequest);

Tag Cloud

Follow

Get every new post delivered to your Inbox.