16 Aralık 2016 Cuma

Yetkileri, Kullanıcı Grubu ve Kişilerini Bir Formda Toplama

Dynamic Ax 2009'da Kullanıcı Grupları ve Kullanıcıları Bir Forma Çekip Kullanma


Dynamics Axapta 2009'da kullanıcı grupları ve içindeki kullanıcılar aynı tabloda tutulmadığı için, bir kullanıcının hangi grupta olduğunu ancak kullanıcı gruplarından bakıp tek tek görebiliyoruz.

Birçok kullanıcı ve grup olduğunu düşünürsek tek tek bakmak sıkıcı olabiliyor.

Öncelikle verileri bir alanda toplamak için  MAA_UserGroupList adında yeni bir tablo oluşturdum.

Kullanıcı grubu için gerekli bilgileri UserGroupListUserGroupInfo, UserInfo tablolarından çekeceğiz.
UserGroupList'ten  groupId ve userId alanlarını, UserGroupInfo'dan name ve company,  UserInfo'dan name alanlarına ulaşıp kendi oluşturduğumuz MAA_UserGroupList  tablosuna verileri çekeceğiz.
Bu tabloları standart Tables'ın içinden göremiyoruz.


Projemize bir form ve DataSource'una MAA_UserGroupList  tablosunu ekliyoruz.
Verileri çekmemiz için forma buton ekliyoruz.

Butonun click metoduna aşağıdaki kodu;

void clicked()
{
    element.getuser(); // buton tıklandığında getuser metodu çalışacak
    MAA_UserGroupList_ds.research(); // Güncel veriler eklendiğinde otomatik refresh yapar.
}

getuser kısmına da aşağıdaki kodu ekliyoruz;

void getuser()
{
      UserGroupInfo       UserGroupInfo;
      UserGroupList       UserGroupList;
      MAA_UserGroupList   maa_UserGroupList ;
      UserInfo            UserInfo;
      ;
delete_from maa_UserGroupList ;
    while select UserGroupInfo join UserGroupList
        where UserGroupInfo.Id == UserGroupList.groupId
         {
            select  UserInfo
                where  UserInfo.id == UserGroupList.userId;
                    {
                         maa_UserGroupList .clear();
                         maa_UserGroupList .groupId   =  UserGroupList.groupId;
                         maa_UserGroupList .userId    =  UserGroupList.userId;
                         maa_UserGroupList .GroupName =  UserGroupInfo.name;
                         maa_UserGroupList .company   =  UserInfo.company;
                         maa_UserGroupList .UserName  =  UserInfo.name;
                         maa_UserGroupList .insert();
                     }
             info(strfmt("%1 %2 %3 %4", maa_UserGroupList .groupId, maa_UserGroupList .userId, maa_UserGroupList .GroupName, maa_UserGroupList .UserName));
          }
}

Burada istediğimiz verileri tablomuza çektik ve formumuza da eklenmiş oldu. Artık hangi grupta kim var ya da bir kişi hangi grup ya da gruplarda görebiliriz.

Bu forma başka neler ekleyebiliriz?

Formda işimizi daha da kolaylaştıracak, İzinler(kişinin ya da grubun yetkilerini ayarladığımız alan)
ve Kayıt düzeyi güvenliği menülerinin Relation'unu ayarlayıp ekleyebilirsiniz.

Bu sayede yetki kontollerini tek formda birleştirip yapabilirsiniz.





1 Aralık 2016 Perşembe

Ana Tablo Formuna Git | Dynamic Ax 2009

Örneğin sizden Teminat Mektuplarında AccountNum alanından CustTable'daki CustAccount alanına gidilmesi istendi.

Formun Data Source'undaki ilgili alanın methots'unda jumpRef'ini Yöntemi gereçersiz kıl diyerek aşağıdaki kodu eklemeniz yeterli olacaktır.
public void jumpRef()
  {
    CustTable custTableMainTable;
    Args args;
    MenuFunction menuFunction;
    ;
    args = new Args();
    args.caller(element);
    args.lookupfield(FieldNum(CustTable,AccountNum));
    args.lookupValue(ETGCollateralTable.AccountNum);
    menuFunction = new MenuFunction(MenuItemDisplayStr(custTable),MenuItemType::Display);
    menuFunction.run(args);
  }

3 Kasım 2016 Perşembe

Dynamic Ax'ta kullanıcıların saat dilimlerinin ayarlanması

Ax'ın içindeki "Tercih edilen saat dilimi" alanının her bir kullanıcı için güncellenmesi gerekirse,
bunu aşağıdaki kod yardımıyla, bütün aktif Ax kullanıcıları için yapabilirsiniz.

static void MAAUserInfoPrefTime(Args _args)
{
    UserInfo  UserInfo;

    ttsBegin;

      while select forupdate UserInfo
        where  UserInfo.enable == NoYes::Yes

        if(UserInfo)
            {
                UserInfo.preferredTimeZone = Timezone::GMTPLUS0300BAGHDAD; // istediğiniz saat dilimini burdan ayarlayabilirsiniz.
                UserInfo.doUpdate();
            }

    ttsCommit;

    info("bitti");
}





UserInfo Table hakkında detaylı bilgiyi bu linkten alabilirsiniz. 

                         https://msdn.microsoft.com/en-us/library/aa596081(v=ax.50).aspx

31 Ekim 2016 Pazartesi

Dynamic Ax'ta excelle update yapma

Excelle istediğimiz bir alanı updete yapabiliriz. Bunun için aşağıdaki kodu inceleyebilirsiniz.
static void ExcelUpdate_MAA(Args _args)
   {

    FilenameOpen        filePath;
    SysExcelApplication application;
    SysExcelWorkBooks   workBooks;
    SysExcelWorkBook    workBook;
    SysExcelWorkSheets  workSheets;
    SysExcelWorkSheet   workSheet;
    SysExcelCells       cells;

    Int                     NoofSheet,i,sn;
    LedgerJournalACType     LedgerJournalACType;
    CustTrans      custtrans;

    ;
    #Excel

    filePath            = "C:\\Desktop\\maakbulut\\ax_excel\\FiyatFarkıFaturaRaporu.xlsx"; // kendi oluşturduğumuz excelin adresini veriyoruz.
    application         = SysExcelApplication::construct();
    application.visible(false);
    workBooks           = application.workbooks();
    workBooks.open(filePath,0,true);
    workSheets          = workBooks.item(1).worksheets();
    noOfSheet           = worksheets.count();

    try
    {
        ttsbegin;

        for( i = 1; i <= 1 ; i++) // noOfSheet
        {
            workSheet       = workSheets.itemFromNum(i);
            if(workSheet)
            {
                for(sn = 2;sn <= 337;sn++) // 2. satırdan başlayıp 337. satıra kadar olan verileri alacak
                {
                    custtrans.clear();

                    cells = workSheet.cells();

                    select forupdate custtrans where custtrans.Voucher == cells.item(sn,1).value().bStr();
                    if (custtrans)
                    {
                         custtrans.Dimension[5]      = "Hediye"; // Şartımız Dimension[5] alanı Hediye olanlar
                         custtrans.doUpdate();
                    }
                }
            }
        }
        ttscommit;
        info("İşlem tamamlandı.");
    }
    catch
    {
        ttsabort;
        info("Hata oluştu.");
    }
    application.quit();
} 

12 Ekim 2016 Çarşamba

Dynamic Ax'ta Formu Yüklenirken Enum'da sizin belirleyeceğiniz seçeneğe göre gelmesi

Sizden form yüklenirken enum'daki istenilen bir alana göre açılması istenirse;


Örneğin bu formda bizden form açılırken Hareket Tipi "Alım" olanlar gelsin diye talep edildi.

Bunun için;

Önce formun ClassDeclaration bölümüne tanımlama yapıyoruz.
public class FormRun extends ObjectRun
{
     QueryBuildRange             qbrStatus;
}

Daha sonra yine formun init'ine şu kodu yazıyoruz.

 qbrStatus.value(SysQuery::value(ETGCollateralPostingType::Receive));

  //  "ETGCollateralPostingType" bu alan Hareket Tipi enum'unun adı.
Şimdi form açılırken Hareket tipi "Alım" olanlar gelecek.


Aşağıdaki kod da form ile enum'daki Hareket Tipi alanını "Alım" olarak ayarlar.
Yapılmazsa Enum'ın ilk sırasındaki seçenek gelir.

filterStatus.selection(ETGCollateralPostingType::Receive);

Dynamic Ax'ta form açıldığında ilk kaydın gelmesi

Sizden form açıldığında ilk kaydın gelmesi istenirse yapacağınız iş çok basit.





Formun data sources kısmından ilgili data source'u sağ tıklayıp özellilker - StartPosition alanını
First yaparsak ilk kayıttan başlayacaktır.



Last yaparsak da son kayıt seçili gelecek.

30 Eylül 2016 Cuma

Bir alana kontrol ekleme (validateWrite'ını ezerek)

Sizden NoYesId alanının durumuna göre şart konulması istendiğinde, DataSource'unda validateWrite'ına aşağıdaki gibi şart koyarak kontrolünü sağlayabilirsiniz.

Örnek kod:
public boolean validateWrite()
 {
    boolean ret;

    ret = super();


      if ( DRT_ArchiveTrans.NoYesId == NoYes::Yes )
            {
                if (!DRT_ArchiveTrans.Archive_ClosetNumber )
                    return checkfailed ("Dolap no alanını doldurunuz!");

                if (!DRT_ArchiveTrans.ShelfNumber )
                    return checkfailed (" Raf no alanını doldurunuz!");
            }

    return ret;
 }

10 Ağustos 2016 Çarşamba

Hata: Ters işlem yürütülemiyor! (Kapalı hareket düzenleme)

Kapalı hareket düzenlemede "Ters Kaydet"mek istediğimizde,

Ters işlem yürütülemiyor! şeklinde hata alırsanız.
CustInvoiceTable'da PreInvoiceId alanı, satırların bir tanesinde bile boş olursa bu hatayı alırsınız.

Çözüm için tablodaki boş olan PreInvoiceId alanını mutlaka doldurun.

not: Bu alan(PreInvoiceId ) Serbest metin faturası ayrıntılarındaki Matbuu fatura numarası.




Kaynak : https://daxapta.wordpress.com/2016/08/10/

29 Temmuz 2016 Cuma

Tekrar eden kayıtta uyarı verme

                     


Örneğin sizden Tahsilat Belge Numarası alanına, aynı kayıttan girildiğinde ekrana uyarı çıksın
şeklinde bir kontrol konulması istendi.

Bu durumda Formun datasource'unda ilgili alanın validate'ine  aşağıdaki şekilde kod yazabilirsiniz.
public boolean validate()
{
    LedgerJournalTrans  tmpLedgerJournalTrans; // Tablonun adıyla Datasource'u aynı olduğunda tabloyu tanımlamanız gerekiyor. Yoksa Ax bunu algılayamıyor.
 
    boolean ret;

    ret = super();

    select firstonly  tmpLedgerJournalTrans
     where tmpLedgerJournalTrans.DRTDocumentId == LedgerJournalTrans.DRTDocumentId;

   if (tmpLedgerJournalTrans.RecId != 0) // Boş olmayan kayıtlar

            {
                info(strfmt("%1 daha önce kullanıldı!", tmpLedgerJournalTrans.DRTDocumentId));
            }

    return ret;
}
Ax'ı Bilgi Teknolojiler Şef'imiz Murat Bey 'le öğrenmeye çalışıyorum.

https://daxapta.wordpress.com/

16 Haziran 2016 Perşembe

Display alan

Formun içinde olmayan bir alanı farklı bir tablodan display yöntemiyle çekebiliriz.

Örneğin, Açık sipariş satırlarına "İş akışı durumu"'nu getirmemiz istendi.




display WFDummiesWorkflowState dispWFDummiesWorkflowState()
{
    return SalesTable::find(this.SalesId).WFDummiesWorkflowState; // SalesTable’daki SalesId alanı      ile SalesLine’daki SalesId alanıyla süzüyorsun(SalesTable::find(this.SalesId) ).
}

Kodu tablonun Metods  kısmına yazıyoruz.



Daha sonra yazdığımız metodu formda bulunan gride sürükleyip bırakıyoruz.



Gride sürükleyip bıraktığımız alanın DataSource'unu seçiyoruz.



Alan formumuza bu şekide gelmiş oluyor.


15 Haziran 2016 Çarşamba

Dynamic Ax Kodla iş akışı yönlendirmesi

İş akışlarını kod ile yönlendirebilirsiniz.

static void WorkFlowReAssign(Args _args)
{
    WorkflowTrackingStatusTable     trackingStatusTable;
    WorkflowWorkItemTable           workItemTable;
    WorkflowTrackingTable           trackingTable;
    WorkflowTrackingCommentTable    trackingCommentTable;
    WorkflowTrackingArgumentTable   trackingArgumentTable;
    UserId                          newUserId = "akblt"; // Yönlendirilecek olan kişi
    ;

    while select trackingStatusTable where trackingStatusTable.TrackingStatus == WorkflowTrackingStatus::Pending &&
                                           trackingStatusTable.InstanceNumber == "MAA1453" // Örnek kodu
    {
        ttsbegin;
        info(strfmt("%1 - %2", trackingStatusTable.ConfigurationName, trackingStatusTable.InstanceNumber));

        select forupdate workItemTable where workItemTable.RefRecId   == trackingStatusTable.ContextRecId &&
                                   workItemTable.RefTableId    == trackingStatusTable.ContextTableId &&
                                   workItemTable.CompanyId  == trackingStatusTable.ContextCompanyId &&
                                   workItemTable.Status     == WorkflowWorkItemStatus::Pending;

        WorkflowWorkItem::delegateWorkItem(workItemTable.Id, newUserId, "");// birine yetki devretmek için

        select forupdate trackingTable where trackingTable.WorkItemActivityInstanceId == workItemTable.ActivityId;

        select forupdate trackingCommentTable where trackingCommentTable.TrackingId == trackingTable.TrackingId;

        select forupdate trackingArgumentTable where trackingArgumentTable.TrackingId == trackingTable.TrackingId && trackingArgumentTable.DataType == "WorkflowUser";

        info(strfmt("%1 - %2 - %3 - %4", workItemTable.UserId, workItemTable.Subject, workItemTable.Description, workItemTable.SubWorkflowId));
        ttscommit;
    }
}

3 Haziran 2016 Cuma

Satınalma siparişi iptali


Satınalma siparişinin iptal edilmesi istenirse size aşağıdaki kod yardımcı olacak;

static void PurchTableCancel()
{
    PurchTable  PurchTable;
    PurchLine   PurchLine;
    InventTrans InventTrans;
    ;
    ttsbegin;

    select forupdate PurchTable
        where PurchTable.PurchId == "MAA00051615";

    PurchTable.PurchStatus  = PurchStatus::Canceled;
    PurchTable.PurchPoolId = "İptal";
    PurchTable.update();

    while select forupdate PurchLine
        where   PurchLine.PurchId   == PurchTable.PurchId
    {
        InventTrans = InventTrans::findTransId(PurchLine.InventTransId, true);
        InventTrans.StatusReceipt = StatusReceipt::Ordered;//Açık sipariş
        InventTrans.DatePhysical = datenull();
        InventTrans.VoucherPhysical ="";
        InventTrans.CostAmountPhysical = 0;
        InventTrans.CostAmountSecCurPhysical_TR = 0;
        InventTrans.update();

        PurchLine.PurchStatus = PurchStatus::Canceled;//Açık sipariş
        PurchLine.ReturnStatus = ReturnStatusLine::None;
        PurchLine.RemainPurchPhysical = 1;
        PurchLine.RemainInventPhysical = 1;
        PurchLine.RemainPurchFinancial = 0;
        PurchLine.RemainInventFinancial = 0;

        PurchLine.PurchStatus = PurchStatus::Canceled;
        PurchLine.doUpdate();
    }
    ttscommit;
    info("bitti");
}

Insert / Delete metodu

Adres defterine ilçe eklenmesi istenirse aşağıdaki job'la bunu yapabilirsiniz.

static void MAATestTableInsertAdress(Args _args)
{
    AddressCounty  AddressCounty;

    ttsBegin;

    AddressCounty.CountryRegionId= "Türkiye";
    AddressCounty.StateId= "Zonguldak";
    AddressCounty.CountyId  = "Ereğli";
    AddressCounty.insert();
    ttsCommit;
    info("bitti");
}



Bir tabloya kodla kayıt eklemek için insert metodunu kullanabilirsiniz.

static void MAATestTableInsert(Args _args)
{
    NumberSequenceReference  NumberSequenceReference;

    ttsBegin;

    NumberSequenceReference.NumberSequence= "IsTakipNo";
    NumberSequenceReference.WizardHighest= 999999;
    NumberSequenceReference.DataTypeId  = 30308;
    NumberSequenceReference.doInsert();
    ttsCommit;
    info("bitti");
}


Bir tablodan kayıt silmek için de delete metodunu kullanabilirsiniz;

static void MAATestDelete (Args _args)
{
    NumberSequenceTable NumberSequenceTable;

        ttsBegin;
        select firstOnly NumberSequenceTable
        where NumberSequenceTable.NumberSequence == "ETGM_303"; //delete edilecek kayıdı bulmak için şartlar belirtilir.
        if(NumberSequenceTable)
        {
            NumberSequenceTable.doDelete();
        }
        ttsCommit;
        info("bitti");
}


Update Methods

Bir tablodaki alanı başka bir tablodaki aynı alanla güncelleme istenirse aşağıdaki metod size yardımcı olacak.

Örneğin CustTable'daki SalesDistrictId alanlanlarını ForecastSales'daki SalesDistrictId alanıyla güncellenmesi istendiğinde bu jobs yardımıyla çözüme ulaşabilirsiniz.


//CustTable'daki SalesDistrictId alanlarını ForecastSales'daki SalesDistrictId alanlarıyla birbirine eşler.

static void MAA_UpdateForecastSales(Args _args)
{
      ForecastSales        forecastSales;
      CustTable            custTable;
    ;

    ttsBegin;

    while select custTable // Tabloyu elimize alıyoruz. bu tablo SalesDistrictId alanı çekilecek olan tablo.
           where custTable.SalesDistrictId != "" // şart yazıyoruz. "CustTable'daki SalesDistrictId alanı boş olmayanlar"
    {
        while select forupdate forecastSales // güncellenecek olan tablo
           where forecastSales.CustAccountId == custTable.AccountNum // CustTable'daki AccountNum'ı forecastSales'daki CustAccountId'siyle eşit olanlar
       {
            if  (forecastSales.SalesDistrictId  != "")
            {
                 forecastSales.SalesDistrictId = custTable.SalesDistrictId; // custTable'daki SalesDistrictId alanlarının hepsini forecastSales'daki aynı alanla eşitle.
                 forecastSales.update();
                 info(strfmt("%1", forecastSales.SalesDistrictId));
            }
        }
    }

    info("Bitti");

    ttsCommit;

}

2 Haziran 2016 Perşembe

Update Methods

Kendi oluşturduğum örnek bir tablodaki alanda matematiksel işlem yaptırarak güncelleme yapmak için aşağıdaki metodu inceleyebilirsiniz.

static void MAA_TestMali(Args _args)
{
    TestMali   TestMali;
    ;

    ttsbegin;

    while select forupdate TestMali
        where TestMali.AccountNum LIKE "MAA00*"
        &&    TestMali.createdBy=='akb' // tablodaki kaydı oluşturan kişinin ax kullanıcısı

    {

       if(TestMali)
       TestMali.amount = ((12+405)*254)*1002;
       TestMali.update();
       info(strfmt("%1",   TestMali.amount));
    }

    info ("tamamlandı");
    ttscommit;
}


Tablodaki bir satırda birden fazla alanın güncellenmesi isteniyorsa size, aşağıdaki kod yardımcı olacak.

static void MAATestUpdate4(Args _args)
{
    PurchLine  PurchLine;

    ttsBegin;

      select firstOnly forUpdate PurchLine
        where PurchLine.PurchId=="MAA001453"; // Tablodaki satırı seçiyoruz (şartımızı belirliyoruz)
           && PurchLine.ItemId  LIKE  "A00*" // A00 ile başlayanlar (şartımızı belirliyoruz)

        if(PurchLine)
            {
                PurchLine.ShipperName        = "Mehmet Ali Akbulut"; // Güncellenecek alanlar
                PurchLine.ShipperTaxOffice   = "Kütahya"; // Güncellenecek alanlar
                PurchLine.ShipperTCNO        = "145312991571"; // Güncellenecek alanlar
                PurchLine.doUpdate();
            }

    ttsCommit;

    info("bitti");
}


Update / Insert / Delete Methods


Herhangi bir tablonun satırındaki bir alanda güncelleme istenirse bu metod kullanılanilir.

// bir satırda güncelleme yapılmak için kullanılır.
 static void MAATestUpdate(Args _args)
{
         NumberSequenceTable NumberSequenceTable;
 
  ttsBegin;

     select firstOnly forUpdate NumberSequenceTable
     where NumberSequenceTable.NumberSequence == "ETGM_303"; //şart

     if(NumberSequenceTable)
  {
     NumberSequenceTable.NumberSequence ="303";            

     NumberSequenceTable.doUpdate(); // alanı her şartta günceller.
  }

ttsCommit; info("bitti");
}

Güncellenecek alanın tipine göre, (enum, date vs.) update metodunda küçük değişiklikler yapmak gerekiyor.

Örneğin güncellenecek alanın tipi tarih(date) ise;

 {
                PriceDiscTable.ToDate= mkDate(31,12,2014);  //güncellenmesini istediğimiz alan
                PriceDiscTable.doUpdate();
  }


Güncellenecek alanın tipi enum ise;

 {
              SalesTable.SalesStatus = SalesStatus::Canceled;
              SalesTable.doUpdate();
 }


Dynamics Ax (Axapta) Nedir?


Dynamics Ax Microsoft’un orta ve büyük ölçekli işletmelerin ihtiyaçlarını karşılamak için tasarladığı temel iş çözümüdür. Veritabanı yönetim sistemi üzerinde çalışan, kendine özgü X++ dilinde geliştirilmiş ve arayüzleri Microsoft Office uygulamalarına çok benzediği için kullanımına alışılması çok kolay olan açık kaynak kodlu bir ERP sistemidir.

Teknolojik altyapısı ve çok katmanlı mimarisi ile Dynamics Ax ERP arenasının güçlü oyuncularından birisidir. Aynı zamanda iş ihtiyaçlarını en ince detaylarına kadar karşılanmasını sağlayan esnek bir yapıya sahiptir. Kendine özgü olan X++ geliştirme dili ile partnerlar ve müşteriler kendine özel geliştirmeler yaparak ek fonksiyonlar veya modüller geliştirebilirler.

Dynamics Ax kullanıcıların bilgisayarına bir masaüstü uygulaması olarak kurulur. Ek bir kullanıcı adı ve şifreye gereksinim duymadan kullanıcılar sisteme Windows hesapları ile girebilirler. Web den sisteme erişmek isteyen kullanıcılar için ise Enterprise Portal geliştirilmiştir. Enterprise portal ile kullanıcılar bir internet tarayıcısı ile sisteme erişerek işlemlerini gerçekleştirebilirler.

Açık kaynak kodlu yapısı ile Dynamics Ax üzerinde herhangi bir formun kaynak koduna ve diğer nesnelerine ulaşılabilir. Aynı zamanda formlar üzerindeki verilerin hangi tablolarda tutulduğu bilgisine erişilebilir. Tablolar arasındaki ilişkiler de açık olarak belirtilmiştir. Bu sayede Report Builder gibi araçlar sayesinde T-SQL komutlarını kullanarak kolayca rapor hazırlanabilir. Veritabanında depolanmış olan verilerin raporlar aracılığıyla sunulmasıyla işletme süreçleri yöneticiler tarafından en ince ayrıntısına kadar izlenilebilir. Alıntıdır.

(Kaynak : axaptanedir.com)

Dynamics Ax

           

Özetle Dynamics AX, tedarikten ==> sevkiyata kadar tüm verilerin koordineli bir şekilde kaydının tutulmasıdır.

Öğrendiğim bilgileri paylaşmak için bloğu oluşturdum. Yararlı olması dileğiyle.

"Bilgi paylaştıkça çoğalır."

Total ciro

static void MAA_SalesTableTotal(Args _args) { SalesTable SalesTable; utcDateTime dateTime; dateTime ...