Archive for the ‘ AX 2012 ’ Category

Gönderme panosunda çalışan ismini göstermek.

Merhaba

AX 2012′de Hizmet yönetimi/ Gönderme panosu (SMADispatchBoard) formunda sadece çalışan kodu gösteriliyor. Kod üzerinde bir süre durursanız çalışanın adını da gösteriyor. Buradan iş ataması yapacak kişilerin bütün kodları bilmesi mümkün değil. Altyapı olarak ActiveX kullanıldığı için direk değiştiremiyoruz. Çalışan ismini göstermek için veriyi dolduran sınıfta ufak bir değişiklik yapmak gerekiyor.

GanttVcDataTable sınıfının  createUserDefinedRecord() metoduna  // FD aralığındaki kodu eklemek yeterli olacaktır.

        else
        {
            if(_mapInsertedFields && _mapInsertedFields.exists(ganttVcDataTableField.parmFieldName()))
            {
                strFieldValue = _mapInsertedFields.lookup(ganttVcDataTableField.parmFieldName());
                // FD
                if(HcmWorker::findByPersonnelNumber(strFieldValue))
                {
                    strFieldValue = HcmWorker::findByPersonnelNumber(strFieldValue).name() ;
                }
                // FD
            }
        }

Selamlar.

Plan data import, export, and migration [AX 2012]

Merhaba.

Ax 2012′de ana veri, şirket ayarları ve geliştirmelerin ortamlar arasından nasıl aktarılacağı konusunda benim kafam karışıktı. Bir çok alternatif yöntem var. Hangi durumda hangisi kullanmak gerektiğini anlamamıştım. Microsoft’ta bu karışıklığın farkına varmış olmalı ki aşağıdaki yazıyı yazmış. Bu makalede hangi senaryo için hangi yöntemin uygun olduğunu tablo şeklinde gösteriyor ve karşılaştırıyor. Buradan benim anladığım bu işlemin netleşmesi için biraz zaman alacak ancak bir çok alternatifimiz var. Denemeden önce mutlaka sağlam yedek almak lazım. Bu araçları kullandıkça tecrübelerimi yazacağım.

TechNet – Plan data import, export, and migration

Selamlar.

Dynamics Ax 2012′de bir boyut nasıl zorunlu hale getirilir.

Merhaba

Ax 2012 ile değişen mali boyut yapısında herhangi bir boyutun nasıl zorunlu hale getirilebileceğine değineceğim.  Öncelikle General Ledger / Seturp /Configure account structures formunu açtığınızda aşağıda resimde göründüğü gibi alanın boş bırakılmasıyla ilgi parametre mevcut.

Bu parametre sadece deftere nakil işleminde çalışıyor. Örneğin yeni bir müşteri tanımlıyorsunuz ve departman boyutunun zorunlu olmasını istiyorsanız bu tanım bu işlemi yapmıyor.  Standartta böyle bir tanım yapılabiliyor mu diye araştırdım bulamadım. Validasyon yazmaktan başka bir çözüm bulamadım. Alanlarında boyut (DefaultDimension ) olan herhangi bir tablonun ValidateWrite() metodunu aşağıdaki gibi değiştirelim.

public boolean validateWrite()
{
    boolean ret;
    ;
    ret = super();

    if(!this.checkDimValue(5637144850)) // Must be parametric
    {
        ret =  checkFailed("Departman boyutu boş bırakılamaz.") && ret;
    }
    return ret;
}

Tabloya gerekli metodu ekleyelim.

Boolean checkDimValue(RefRecId _refRecId)
{
    DimensionAttributeValue             dimAttrValue;
    DimensionAttributeValueSetItem      dimAttrValueSetItem;

    ;

    select firstonly dimAttrValueSetItem
    where dimAttrValueSetItem.DimensionAttributeValueSet == this.DimensionDefault
    join dimAttrValue
        where dimAttrValue.RecId == dimAttrValueSetItem.DimensionAttributeValue
        &&    dimAttrValue.DimensionAttribute   == _refRecId ;

    if(dimAttrValueSetItem.DisplayValue)
        return true;
    else
        return false;

}

Selamlar.

Microsoft Dynamics AX 2012 Test Data Transfer Tool (beta)

Merhaba

Ax 2012′de değişen yapıyla birlikte ortamlar arasında veri transferi biraz sıkıntılı bir durum oldu. Örneğin canlı ortamın veri tabanı yedeğini alıp test ortamına yüklerseniz tamamen eşitlemiş oluyorsunuz. Geliştirmeler temel  ayarlar dahil. Bazen bunu da yapmak isteyebiliriz ama genelde sadece işle alakalı verilerin aktarılmasını isteriz. Bunu yapabilmek için InformationSource’ ta  Test Data Transfer Tool (beta) adında bir araç yayınlandı. Bu araçla ilgili ayrıntılı bilgiyi TechNet‘te bulabilirsiniz. Microsoft bu aracı sadece canlı ortamdan veri aktarmak için kullanmayı tavsiye ediyor. Canlı ortamın kendisine bu aracı kullanarak veri aktarmayı tavsiye etmiyor.

The Test Data Transfer Tool (beta) aşağıdaki durumlar için uygundur.

  • Büyük verileri veya birden çok şirketi içeren verileri içeri aktarmak veye dışarı aktarmak için.
  • Birbirinden çok farklı olmayan ax ortamları arasında veri aktarımı için.
  • Versiyon kontrol sistemi kullanıldığında.
  • Microsoft Dynamics AX Application Object Server (AOS) çalışmadan aktarım yapmak gerektiğinde.

The Test Data Transfer Tool (beta) veri aktarımı için Microsoft SQL Server bulk copy tool (bcp)’yi kullanıyor. Bu sayede işlemler SQL server üzerinden daha hızlı yapılabiliyor ve AOS’a ihtiyaç duymuyor. SQL üzerinde bu aktarım yaptığımız için veri bütünlüğü korunur. Örneğin RecID’lerde değişiklik yapmaz aynısını oluşturur.Hangi verinin dışarı aktarılacağı filtrelenebilir.

Aşağıda dışarı aktarım ve içeri aktarım işlemini özetleyen bir grafik var. Burada da görüleceği gibi 3 tane farklı dosya dışarı aktarılıyor. Bu dosyalar text bazlı olduğu için versiyon kontrolü bile yapılabilir.

İçeri aktarım işine mutlaka SQL Server’ın kurulu olduğu makinede admin yetkisiyle yapmak gerekiyor.

Ax 2012 ile veri aktarımı için bir çok alternatif geldi. Bunların hangisi hangi durum için en uygun çözüm olduğunu anlatan bir makaleyi ilerde yazacağım.

Selamlar.

What makes a good Dynamics AX Project Manager?

Source : http://www.cognitive-group.com

X++ ile Vergi Kimlik Numarası kontrolü nasıl yapılır

Merhaba

Vergi kimlik numarasının bir algoritması var. Bu algoritma sayesinde girilen numaranın geçerli olup olmadığını tespit edebilirsiniz. Bu kontrolü yapacak bir fonksiyona ihtiyacım vardı. İnternette farklı dillerde yazılmış bir çok örnek buldum ancak X++ ile yazılmış bulamadım. Global sınıfına vergiKimlikNoValidation_FD adında bir metot yazdım.


// FD : Vergi kimlik no doğrulama
private boolean vergiKimlikNoValidation_FD(int64 kno)
{
    int     lastDigit;
    int     total = 0;
    int     i ;
    int     j = 1000000000;
    int     dig;
    int     v1 , v11;
    ;

    if (strLen(int2str(kno)) != 10)
        return   false;

    lastDigit = kno mod 10;

    for (i = 9; i >= 1; i--)
    {
        dig = (kno div j) mod 10 ;
        j = j / 10 ;
        if (dig < 0)
            return  false;
        v1  = ((dig + i) mod 10);
        v11 = (v1 * power(2, i)) mod 9;
        if (v1 != 0 && v11 == 0)
            v11 = 9;
        total += v11;
    }

    if (total mod 10 == 0)
        total = 0;
    else
        total = (10 - (total mod 10));

    if (total == lastDigit)
        return  true;
    else
        return  false;
}

Selamlar.

How to release products to all companies.

Hi,

As you know with Dynamics AX 2012, you have to create a product first and then release to the product to companies. You can release which company do you want. In my company there is a request to release product all companies automaticly. I have some research and found good post and methods about it. I wrote a class named SECReleaseProductForAllCompanies and make it MenuItemButton as you can see below.

Let see methods of class now.

Class decleration;

// FD Relaese products for all companies
class SECReleaseProductForAllCompanies
{
    EcoResProductDisplayProductNumber   productNumber;
    EcoResProduct                       ecoResProduct;
}

Main method; Gets all the selected records and calls run.

public static void main(Args args)
{
    SECReleaseProductForAllCompanies    releaseProductForAllCompanies;
    ecoResProduct                       EcoResProduct;
    FormDataSource                      fdsEcoResProduct;
    ;

    fdsEcoResProduct = args.record().dataSource();
    for (EcoResProduct = fdsEcoResProduct.getFirst(true) ? fdsEcoResProduct.getFirst(true) :
            fdsEcoResProduct.cursor();   EcoResProduct; EcoResProduct = fdsEcoResProduct.getnext())
    {
        releaseProductForAllCompanies = new SECReleaseProductForAllCompanies();
        releaseProductForAllCompanies.parmProductNumber(ecoResProduct.DisplayProductNumber);
        releaseProductForAllCompanies.run();

        info(strfmt("%1  %2 product successfully released to all companies. ",
                    EcoResProduct.productNumber() , EcoResProduct.productName() ));
    }
}

Parm method;

public EcoResProductDisplayProductNumber parmProductNumber(
            EcoResProductDisplayProductNumber _productNumber = productNumber)
{
    productNumber = _productNumber;

    return productNumber;
}

Run method;

private void run()
{
    ;
    this.releaseProduct();
}

Release method; You can use EcoResProductReleaseManagerBase::releaseProduct() static method instead of this.

private void releaseProduct()
{
    InventTable                 inventTable;
    InventTableModule           inventTableModule;
    NumberSequenceTable         numberSequenceTable;
    ItemId                      itemId;
    InventItemSetupSupplyType   inventItemSetupSupplyType;
    CompanyInfo                 companyInfo;

    EcoResStorageDimensionGroupProduct  ecoResStorageDimensionGroupProduct;
    EcoResTrackingDimensionGroupProduct ecoResTrackingDimensionGroupProduct;
    EcoResStorageDimensionGroupItem     ecoResStorageDimensionGroupItem;
    EcoResTrackingDimensionGroupItem    ecoResTrackingDimensionGroupItem;
    ;

    select firstOnly ecoResProduct
        where EcoResProduct.DisplayProductNumber == productNumber;

    while select companyInfo
        where companyInfo.DataArea != "DAT"
    {
        changecompany (companyInfo.DataArea)
        {
            ttsBegin;
            inventTable = null;
            inventTableModule = null;
            inventItemSetupSupplyType = null;
            ecoResStorageDimensionGroupProduct = null;
            ecoResTrackingDimensionGroupProduct = null;
            ecoResStorageDimensionGroupItem = null;
            ecoResTrackingDimensionGroupItem = null;

            numberSequenceTable = InventParameters::numRefItemId().numberSequenceTable();

            if (!numberSequenceTable.RecId || numberSequenceTable.Manual)
            {
                itemId = ecoResProduct.productNumber();
            }
            else
            {
                itemId = NumberSeq::newGetNumFromId(numberSequenceTable.RecId).num();
            }

            inventTable.initValue();
            inventTable.initFromEcoResProduct(ecoResProduct);
            inventTable.ItemId = ItemId;
            inventTable.NameAlias = ecoResProduct.SearchName;
            inventTable.insert(true);

            inventTableModule.initValue();
            inventTableModule.ItemId = inventTable.ItemId;
            inventTableModule.ModuleType = ModuleInventPurchSales::Invent;
            inventTableModule.insert();

            inventTableModule.initValue();
            inventTableModule.ItemId = inventTable.ItemId;
            inventTableModule.ModuleType = ModuleInventPurchSales::Purch;
            inventTableModule.insert();

            inventTableModule.initValue();
            inventTableModule.ItemId = inventTable.ItemId;
            inventTableModule.ModuleType = ModuleInventPurchSales::Sales;
            inventTableModule.insert();

            InventItemLocation::createDefault(inventTable.ItemId);

            inventItemSetupSupplyType.initValue();
            inventItemSetupSupplyType.ItemId = inventTable.ItemId;
            inventItemSetupSupplyType.ItemDataAreaId = inventTable.DataAreaId;
            inventItemSetupSupplyType.insert();

            ecoResStorageDimensionGroupProduct  = EcoResStorageDimensionGroupProduct::findByProduct(ecoResProduct.RecId);
            ecoResTrackingDimensionGroupProduct = EcoResTrackingDimensionGroupProduct::findByProduct(ecoResProduct.RecId);

            if (ecoResStorageDimensionGroupProduct.RecId)
            {
                ecoResStorageDimensionGroupItem.ItemDataAreaId = inventTable.DataAreaId;
                ecoResStorageDimensionGroupItem.ItemId = inventTable.ItemId;
                ecoResStorageDimensionGroupItem.StorageDimensionGroup = ecoResStorageDimensionGroupProduct.StorageDimensionGroup;
                ecoResStorageDimensionGroupItem.insert();
            }

            if (ecoResTrackingDimensionGroupProduct.RecId)
            {
                ecoResTrackingDimensionGroupItem.ItemDataAreaId = inventTable.DataAreaId;
                ecoResTrackingDimensionGroupItem.ItemId = inventTable.ItemId;
                ecoResTrackingDimensionGroupItem.TrackingDimensionGroup = ecoResTrackingDimensionGroupProduct.TrackingDimensionGroup;
                ecoResTrackingDimensionGroupItem.insert();
            }

            ttsCommit;

        }
    }
}


You can download class from here.

Thanks Sreenath Reddy G. for methods.

Until next time.

How to Replace a Financial Dimension in Default Dimensions [Dynamics AX 2012]

Merhaba

Ax 2012 ile finansal boyut yapısının tamamen değiştiğini daha önce ifade etmiştim. Bu değişiklik bize bazı durumlarda fazladan yazılım yükü oluşturuyor.  Bunlardan biride bir boyuttaki belli bir boyutun değerini kod  ile değiştirmek. Şöyle örnekleyeyim.

Bir müşteriniz var ve departman boyutunda 0026 yazıyor. Siz bunu 0030 ile değiştirmek istiyorsunuz.

Ax 2009 ‘da

custTable.Dimension[2] = “0030″;  gibi basit bir kod ile bunu yapabilirdiniz.

Ax 2012 ‘de ise şöyle bir metoda ihtiyacınız var;


static void FD_ChangeDimValue(Args _args)
{
    CustTable                           custTable;
    DimensionAttributeValueSetStorage   dimensionStorage;
    DimensionAttribute                  deparmentDimensionAttribute;
    DimensionAttributeValue             newDepartmentValue;

    ;
    ttsBegin;
    // Müşteri seçiliyor
    custTable =  CustTable::findRecId(22565423201,true);

    // Değiştirelecek boyut seçiliyor
    deparmentDimensionAttribute = DimensionAttribute::findByName("Department");
    // Değiştirilecek boyut için değer seçiliyor.
    newDepartmentValue = DimensionAttributeValue::findByDimensionAttributeAndValue(deparmentDimensionAttribute, "0030");

    dimensionStorage = DimensionAttributeValueSetStorage::find(CustTable.DefaultDimension);
    dimensionStorage.addItem(newDepartmentValue);

    CustTable.DefaultDimension = dimensionStorage.save();

    CustTable.update();
    ttscommit;
}

Selamlar.

Ax 2012′de kodla farklı bir SQL’e bağlanıp veri çekmek

Merhaba

Yeni projemde yapmakta olduğum bir entegrasyon işi için farklı bir sql server’a bağlanıp veri almam gerekiyordu. Yaptığım çalışmayı sizlerle paylaşıyorum.

İlk iş bir ODBC bağlantısı kurmak. Bağlantıyı ister AOS’a isterseniz Client makineye kurabilirsiniz. Ancak AOS’ta olması daha mantıklı. Administrative Tools / Data Sources (ODBC) ‘a tıklayarak bağlanmak istediğiniz Sql için Data Source Name (DSN) oluşturmalısınız. Oluşturduğumuz  DSN’i kodda kullanacağız.

static public void fd_ConnectSQLthrougODBC(Args _args)
{
    LoginProperty                 loginProperty;
    OdbcConnection                odbcConnection;
    Statement                     statement;
    ResultSet                     resultSet;
    str                           sql;
    SqlStatementExecutePermission perm;
    FDTransferCardTable           transferCardTable;
    ;

    loginProperty = new LoginProperty();
    loginProperty.setDSN("CASC"); //Tanımladığımız DSN
    loginProperty.setDatabase("SWHSystem");

    odbcConnection = new OdbcConnection(loginProperty);

    if (odbcConnection)
    {
        sql = "SELECT * FROM Personnel ";

        perm = new SqlStatementExecutePermission(sql);
        perm.assert();

        statement = odbcConnection.createStatement();
        resultSet = statement.executeQuery(sql);

        while (resultSet.next())
        {
            transferCardTable.clear();
            transferCardTable.ObjectID        = resultSet.getString(1);
            transferCardTable.Name            = resultSet.getString(2);
            transferCardTable.Protected       = str2num(resultSet.getString(6));
            transferCardTable.PartitionID     = resultSet.getString(7);
            transferCardTable.LastName        = resultSet.getString(10);
            transferCardTable.FirstName       = resultSet.getString(11);
            transferCardTable.MiddleName      = resultSet.getString(12);
            transferCardTable.PersonnelTypeID = resultSet.getString(13);
            transferCardTable.Template        = resultSet.getString(14);
            transferCardTable.Temporary       = str2num(resultSet.getString(15));
            transferCardTable.Disabled        = str2num(resultSet.getString(22));
            transferCardTable.Text1           = resultSet.getString(27);
            transferCardTable.Text12          = resultSet.getString(38);
            transferCardTable.insert();
        }
        resultSet.close();
        statement.close();
    }
    else
    {
        error("ODBC ile veritabanına bağlantı kurulamadı.");
    }
}

Kaynak

Selamlar.

Dynamics ax 2012′de kodla satınalma siparişi oluşturmak

Merhaba

Bu yazımda AIF servis sınıfları kullanarak bir satınalma siparişi oluşturacağım. Örneği inceleyelim.

static void FD_CreatePurchaseOrder(Args _args)
{
    PurchTable      purchTable;
    PurchLine       purchLine;

    AxPurchTable    axPurchTable;
    AxPurchLine     axPurchLine;
// Kullanacağımız sınıflar

    InventDim       inventDim;
    ;

    purchTable.initFromVendTable(VendTable::find("2002"));

    axPurchTable = AxPurchTable::newPurchTable(purchTable);
    axPurchTable.parmPurchaseType(PurchaseType::Purch);
    axPurchTable.parmDocumentStatus(DocumentStatus::PurchaseOrder);
    axPurchTable.parmPurchName("Deneme siparişi");
    axPurchTable.parmAccountingDate(08\06\2013);
    axPurchTable.parmDeliveryDate(08\06\2013);
    axPurchTable.parmItemBuyerGroupId("20");
    axPurchTable.parmPurchPoolId("02");
    axPurchTable.parmInventSiteId("2");
    axPurchTable.parmPurchStatus(PurchStatus::Backorder);
    axPurchTable.doSave();
// İstediğimiz bilgileri doldurup kaydediyoruz. PurchTable'ı kendisi oluşturuyor.

    purchTable = axPurchTable.purchTable();
    purchLine.initFromPurchTable(purchTable);

    inventDim.clear();
    inventDim.InventLocationId  = "11";
    inventDim.InventSiteId      = "1";

    inventDim = inventDim::findOrCreate(inventDim);   

    axPurchLine = AxPurchLine::newPurchLine(purchLine);
    axpurchLine.parmItemId("0004");
    axPurchLine.parmPurchQty(2);
    axPurchLine.parmPurchPrice(10);
    axPurchLine.parmInventDimId(inventDim.inventDimId);
    axPurchLine.doSave();
// PurchLine oluşturuluyor. 

    info(strfmt("%1 nolu sipariş oluşturuldu.",purchTable.PurchId ));

}

Birden çok PurchLine satırını bu yöntemle oluşturamadım. Nasıl yapıldığını bilen varsa bana da bilgi versin, memnun olurum. Biraz araştırdım, yapılıp yapılamadığına dair bir bilgi bulamadım ama gördüğüm bütün örnekler tek satır üzerine yapılmıştı. Tek satır yapabilmek çok kullanışlı değil mutlaka bir yolu olmalı, eğer bir yolu yoksa bu sınıflar eksik olmuş demektir.

Selamlar.

Page 3 of 712345...Last »