Dynamics 365 F&O – Events

Bu yazıda Dynamics 365 Finance and Operations da yeni tanıştığımız ve extensibility framework‘ün bir parçası olan event kavramından bahseceğim. Hem tablo-form gibi çeşitli objelerin üzerinde gördüğümüz event‘lerden hem de methodlar için kullanılan pre-post event‘lere değineceğiz.

1. Event Nedir ?

Adından da anlaşılabileceği gibi çeşitli durumlarda tetiklenen yer tutuculardır. Örneğin bir tabloya kayıt eklendiğinde OnInserted event’i tetiklenir. Kayıt silindiğinde OnDeleted çalışır. Siz ihtiyacınıza uygun olanı seçip, kullanabilirsiniz. Neredeyse her event standartta var olan ve override ederek kullandığımız sistem methodlarına karşılık gelir. Örneğin insert methodunun super öncesi için OnInserting, super sonrası için OnInserted event’i bulunur.

Kullanımı

D365 F&O içinde tablo-form gibi çeşitli objelerde Events isminde bir bölüm olduğunu görmüşsünüzdür. Bu bölüm, o obje için kullanabileceğiniz event listesini içerir. Her obje için bu liste farklıdır. Listede ilgili event üzerine gelip sağ tık > kopyala diyerek aldığınız kodu, yeni oluşturduğunuz bir sınıfın içine yapıştırarak kullanabilirsiniz. Yapıştırdığınız method’un içini kendinize uygun şekilde doldurduktan sonra değişikliklerin yansıması için Visual Studio’yu build etmeniz yeterli.

Örnekler

Event’lerde this yada element gibi özel ifadeleri direkt kullanamıyorsunuz. Bu sebeple aşağıda en çok kullanacağınız objeler için çeşitli örnek kodlar ekledim.

Özellikle form event’lerinin kullanımı başlarda karışık gelebilir. Form içindeki diğer objelere nasıl erişeceğinizi anlayabilmeniz için aşağıdaki örnek kodları inceleyebilirsiniz.

Tablo Örnek 1 – Updating

[DataEventHandler(tableStr(TrvRequisitionTable), DataEventType::Updating)]
public static void TrvRequisitionTable_onUpdating(Common sender, DataEventArgs e)
{
	TrvRequisitionTable trvRequisitionTable = sender;

	if (trvRequisitionTable.orig()
		&& trvRequisitionTable.orig().GvnField != trvRequisitionTable.GvnField)
	{
		// do something
	}
}

Tablo Örnek 2 – ValidateWrite

[DataEventHandler(tableStr(TrvRequisitionTable), DataEventType::ValidatingWrite)]
public static void TrvRequisitionTable_onValidatingWrite(Common sender, DataEventArgs e)
{
	ValidateEventArgs   validateEventArgs   = e as ValidateEventArgs;
	boolean             ret                 = validateEventArgs.parmValidateResult();
	TrvRequisitionTable trvRequisitionTable = sender;
	
	if (ret
		&& !trvRequisitionTable.TravelPurpose)
	{
		ret = checkFailed(strFmt("@GVN:TravelPurposeEmpty"));
	}

	if (ret
		&& trvRequisitionTable.GvnEndDateTime
		&& trvRequisitionTable.GvnStartDateTime
		&& trvRequisitionTable.GvnEndDateTime < trvRequisitionTable.GvnStartDateTime)
	{
		ret = checkFailed("@GVN:StartEndDateError");
	}

	validateEventArgs.parmValidateResult(ret);
}

Form – Initialized

[FormEventHandler(formStr(TrvExpenses), FormEventType::Initialized)]
public static void TrvExpenses_OnInitialized(xFormRun sender, FormEventArgs e)
{
	FormDataSource  trvExpTableDs   = sender.dataSource(formDataSourceStr(TrvExpenses, TrvExpTable));
	TrvExpTable     trvExpTable     = trvExpTableDs.cursor();
	FormDataSource  trvExpTransDs   = sender.dataSource(formDataSourceStr(TrvExpenses, TrvExpTrans));
	FormDesign      design          = sender.design();

	// field gizliliği
	trvExpTableDs.object(fieldNum(TrvExpTable, MyField)).visible(false);

	// buton gizliliği
	design.controlName(formControlStr(TrvExpenses, GvnDummyButton)).enabled(false);

	// dataSource
	trvExpTransDs.allowCreate(false);
	trvExpTransDs.allowDelete(false);
	trvExpTransDs.allowEdit(false);
}

FormDataSource – Activated

[FormDataSourceEventHandler(formDataSourceStr(TrvRequisition, TrvRequisitionTable), FormDataSourceEventType::Activated)]
public static void TrvRequisitionTable_OnActivated(FormDataSource sender, FormDataSourceEventArgs e)
{
	sender.object(fieldNum(TrvRequisitionTable, GvnDummyField)).visible(trvRequisitionTable.CurrencyCode != "");
}

FormDataSource Field – Modified

[FormDataFieldEventHandler(formDataFieldStr(TrvCashAdvances, TrvCashAdvance, GvnWorker), FormDataFieldEventType::Modified)]
public static void GvnWorker_OnModified(FormDataObject sender, FormDataFieldEventArgs e)
{
	FormDataSource formDs = sender.datasource();
	TrvCashAdvance trvCashAdvance = formDs.cursor();
	
	// do something
}

FormControl – Lookup

Lookup ile ilgili detaylı yazıma buradan bakabilirsiniz.

[FormControlEventHandler(formControlStr(TrvCashAdvances, General_GvnWorker), FormControlEventType::Lookup)]
public static void General_GvnWorker_OnLookup(FormControl sender, FormControlEventArgs e)
{
	TrvCashAdvance          trvCashAdvance = sender.formRun().dataSource(formdatasourcestr(TrvCashAdvances, TrvCashAdvance)).cursor();
	Query                   query;
	QueryBuildDataSource    qbds;
	SysReferenceTableLookup sysTableLookup;

	query = new Query();
	qbds = query.addDataSource(tableNum(HcmWorker));


	sysTableLookup = SysReferenceTableLookup::newParameters(tableNum(HcmWorker), sender);
	sysTableLookup.addLookupMethod("name");
	sysTableLookup.addLookupfield(fieldNum(HcmWorker, PersonnelNumber));

	sysTableLookup.parmQuery(query);
	sysTableLookup.performFormLookup();


	FormControlCancelableSuperEventArgs event = e;
	event.CancelSuperCall();
}

2. Pre-Post Event Handler

D365 F&O objelerinde yer alan methodların öncesine veya sonrasına kod yazmak için kullanılırlar.

Herhangi bir tabloda, sınıfta yada formda (sadece form methodları için, datasource ve design daki methodlar için değil) bulunan method’a sağ tıklayıp Copy event handler method > Pre / Post diyerek kopyaladığınız kodu, bir sınıf içerisine yapıştırıp kullanabilirsiniz. Örnek kullanımlar aşağıdaki gibidir.

Pre

[PreHandlerFor(classStr(RetailTransactionServiceCustomer), staticMethodStr(RetailTransactionServiceCustomer, updateCustomer))]
public static void RetailTransactionServiceCustomer_Pre_updateCustomer(XppPrePostArgs args)
{       
	RetailTransactionServiceCustomer serviceCustomer = args.getThis();

	// do something
}

Post

[PostHandlerFor(formStr(TrvCashAdvances), formMethodStr(TrvCashAdvances, init))]
public static void TrvCashAdvances_Post_init(XppPrePostArgs args)
{
	FormRun formRun = args.getThis();
	FormDataSource formDs = formRun.dataSource(formdatasourcestr(TrvCashAdvances, TrvCashAdvance));
	
	formDs.object(fieldNum(TrvCashAdvance, RequestingWorker)).visible(true);
}

Bilinen Kısıtlamalar

  • Sadece public olan methodlar için bu yöntemi kullanabilirsiniz. Protected veya private bir method da visual studio’nun hata verdiğini göreceksiniz.
  • Eğer method public olduğu halde Hookable(false) olarak işaretlenmiş ise yine bu yöntemi kullanamassınız.
  • Method’un döndüğü veriye müdahale edemessiniz. Sadece öncesine veya sonrasına kod yazabilirsiniz. Veriye müdahale etmek için class extension – chain of command yöntemini kullanmalısınız. Bu konu hakkındaki yazıma buradan ulaşabilirsiniz.

Son olarak

Eventler hakkında bahsedeceklerim bu kadardı. Diğer D365 F&O yazılarıma buradan, Dynamics AX yazılarıma da şuradan bakabilirsiniz. Hoşçakalın.

Yazıyı Paylaş

“Dynamics 365 F&O – Events” hakkında 1 yorum

  1. Geri bildirim: Dynamics 365 F&O – Class Extension & Chain of Command | Güven Şahin

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir