Posts Tagged ‘ Dynamics 365 nedir

Dynamics 365 Finance and Operations Sorguya dinamik filtre eklemek?

Bu yazıda Dynamics 365 Finance and Operations içinde yazdığınız herhangi bir sorguya filtre eklerken eğer sadece değişken doluysa filtre eklemek istiyorsanız kullanabileceğiniz bir teknikten bahsedeceğim.

Örnek bir kodu inceleyelim. Öncelikle Generateonly ile sorgunuzu sadece hazırlamış oluyorsunuz çalıştırılmıyor bu sayede SQL çıktısını görebiliyorsunuz.

static void DmrFDQuerySQLStatment(Args _args)

{

CustAccount custAccount;

CustTable   custTable;

custAccount = “C00003″;

select generateonly custTable

where custTable.AccountNum == custAccount;

// 1. sorgu

info(custTable.getSQLStatement());

// Eğer değişkenin boş mu dolu mu olduğunu kontrol etmek istersem if kullanmalıyım. Birden çok değişken olduğunda bu çok karışık bir hal alabilir.

if(custAccount != “”)

{

select generateonly custTable

where custTable.AccountNum == custAccount;

info(custTable.getSQLStatement());

}

else

{

select generateonly custTable ;

info(custTable.getSQLStatement());

}

// Bu şekilde yazarak eğer değişken doluysa ekliyor. Eğişken boşsa hiç eklemiyor if e ihtiyaç duymadan işimizi hallediyoru.

// 3. sorgu

custAccount = “”;

select generateonly custTable

where (( custTable.AccountNum == custAccount && custAccount ) || (!custAccount));

info(custTable.getSQLStatement());

}

  1. sorgu

SELECT T1.ACCOUNTNUM,T1.INVOICEACCOUNT,T1.CUSTGROUP,T1.LINEDISC,

T1.PAYMTERMID,T1.CASHDISC,T1.CURRENCY,

T1.INTERCOMPANYAUTOCREATEORDERS,T1.SALESGROUP,T1.BLOCKED,

T1.ONETIMECUSTOMER,T1.ACCOUNTSTATEMENT,

T1.CREDITMAX,T1.MANDATORYCREDITLIMIT,T1.VENDACCOUNT,

T1.PRICEGROUP,T1.MULTILINEDISC,T1.ENDDISC,T1.VATNUM,

T1.INVENTLOCATION,T1.DLVTERM,T1.DLVMODE,T1.MARKUPGROUP,

T1.CLEARINGPERIOD,T1.FREIGHTZONE,T1.CREDITRATING,T1.TAXGROUP,

T1.STATISTICSGROUP,T1.PAYMMODE,T1.COMMISSIONGROUP,

T1.BANKACCOUNT,T1.PAYMSCHED,T1.CONTACTPERSONID,T1.INVOICEADDRESS,

T1.OURACCOUNTNUM,T1.SALESPOOLID,T1.INCLTAX,T1.CUSTITEMGROUPID,

T1.NUMBERSEQUENCEGROUP,T1.PAYMDAYID,T1.LINEOFBUSINESSID,

T1.DESTINATIONCODEID,T1.GIROTYPE,T1.SUPPITEMGROUPID,

T1.GIROTYPEINTERESTNOTE,T1.TAXLICENSENUM,T1.WEBSALESORDERDISPLAY,

T1.PAYMSPEC,T1.BANKCENTRALBANKPURPOSETEXT,T1.BANKCENTRALBANKPURPOSECODE,

T1.INTERCOMPANYALLOWINDIRECTCREATION,

T1.PACKMATERIALFEELICENSENUM,T1.TAXBORDERNUMBER_FI,T1.EINVOICEEANNUM,

T1.FISCALCODE,T1.DLVREASON,T1.FORECASTDMPINCLUDE,

T1.GIROTYPECOLLECTIONLETTER,T1.SALESCALENDARID,T1.CUSTCLASSIFICATIONID,

T1.INTERCOMPANYDIRECTDELIVERY,T1.ENTERPRISENUMBER,

T1.SHIPCARRIERACCOUNT,T1.GIROTYPEPROJINVOICE,T1.INVENTSITEID,

T1.ORDERENTRYDEADLINEGROUPID,T1.SHIPCARRIERID,

T1.SHIPCARRIERFUELSURCHARGE,T1.SHIPCARRIERBLINDSHIPMENT,

T1.SHIPCARRIERACCOUNTCODE,T1.GIROTYPEFREETEXTINVOICE,

T1.SYNCENTITYID,T1.SYNCVERSION,T1.SALESDISTRICTID,

T1.SEGMENTID,T1.SUBSEGMENTID,T1.RFIDITEMTAGGING,T1.RFIDCASETAGGING,

T1.RFIDPALLETTAGGING,T1.COMPANYCHAINID,T1.COMPANYIDSIRET,

T1.PARTY,T1.IDENTIFICATIONNUMBER,T1.PARTYCOUNTRY,T1.PARTYSTATE,

T1.ORGID,T1.PAYMIDTYPE,T1.FACTORINGACCOUNT,T1.DEFAULTDIMENSION,

T1.CUSTEXCLUDECOLLECTIONFEE,T1.CUSTEXCLUDEINTERESTCHARGES,

T1.COMPANYNAFCODE,T1.BANKCUSTPAYMIDTABLE,T1.GIROTYPEACCOUNTSTATEMENT,

T1.MAINCONTACTWORKER,T1.CREDITCARDADDRESSVERIFICATION,

T1.CREDITCARDCVC,T1.CREDITCARDADDRESSVERIFICATIONVOID,

T1.CREDITCARDADDRESSVERIFICATIONLEVEL,T1.COMPANYTYPE_MX,T1.RFC_MX,T1.CURP_MX,

T1.STATEINSCRIPTION_MX,T1.RESIDENCEFOREIGNCOUNTRYREGIONID_IT,

T1.BIRTHCOUNTYCODE_IT,T1.BIRTHDATE_IT,T1.BIRTHPLACE_IT,T1.EINVOICE,

T1.CCMNUM_BR,T1.CNPJCPFNUM_BR,T1.PBACUSTGROUPID,T1.IENUM_BR,

T1.SUFRAMANUMBER_BR,T1.SUFRAMA_BR,T1.CUSTFINALUSER_BR,T1.INTERESTCODE_BR,

T1.FINECODE_BR,T1.SUFRAMAPISCOFINS_BR,T1.TAXWITHHOLDCALCULATE_TH,

T1.TAXWITHHOLDGROUP_TH,T1.CONSDAY_JP,T1.NIT_BR,T1.INSSCEI_BR,T1.CNAE_BR,

T1.ICMSCONTRIBUTOR_BR,T1.SERVICECODEONDLVADDRESS_BR,

T1.INVENTPROFILETYPE_RU,T1.INVENTPROFILEID_RU,T1.TAXWITHHOLDCALCULATE_IN,

T1.UNITEDVATINVOICE_LT,T1.ENTERPRISECODE,T1.COMMERCIALREGISTERSECTION,

T1.COMMERCIALREGISTERINSETNUMBER,T1.COMMERCIALREGISTER,

T1.REGNUM_W,T1.ISRESIDENT_LV,T1.INTBANK_LV,T1.PAYMENTREFERENCE_EE,

T1.PACKAGEDEPOSITEXCEMPT_PL,T1.FEDNONFEDINDICATOR,

T1.IRS1099CINDICATOR,T1.AGENCYLOCATIONCODE,T1.FEDERALCOMMENTS,

T1.USEPURCHREQUEST,T1.MCRMERGEDPARENT,T1.MCRMERGEDROOT,

T1.AFFILIATED_RU,T1.CASHDISCBASEDAYS,T1.CUSTTRADINGPARTNERCODE,

T1.CUSTWHTCONTRIBUTIONTYPE_BR,T1.DAXINTEGRATIONID,

T1.DEFAULTDIRECTDEBITMANDATE,T1.DEFAULTINVENTSTATUSID,

T1.ENTRYCERTIFICATEREQUIRED_W,T1.EXPORTSALES_PL,T1.EXPRESSBILLOFLADING,

T1.FISCALDOCTYPE_PL,T1.FOREIGNRESIDENT_RU,

T1.GENERATEINCOMINGFISCALDOCUMENT_BR,T1.INVOICEPOSTINGTYPE_RU,

T1.ISSUEOWNENTRYCERTIFICATE_W,T1.ISSUERCOUNTRY_HU,

T1.LVPAYMTRANSCODES,T1.MANDATORYVATDATE_PL,T1.PASSPORTNO_HU,

T1.PDSCUSTREBATEGROUPID,T1.PDSFREIGHTACCRUED,T1.PDSREBATETMAGROUP,

T1.TAXPERIODPAYMENTCODE_PL,T1.USECASHDISC,T1.FIELD1,

T1.MODIFIEDDATETIME,T1.DEL_MODIFIEDTIME,T1.MODIFIEDBY,

T1.CREATEDDATETIME,T1.DEL_CREATEDTIME,T1.RECVERSION,T1.PARTITION,

T1.RECID,T1.MEMO FROM CUSTTABLE T1 WHERE (((PARTITION=?) AND (DATAAREAID=?)) AND (ACCOUNTNUM=?))

  1. sorgu

SELECT T1.ACCOUNTNUM,T1.INVOICEACCOUNT,T1.CUSTGROUP,T1.LINEDISC,

T1.PAYMTERMID,T1.CASHDISC,T1.CURRENCY,T1.INTERCOMPANYAUTOCREATEORDERS,

T1.SALESGROUP,T1.BLOCKED,T1.ONETIMECUSTOMER,T1.ACCOUNTSTATEMENT,

T1.CREDITMAX,T1.MANDATORYCREDITLIMIT,T1.VENDACCOUNT,

T1.PRICEGROUP,T1.MULTILINEDISC,T1.ENDDISC,T1.VATNUM,

T1.INVENTLOCATION,T1.DLVTERM,T1.DLVMODE,T1.MARKUPGROUP,T1.CLEARINGPERIOD,

T1.FREIGHTZONE,T1.CREDITRATING,T1.TAXGROUP,T1.STATISTICSGROUP,

T1.PAYMMODE,T1.COMMISSIONGROUP,T1.BANKACCOUNT,T1.PAYMSCHED,

T1.CONTACTPERSONID,T1.INVOICEADDRESS,T1.OURACCOUNTNUM,

T1.SALESPOOLID,T1.INCLTAX,T1.CUSTITEMGROUPID,T1.NUMBERSEQUENCEGROUP,

T1.PAYMDAYID,T1.LINEOFBUSINESSID,T1.DESTINATIONCODEID,

T1.SUPPITEMGROUPID,T1.TAXLICENSENUM,T1.WEBSALESORDERDISPLAY,T1.PAYMSPEC,

T1.BANKCENTRALBANKPURPOSETEXT,T1.BANKCENTRALBANKPURPOSECODE,

T1.INTERCOMPANYALLOWINDIRECTCREATION,T1.PACKMATERIALFEELICENSENUM,

T1.DLVREASON,T1.FORECASTDMPINCLUDE,T1.SALESCALENDARID,

T1.CUSTCLASSIFICATIONID,T1.INTERCOMPANYDIRECTDELIVERY,T1.SHIPCARRIERACCOUNT,

T1.INVENTSITEID,T1.ORDERENTRYDEADLINEGROUPID,

T1.SHIPCARRIERID,T1.SHIPCARRIERFUELSURCHARGE,T1.SHIPCARRIERBLINDSHIPMENT,

T1.SHIPCARRIERACCOUNTCODE,T1.SYNCENTITYID,T1.SYNCVERSION,

T1.SALESDISTRICTID,T1.SEGMENTID,T1.SUBSEGMENTID,T1.RFIDITEMTAGGING,

T1.RFIDCASETAGGING,T1.RFIDPALLETTAGGING,T1.COMPANYCHAINID,

T1.PARTY,T1.IDENTIFICATIONNUMBER,T1.PARTYCOUNTRY,T1.PARTYSTATE,

T1.DEFAULTDIMENSION,T1.CUSTEXCLUDECOLLECTIONFEE,

T1.CUSTEXCLUDEINTERESTCHARGES,T1.MAINCONTACTWORKER,

T1.CREDITCARDADDRESSVERIFICATION,T1.CREDITCARDCVC,

T1.CREDITCARDADDRESSVERIFICATIONVOID,T1.CREDITCARDADDRESSVERIFICATIONLEVEL,

T1.PBACUSTGROUPID,T1.FEDNONFEDINDICATOR,T1.IRS1099CINDICATOR,

T1.AGENCYLOCATIONCODE,T1.FEDERALCOMMENTS,T1.USEPURCHREQUEST,

T1.MCRMERGEDPARENT,T1.MCRMERGEDROOT,T1.CASHDISCBASEDAYS,

T1.CUSTTRADINGPARTNERCODE,T1.DAXINTEGRATIONID,T1.DEFAULTDIRECTDEBITMANDATE,

T1.DEFAULTINVENTSTATUSID,T1.ENTRYCERTIFICATEREQUIRED_W,

T1.EXPRESSBILLOFLADING,T1.ISSUEOWNENTRYCERTIFICATE_W,T1.PDSCUSTREBATEGROUPID,

T1.PDSFREIGHTACCRUED,T1.PDSREBATETMAGROUP,T1.USECASHDISC,

T1.FIELD1,T1.MODIFIEDDATETIME,T1.DEL_MODIFIEDTIME,T1.MODIFIEDBY,T1.CREATEDDATETIME,

T1.DEL_CREATEDTIME,T1.RECVERSION,T1.PARTITION,T1.RECID,

T1.MEMO FROM CUSTTABLE T1 WHERE ((PARTITION=?) AND (DATAAREAID=?))

  1. Sorguda gördüğünüz gibi AccountNum filtresi verilmiyor. Değişkene değer verip tekrar çalıştırırsanız filtrenin eklendiğini görebilirsiniz. Değerlerin görünmemesi normal. SQL üzerinden bakarsanız değerleri de görebilirsiniz.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM, X++, Query, Filter

Dynamics 365 Finance and Operations: Seçilen çoklu kayıtları formlar arasında transfer etme.

Bu yazıda Dynamics 365 Finance and Operations içinde bir formda seçilen çoklu kayırları faklı bir forma nasıl aktarabiliriz anlatmaya çalışacağım.

Bu örnekte iki formum var. Birinci forma bir buton ekleyip clicked metodunu eziyorum.

public void clicked()

{

VendPackingSlipJour vendPackingSlipJourSelected;

container           con;

Args                args;

str                 packingSlipIds;

;

// For döngüsü ile veri kaynağında seçilen kayıtları dolaşabiliyorum. Bunu faklı döndülerlede yapabilirsiniz.

for (vendPackingSlipJourSelected = VendPackingSlipJour_ds.getFirst(true) ? VendPackingSlipJour_ds.getFirst(true) : VendPackingSlipJour_ds.cursor();

vendPackingSlipJourSelected; vendPackingSlipJourSelected = VendPackingSlipJour_ds.getnext())

{

con = conIns(con,1,vendPackingSlipJourSelected.PackingSlipId); // Sonrasında bir contanier oluşturuyorum.

packingSlipIds = con2Str(con,”,”);

}

args = new Args();

args.parm(packingSlipIds);

new MenuFunction(menuitemDisplayStr(DmrVendInvoicePost), MenuItemType::Display).run(args);

// MenuFunction kullanarak ikinci formu açıyorum.

}

Şimdi ikinci formda ilk formda seçtiğim kayıtlara nasıl ulaşıyorum bakalım.

public void init()

{

int                 i;

str                 packingSlipIds;

super();

isRecordExists = false;

packingSlipIds = element.args().parm();  // args ile oluşturduğumuz string değişkene ulaşıyoruz.

con = str2con(packingSlipIds,”,”); // Containera alıyoruz.

for(i = 1; i<= conLen(con) ; i++)

{

// Döngüye sokup range olarak veriyorum. Aslında virgül ile oluşturduğum için direk range olarak ta verebilirim.

DmrPurchParmTable_ds.query().dataSourceTable(tableNum(DmrPurchParmTable)).addRange(fieldNum(DmrPurchParmTable , PackingSlipId)).value(SysQuery::value(conPeek(con,i)));

}

}

Bu yazıda iki forma arasında çoklu seçilmiş kayıtları nasıl aktarabilirsiniz anlatmaya çalıştım.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM, X++

Dynamics 365 Finance and Operations LedgerDimension ve Segmented Entry nasıl eklenir?

Bu yazıda Dynamics 365 Finance and Operations içinde bir tabloya LedgerDimension nasıl eklenir ve bu alanı formda Segmented entry control ile nasıl kullanıcıya kullandırabiliriz anlatmaya çalışacağım.

LedgerDimension aslında DimensionAttributeValueCombination kaydıdır. LedgerDimension MainAccount ve DefaultDimension’ın bileşimidir.

Öncelikle Tabloya LedgerDimensionAccount EDT sini kullanarak bir alan ekleyelim. Eğer sürükle bırak ile eklerseniz otomatik ilişkiyi oluşturacak. Yoksa elle eklemeniz gerekir.

Resim-1

Sonrasında forma gelip eklediğimiz alanı tasarımda istediğimiz bir yere sürükleyip bırakıyoruz. Segmented Entry oluşuyor. Özelliklerinde resimde görünen tanımları yapmalıyız. Özellikle Controller Class çok önemli.

Resim-2

Derleyip çalıştırdığımızda formda alanımızı göreceğiz. DefaultAccount ile aradaki farkı görebilirsiniz. Sadece Main Account değil boyutlarda geliyor ve bir kombinasyon oluşturuluyor.

Resim-3

Oluşan verileri Sql üzerinden incelediğimizde aradaki fark çok net bir şekilde ortaya çıkıyor.

Resim-4

Bu yazıda LedgerDimension nedir ve nasıl eklenir anlatmaya çalıştım. Sonraki yazılarımda bunları kodda nasıl kullanıp birbirlerine çeviriyoruz anlatmaya devam edeceğim.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, DefaultAccount, LedgerDimension, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Dynamics 365 Finance and Operations LedgerDimension Yeni Bir Finansal Boyut Nasıl Eklenir?

Bu yazıda Dynamics 365 Finance and Operations için yeni bir finansal boyut nasıl eklenir anlatmaya çalışacağım.

Hazırda olan boyut seçeneklerini görmek için General ledger-> Chart of accounts -> Dimensions -> Financial dimensions formunu açıyoruz.

Resim-1

Bu formda hazırda kurulmuş boyutlar geliyor. New ile yeni boyut oluşturuyoruz. Açılan listeden istediğimizi seçebiliriz. Bu yazıda ben bu listeye nasıl ekleme yaptığımızı anlatacağım.

Resim-2

Bu örnekte standart bir tabloyu boyut haline getirmeyi göstereceğim. Örnek olarak BankGroup tablosunu seçtim. Tamamen yeni bir tablo da kullanabilirsiniz.

Öncelikle bir View oluşturmak gerekiyor. Aşağıdaki yapının aynı olmalı yazım hataları bile listede görünmesini engelleyecektir. İsmi DimAttribute ile başlamalı. DataSoruce’a kendi tablomuzu ekleyip ismini BackingEntity yapmalısınız.

3 alana ihtiyaç var.

  1. Key     : RecId
  2. Value : BankGroupId
  3. Name : Name

Resim-3

Yeni bir metot ekleyip View ismini yazıyoruz.

Resim-4

Bu haliyle derleme ve eşitleme yaptığınızda listede göremeyeceksiniz. Eğer Debug modda açarsanız hatayı görebilirsiniz. Boyut olacak tablo için mutlaka RecId nin bir tekil index’te ilk sırada olmasını bekliyor.

VendGroup tablosunda RecId Index oluşturulmamış. Entension ile de değiştiremiyoruz. Bu yüzden yeni bir index oluşturdum. Burada sorun tek başına RecId ye izin vermiyor. Mecbur başka bir alanla eklemem gerekti.

Resim-5

Bu işlemlerden sonra derleme ve eşitleme yaparsanız listeye geldiğini görebilirsiniz. Eğer listeye gelmiyorsa mutlaka Debug modda çalıştırın sorunlu View de hatayı gösterecektir.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, DefaultAccount, LedgerDimension, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Standart Tabloların initFrom…() Metodlarına Extension ile Nasıl Ekleme Yapılır?

Bu yazıda Extension kullanımını faklı bir örnek vereceğim. Bir örnekle açıklayayım. SalesTable ve CustInvoiceJour’a bir alan açtım ve fatura oluştuğunda bu alan SalesTable’dan CustInvoiceJour’a taşınsın istiyorum.

Eski versiyonda bu çok kolaydı CustInvoiceJour-> initFromSalesTable() metoduna bir satır ekleyip işi çözebilirdiniz. Yeni mantıkla birlikte bir Extension sınıfı yazıp onun içinde halletmek zorundasınız.

Resim-1

Sınıfı oluşturup aşağıdaki gibi bir iki metot yazdım. Ben iki faklı metodu aynı sınıfta düzenledim. Burada dikkat etmeniz gereken iki konu var. Birincisi PostHandlerFor kullanımı. Bu standart metot bitince buraya girecek demek. İkincisi getArgs() ile aldığım salesTable değişkeni. Burada standart metottaki değişkenle aynı isimde olmalı yoksa çalışmaz. Ben direk _ kullanılmıştır diye düşünüp ekledim çalışmadı sonra bakınca fark ettim standart metot kullanmamış.

Resim-2

Bu yazıda initFrom metotlarına Extension ile nasıl ekleme yapabileceğinizi anlatmaya çalıştım. Eskiye nazaran biraz daha uzun bir işlem buda geliştirme sürelerini arttırıyor.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps,  initFrom, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Muhasebe günlüklerinden mahsup hesap boyutunun hesap boyutundan gelmesi nasıl engellenir?

Bu yazıda Türkiye muhasebe ekiplerince mutlaka istenen bir geliştirmeyi D365 te nasıl yaptık anlatmaya çalışacağım. Talep aslında çok basit belki de parametrik olması gerekiyor. Şöyle bir örnek olsun. Bir günlük açtınız ve hesap tipi banka seçip Bnk0001 seçtiniz. Otomatik olarak bu bankanın boyutları hesap boyutlarına atandı. Mahsup tarafa gelip orada da tipi banka ve hesabı Bnk0002 seçtiniz. Bu durumda mahsup boyutunu hesap üzerinden alıyor Mahsup banka boyutlarını getirmiyor. Talep mahsup tarafta ne seçersem onun boyutları gelsin hesaptan direk almasın.

Ax2012’de bu çok basit bir işlemdi burayı dolduran kısmı bulup değiştirmek yeterliydi ancak D365 te işler biraz değişti.

Önce Ax2012’de ne yapıyorduk ona bakalım. LedgerJournalEngine sınıfında initOffsetDefaultDimensionServer metodunun boyadığım satırı kapatmak boyutun hesap boyutundan alınmasını engelliyordu. Tek satır işlemle aşağı yukarı istediğimiz oluyor. Ancak D365’te buna müdahale şansımız yok. Bu metot private ve sınıfta AplicationSuit’te dolayısıyla bize değiştirme imkânı vermiyor.

Resim-1

Bu talebin nasıl yapılacağını incelerken initOffsetDefaultDimension metodunun Extension için uygun olduğunu gördüm.

Resim-2

İşimi halledebilmek için Bir Extension sınıfı oluşturup iki metot ekledim. Birincisi initOffsetDefaultDimension metodunun Extension ile öncesi ve sonrasına kod yazma imkânı veren hali. İkincisi ise mahsup hesaba göre boyutu getiren, standarttan kopyaladığım ve içeriğini mahsup boyuta göre düzenlediğim boyut bulma metodu.

Resim-3

Derleyip çalıştırdığımızda test edebilirsiniz. Aşağıdaki gibi bir günlükte Mahsup banka boyutunu hesap banka boyutundan farklı gelmesi gerekiyor.

Resim-4

Financial dimensions’a tıklayarak mahsup boyutları açabilirsiniz.

Resim-5

Bu yazıda Extension kullanımına örnek olacak bir talebi nasıl yaptığımı anlatmaya çalıştım. Eskiye nazaran işler biraz daha zor görünmekle birlikte genelde çözümsüz değil. Sadece daha çok zaman alıyor ama getirileri düşünüldüğünde kesinlikle buna değer.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, DefaultAccount, LedgerDimension, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Dynamics 365 Finance and Operations LedgerDimension ve Segmented Entry nasıl eklenir?

Bu yazıda Dynamics 365 Finance and Operations içinde bir tabloya LedgerDimension nasıl eklenir ve bu alanı formda Segmented entry control ile nasıl kullanıcıya kullandırabiliriz anlatmaya çalışacağım.

LedgerDimension aslında DimensionAttributeValueCombination kaydıdır. LedgerDimension MainAccount ve DefaultDimension’ın bileşimidir.

Öncelikle Tabloya LedgerDimensionAccount EDT sini kullanarak bir alan ekleyelim. Eğer sürükle bırak ile eklerseniz otomatik ilişkiyi oluşturacak. Yoksa elle eklemeniz gerekir.

Resim-1

Sonrasında forma gelip eklediğimiz alanı tasarımda istediğimiz bir yere sürükleyip bırakıyoruz. Segmented Entry oluşuyor. Özelliklerinde resimde görünen tanımları yapmalıyız. Özellikle Controller Class çok önemli.

Resim-2

Derleyip çalıştırdığımızda formda alanımızı göreceğiz. DefaultAccount ile aradaki farkı görebilirsiniz. Sadece Main Account değil boyutlarda geliyor ve bir kombinasyon oluşturuluyor.

Resim-3

Oluşan verileri Sql üzerinden incelediğimizde aradaki fark çok net bir şekilde ortaya çıkıyor.

Resim-4

Bu yazıda LedgerDimension nedir ve nasıl eklenir anlatmaya çalıştım. Sonraki yazılarımda bunları kodda nasıl kullanıp birbirlerine çeviriyoruz anlatmaya devam edeceğim.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, DefaultAccount, LedgerDimension, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Dynamics 365 Finance and Operations Test ortamı Canlı veri tabanıyla nasıl ezilir?

Bu yazıda Dynamics 365 Finance and Operations Sandbox ortamını canlı veri ile nasıl ezeriz adım adım anlatacağım.

LCS’e girip projemizi acıyoruz. Sandbox detaylarını tıklıyoruz.

Resim-1

Maintain->Move database diyoruz.

Resim-2

Farklı seçenekler karşımıza çıkıyor.

Export database: Sandbox ortamının verisini dışarı aktarır.

Import database: bacpac formatında bir db’yi içeri aktarır.

Point-im-time restore Prod to Sandbox: Canlı ortamdan yedeklenmiş veri tabanını teste ezer. Biz bu seçenek ile devam edeceğiz.

Point-in-time restore: Test ortamının önceki yedeklerinden ezme yapar.

Refresh database: Başka bir sandbox ortamından ezme yapar.

Resim-3

Kaynak ve hedefe dikkat etmek lazım. Zamanı ayarladıktan sonra kabul edebilirsiniz.

Resim-4

Bir onay ekranı çıkacak.

Resim-5

24 saat diyor ama genelde benim gördüğüm daha kısa sürede bitiyor.

Resim-6

İşlem başlayınca durum Servicing’e geçiyor. Bitmesini beklemelisiniz.

Resim-7

Bu aşamalardan sonra işlem bitmiş oluyor. Eski versiyonlara göre çok daha kolay bir işlem oluyor.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Dynamics 365 Finance and Operations Form Lookup Nasıl Yapılır?

Bu yazıda Dynamics 365 Finance and Operations içinde bir formun nasıl lookup olarak kullanılabileceğini anlatacağım. Öncelikle neden lookup olarak forma ihtiyaç duyarız ona bakalım. Kodla yaptığımız lookuplarda birkaç kısıntımız var. Birincisi tasarım. Form olduğunda tasarım için çok esnek bir yapımız oluyor ama diğerinde böyle bir imkânı yok. Veri kaynağı yönetimi ve parametrik olarak farklı çalışma özellikleri yine form olunca mevcut. Gelelim nasıl yapıldığına.

Öncelikle yeni bir form oluşturuyoruz. Lookup- Basic desenini uyguluyoruz.

Resim-1

Veri kaynağını ekliyoruz. Tasarıma bir Grid ekleyip gerekli alanları sürükleyip bırakıyoruz.

Resim-2

Run metoduna hangi alanı geri döndürmek istiyorsak onu ekliyoruz. Burada direk girdde oluşturduğumuz nesnenin adını kullanmak gerekiyor. Bu yüzden AutoDecleration yes olmalı.

Resim-3

Form ile işimiz bitti. Şimdi İlgili EDT de Form help kısmından formumuzu seçiyoruz. Artık bu EDT’nin kullanıldığı yerlerde otomatik olarak bizim form lookup olarak açılacak.

Resim-4

Deneme için bir tabloya alanı açıyoruz.

Resim-5

Forma alanı ekleyip çalıştırıyoruz.

Resim-6

Son olarak formda oluşturduğumuz lookupı görebiliriz.

Resim-7

Bu yazıda lookup olarak bir form nasıl yaparız anlatmaya çalıştım. Lookup yapmanın çok fazla yolu var hangisi hangi durumda kullanılmalı dikkat etmek lazım.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, Lookup, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Depoda toplanan ürünün yerine geri koyulmasını ve sevkiyatının iptal edilmesini kodla nasıl yaparız?

Bu yazıda Dynamics 365 Finance and Operations içinde depo yönetimi modülünde toplanan bir ürünün kodla yerine koyulması ve sevkiyatın iptal edilmesinin nasıl yapılacağını anlatacağım.

Aslında bu işlemi ekran üzerinden tek tek yapabiliyoruz.  Load Line formunu açıp Reduce picked quantity’ye tıklıyoruz.

Resim-1

Açılan formda miktarı ayarlayıp Ok dediğimizde aslında bu işlemi yapmış oluyoruz.

Resim-2

Benim burada yapacağım bu işlemi toplu yapmak için bir kod yamak olacak. Bir sebepten otomatik toplanan bazı siparişlerin iptali gerektiğinde elle tek tek yapmak çok uzun süreceğinden böyle bir koda ihtiyaç oldu. Öncelikle Ax2012’de bu işlem için Güven arkadaşım şu makaleyi yazmış. Benim işimi tam çözmüyor. Ben bir dosyadan beri okuyup D365 te bu işlemi yapmak istiyorum.

Öncelikle WhsUnShip sınıfından bir Extension sınıfı oluşturmam gerekti.  BuildTmpTable aslında Ax2012 olan bir metottu ama D365 te kullanamıyoruz.

[ExtensionOf(classStr(WhsUnShip))]

final class WhsUnShip_Extension

{

public WHSTmpLoadLineInventory dmrBuildTmpTable(WHSLoadLine _loadLine = loadLine)

{

WHSTmpLoadLineInventory     tmpLoadLineInv;

WHSWorkLine                 workLine;

WHSWorkLine                 putWorkLine;

WHSWorkTable                workTable;

WHSDimTracking              dimTracking;

InventDim                   inventDim;

Qty                         closedContainerQty;

InventDim                   inventDimId;

SalesLine                   salesLine;

InventTransferLine          transferLine;

InventDim                   loadLineInventDim;

boolean                     putIsPackingStation;

WHSWorkId                   lastWHSWorkId;

WMSLocation                 wmsLocation;

boolean                     hasDimTracking;

// Set LoadLine if specified.

loadLine = _loadLine;

loadLineInventDim = loadLine.inventDim();

switch (loadLine.InventTransType)

{

case InventTransType::Sales:

salesLine = loadLine.getOrderCommonFromLoadLine() as SalesLine;

break;

case InventTransType::TransferOrderShip:

transferLine = loadLine.getOrderCommonFromLoadLine() as InventTransferLine;

break;

}

while select InventQtyWork, ItemId, LineNum, WorkId, ContainerId from workLine

order by workLine.WorkId

where workLine.LoadLineRefRecId  == loadLine.RecId &&

workLine.WorkStatus        == WHSWorkStatus::Closed

join WorkId, TargetLicensePlateId, InventLocationId from workTable

where workTable.WorkId       == workLine.WorkId &&

workTable.WorkStatus   == WHSWorkStatus::Closed

{

if (lastWHSWorkId != workLine.WorkId)

{

select firstonly wmsLocationId from putWorkLine

order by putWorkLine.LineNum desc

where putWorkLine.WorkId     == workTable.WorkId        &&

putWorkLine.WorkStatus == WHSWorkStatus::Closed   &&

putWorkLine.WorkType   == WHSWorkType::Put

join LocProfileId from wmsLocation

where wmsLocation.wMSLocationId == putWorkLine.wmsLocationId &&

wmsLocation.InventLocationId == workTable.InventLocationId;

putIsPackingStation = wmsLocation.LocProfileId == parameters.PackingLocType;

lastWHSWorkId = workLine.WorkId;

}

hasDimTracking = false;

// If the workLine uses dim tracking we must use those values.

while select InventDimId, Qty from dimTracking

where dimTracking.WorkId    == workLine.WorkId

&&    dimTracking.LineNum   == workLine.LineNum

{

hasDimTracking = true;

inventDim = InventDim::find(dimTracking.InventDimId);

inventDim.wmsLocationId = putWorkLine.wmsLocationId;

if (WMSLocation::find(inventDim.wmsLocationId, inventDim.InventLocationId).whsLocationIsLPControlled())

{

inventDim.LicensePlateId = workTable.TargetLicensePlateId;

}

inventDim = InventDim::findOrCreate(inventDim);

// If put location is a packing station, then we need to look for closed containers that may have moved inventory.

if (putIsPackingStation)

{

InventDimParm       inventDimParm;

InventDim           joinInventDim;

InventDim           inventDimMethod;

WHSContainerLine    containerLine;

WHSContainerTable   containerTable;

inventDimParm.initFromInventDim(inventDim);

// Loop over container lines for closed containers

while select containerLine

where containerLine.LoadLine    == loadLine.RecId

join InventDimId, ContainerId from containerTable

where containerTable.ContainerId        == containerLine.ContainerId

&&    containerTable.ContainerStatus    == WHSContainerStatus::Closed

#InventDimExistsJoin(containerLine.inventDimId, joinInventDim, inventDim, inventDimParm)

{

tmpLoadLineInv.InventQty = InventTableModule::unitConvert(containerLine.ItemId, ModuleInventPurchSales::Invent, containerLine.UnitId, containerLine.Qty);

inventDimMethod = containerLine.mergedClosedInventDim();

tmpLoadLineInv.InventDimId = inventDimMethod.InventDimId;

tmpLoadLineInv.RefRecId = loadLine.RecId;

tmpLoadLineInv.ContainerId = containerTable.ContainerId;

tmpLoadLineInv.insert();

closedContainerQty += tmpLoadLineInv.InventQty;

}

}

if (dimTracking.Qty > closedContainerQty)

{

tmpLoadLineInv.clear();

tmpLoadLineInv.InventQty = dimTracking.Qty – closedContainerQty;

tmpLoadLineInv.InventDimId = inventDim.InventDimId;

tmpLoadLineInv.RefRecId = loadLine.RecId;

tmpLoadLineInv.ContainerId = workLine.ContainerId;

tmpLoadLineInv.insert();

}

}

if (!hasDimTracking)

{

inventDim.clear();

inventDim.initFromInventDim(loadLineInventDim);

inventDim.wmsLocationId = putWorkLine.wmsLocationId;

if (WMSLocation::find(inventDim.wmsLocationId, inventDim.InventLocationId).whsLocationIsLPControlled())

{

inventDim.LicensePlateId = workTable.TargetLicensePlateId;

}

inventDim = InventDim::findOrCreate(inventDim);

// If put location is a packing station, then we need to look for closed containers that may have moved inventory.

if (putIsPackingStation)

{

InventDimParm       inventDimParm;

InventDim           joinInventDim;

InventDim           inventDimMethod;

WHSContainerLine    containerLine;

WHSContainerTable   containerTable;

inventDimParm.initFromInventDim(inventDim);

// Loop over container lines for closed containers

while select containerLine

where containerLine.LoadLine    == loadLine.RecId

join InventDimId, ContainerId from containerTable

where containerTable.ContainerId        == containerLine.ContainerId

&&    containerTable.ContainerStatus    == WHSContainerStatus::Closed

#InventDimExistsJoin(containerLine.inventDimId, joinInventDim, inventDim, inventDimParm)

{

tmpLoadLineInv.InventQty = InventTableModule::unitConvert(containerLine.ItemId, ModuleInventPurchSales::Invent, containerLine.UnitId, containerLine.Qty);

inventDimMethod = containerLine.mergedClosedInventDim();

tmpLoadLineInv.InventDimId = inventDimMethod.InventDimId;

tmpLoadLineInv.RefRecId = loadLine.RecId;

tmpLoadLineInv.ContainerId = containerTable.ContainerId;

tmpLoadLineInv.insert();

closedContainerQty += tmpLoadLineInv.InventQty;

}

}

if (workLine.InventQtyWork > closedContainerQty)

{

tmpLoadLineInv.clear();

tmpLoadLineInv.InventQty = workLine.InventQtyWork – closedContainerQty;

tmpLoadLineInv.InventDimId = inventDim.InventDimId;

tmpLoadLineInv.RefRecId = loadLine.RecId;

tmpLoadLineInv.ContainerId = workLine.ContainerId;

tmpLoadLineInv.insert();

}

}

}

return tmpLoadLineInv;

}

public WHSLoadLine parmLoadLine(WHSLoadLine _loadLine = loadLine)

{

loadLine = _loadLine;

return loadLine;

}

}

Sonrasında asıl işi yapan sınıfı yazdım. Burada bir csv dosyasından veri okuyup ilgili kaydı bulup iptal işlemini yapan kod var.

class DmrUnsipLoadCsv

{

public static void main(Args _args)

{

DmrUnsipLoadCsv DmrUnsipLoadCsv;

DmrUnsipLoadCsv = new DmrUnsipLoadCsv();

DmrUnsipLoadCsv.run();

}

void run()

{

whsworkid       whsworkid;

container   rec;

Array                               fileLines;

Counter                             counter = 0;

AsciiStreamIo                       file;

InventTable                         inventTable;

FileUploadTemporaryStorageResult    fileUpload;

#OCCRetryCount

//conPeek(rec, 3);

try

{

fileUpload  = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

file        = AsciiStreamIo::constructForRead(fileUpload.openResult());

if (file)

{

if (file.status())

{

throw error(“@SYS52680″);

}

file.inFieldDelimiter(“;”);

file.inRecordDelimiter(“\r\n”);

}

while (!file.status())

{

counter++;

rec = file.read();

if (conLen(rec))

{

whsworkid = conPeek(rec, 1);

ttsbegin;

this.unship(whsworkid);

ttscommit;

//info(strFmt(“%1″,conPeek(rec, 1)));

}            }

// info(“Aktarım tamamlandı.”);

}

catch (Exception::Deadlock)

{

retry;

}

catch (Exception::UpdateConflict)

{

if (appl.ttsLevel() == 0)

{

if (xSession::currentRetryCount() >= #RetryNum)

{

throw Exception::UpdateConflictNotRecovered;

}

else

{

retry;

}            }

else

{

throw Exception::UpdateConflict;

}

}

}

void unship(whsworkid _whsworkid )

{

WHSWorkLine             WHSWorkLine;

WHSWorkLine             WHSWorkLineLocation;

WHSUnShip               WHSUnShip;

WHSTmpLoadLineInventory tmpLoadLineInv;

WHSLoadLine             WHSLoadLine;

;

while select WHSWorkLine

group by LoadLineRefRecId

where WHSWorkLine.WorkId == _whsworkid

&&    WHSWorkLine.WorkType == WHSWorkType::Pick

&&    WHSWorkLine.WorkStatus == WHSWorkStatus::Closed

{

WHSLoadLine = WHSLoadLine::findbyRecId(WHSWorkLine.LoadLineRefRecId);

WHSUnShip = null;

WHSUnShip = new WHSUnShip();

tmpLoadLineInv = null;

tmpLoadLineInv = WHSUnShip.dmrbuildTmpTable(WHSLoadLine);

while select tmpLoadLineInv

{

select WHSWorkLineLocation

where WHSWorkLineLocation.LoadLineRefRecId == WHSLoadLine.RecId;

WHSUnShip.parmMoveToLocation(WMSLocation::find(WHSWorkLineLocation.WMSLocationId,InventDim::find(WHSWorkLineLocation.inventDimId).inventLocationId));

WHSUnShip.parmDecrementLoadLine(true);

WHSUnShip.unShip(

InventDim::find(tmpLoadLineInv.InventDimId),

tmpLoadLineInv.InventQty, // qty to reduce

WHSLoadLine,

tmpLoadLineInv.ContainerId,

tmpLoadLineInv.InventQty);

}

//info(_whsworkid);

}

info(_whsworkid);

}

}

Bu kodları kullanacaksanız mutlaka canlıdan önce bir ortamda test etmelisiniz. Her kurulum farklı olabilir verilerinizde sorun oluşturma ihtimali olabilir dikkatli olmak lazım. Biz baya test ettik sonunda işimizi gördüğünü düşündük ve canlı ortamda çalıştırdık. Umarım sizin de işinize yarar.

Selamlar.

www.fatihdemirci.net

TAGs: Microsoft Life Cycle Services, LCS, Azure, Azure DevOps, WmsUnShip, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365, Segmented Entry, Power Automate, Power Apss, Power Virtual Agents, Dynamics 365 nedir, Dynamics 365 ERP, Dynamics 365 CRM

Page 1 of 712345...Last »