Powered By

Skin Design:
Free Blogger Skins

Powered by Blogger

Cari Blog Ini

Tampilkan postingan dengan label Dynamics AX. Tampilkan semua postingan
Tampilkan postingan dengan label Dynamics AX. Tampilkan semua postingan

14 Oktober 2026

AX 2012 Legacy Report

 

1. Method element yang relevan pada report AX 2012

Berikut method yang relevan untuk memahami alur report klasik. Ini bukan daftar lengkap seluruh method internal ReportRun, tetapi mencakup method penting untuk kasus Anda.

A. Method untuk alur data dan pencetakan

Method

Fungsi

run()

Memulai proses report. Implementasi standar mengatur prompt, mengambil data, lalu mengarahkan hasil ke output.


fetch()

Menjalankan query report dan mengirim record yang ditemukan melalui send(). Nilai balik menentukan apakah pemrosesan dilanjutkan.



send()

Mengirim record ke section Body yang sesuai. Ada beberapa overload, termasuk yang menerima record dan level section.



executeSection()

Mencetak section tertentu. Pada Body, method ini dipicu saat send() memproses record.


execute(int)

Menjalankan programmable section berdasarkan level yang diberikan.



print()

Mengarahkan report yang telah dihasilkan ke media output, seperti layar atau printer.


Microsoft Learn

reset()

Mereset state agar instance ReportRun dapat digunakan untuk membuat report lain.

query()

Mengakses query yang digunakan report; berguna saat memeriksa sumber dan range data.

B. Method untuk halaman dan format

Method

Fungsi

newPage()

Meminta report memulai halaman baru.

newPage(boolean)

Varian dengan parameter Boolean untuk mengatur perilaku page break. Detail semantiknya perlu diverifikasi pada versi AX yang digunakan.

page() / page(int)

Mengakses atau mengatur informasi halaman; pastikan overload yang dipakai sesuai kebutuhan.

pagesTotal()

Mendapatkan informasi jumlah halaman report.

pageFormatting()

Menampilkan pengaturan properti printer.

packPageSettings()

Mengemas pengaturan halaman.

packPrinterSettings()

Mengemas pengaturan printer.

packPrintJobSettings()

Mengemas pengaturan pekerjaan cetak.

Daftar method ReportRun Microsoft mencantumkan method-method tersebut. Perlu diingat, dokumentasi API yang tersedia saat ini juga mencakup versi Dynamics yang lebih baru, sehingga detail implementasi internalnya tidak selalu identik dengan AX 2012.


C. Method untuk mengatur section

Method

Kegunaan

enableBody() / enableBody(int)

Mengaktifkan Body tertentu.

disableBody() / disableBody(int)

Menonaktifkan Body tertentu.

enableAllBodies()

Mengaktifkan seluruh Body.

enableSection(ReportSection)

Mengaktifkan section tertentu.

disableSection(ReportSection)

Menonaktifkan section tertentu.

enablePageFooter() / disablePageFooter()

Mengatur pencetakan page footer.

executeHeader()

Menjalankan section Header.

executeFooter()

Menjalankan section Footer.

executeBodyColumnHeadings()

Menjalankan heading kolom Body.

executeColumnHeadings(ReportSection)

Menjalankan heading kolom pada section tertentu.

header(...) / footer(...)

Mengatur pemrosesan Header atau Footer berdasarkan section dan level.

sectionsLeft(ReportSection)

Memeriksa informasi section yang tersisa dalam alur report.

Method di atas berguna ketika Anda ingin mengontrol section mana yang dicetak atau kapan bagian report dieksekusi.


D. Method untuk query dan informasi report

Method

Kegunaan

query() / query(Query)

Mengambil atau menetapkan objek query report.

queryRun() / queryRun(QueryRun)

Mengambil atau menetapkan objek QueryRun.

design() / design(Object)

Mengambil atau menetapkan design report.

report()

Mengakses informasi report yang sedang dijalankan.

reportUser() / reportUser(String)

Mengambil atau menetapkan informasi user report.

args()

Mengakses argumen yang diberikan saat objek dibuat.

hasGeneratedDesign()

Memeriksa apakah report memakai generated design.

name() / name(String)

Mengambil atau menetapkan nama objek.

init()

Inisialisasi objek report.

prompt()

Menampilkan dialog pengaturan sebelum report dijalankan.

getTarget() / setTarget(PrintMedium)

Mengakses atau menetapkan target output report.

Referensi method ReportRun mencantumkan kelompok method tersebut.


E. Method untuk printer dan pengaturan output

Ada banyak accessor untuk informasi printer, antara lain:

  • printerPrinterName() — nama printer.

  • printerDriverName() — nama driver.

  • printerPortName() — port printer.

  • printerServerName() — server printer.

  • printerPaper() — informasi kertas.

  • printerPageHeight() / printerPageWidth() — dimensi halaman printer.

  • printerSettings() — pengaturan printer.

  • printJobSettings() — pengaturan pekerjaan cetak.

  • copies() / copies(int) — jumlah salinan.

  • collate() / collate(boolean) — pengaturan pengurutan salinan.

  • deviceName() / deviceName(String) — informasi perangkat output.

  • getNumberOfPrinters() / getPrinter(int) — informasi printer yang tersedia.

Perlu diperhatikan bahwa sebagian besar accessor printer tersebut merupakan informasi atau pengaturan output, bukan pengendali iterasi record.


F. Method untuk subtotal, footer, dan informasi halaman

Method

Kegunaan

sum() / sumPos() / sumNeg()

Mengakses fungsi agregasi dan subtotal report.

sumControl() / sumControlPos() / sumControlNeg()

Mengakses agregasi berdasarkan control.

printSum()

Mengakses informasi pencetakan subtotal.

addPendingSums()

Memproses footer yang berkaitan dengan subtotal.

addRangeDescription()

Menambahkan deskripsi range report.

getRangeDescription()

Mengambil deskripsi range.

clearAllRangeDescriptions()

Menghapus deskripsi range.

caption()

Mengatur caption preview atau nama dokumen cetak.

title() / title(String)

Mengambil atau mengatur judul pekerjaan cetak.

progressInfo()

Membuat informasi progres pemrosesan report.

suppressReportIsEmptyMessage()

Mengatur pesan ketika report kosong.

02 Agustus 2023

Dynamics AX 2012 Workflow Stopped error: The SQL database has issued an error.

 Terjadi error workflow dengan tampilan seperti ini:

Stopped (error): session 113 (Sync) UPDATE T1 SET ACCOUNTINGEVENT=5638165117,RECVERSION=786788108 FROM ACCOUNTINGDISTRIBUTION T1 WITH (INDEX(I_7452SOURCEDOCUMENTHEADERIDX)) CROSS JOIN SOURCEDOCUMENTLINE T2 WHERE (((T1.PARTITION=5637144576) AND (T1.ACCOUNTINGEVENT=0) AND (T1.ACCOUNTINGDATE={ d''})) AND (T1.SOURCEDOCUMENTHEADER=5638834650)) AND ((T2.RECID=T1.SOURCEDOCUMENTLINE) AND (T2.ACCOUNTINGSTATUS=4 OR T2.ACCOUNTINGSTATUS=6)) AND (T2.PARTITION=5637144576) [Microsoft][SQL Server Native Client 10.0][SQL Server]Conversion failed when converting date and/or 
time from character string. Object Server 01:  Cannot execute the required database operation.
The SQL database has issued an error.

Penyebabnya adalah tidak disetnya AccountingDate pada tabel PurchReqTable dan PurchReqLine. Kenapa terjadi seperti itu? Tidak tau. Karena secara default harusnya accounting date terisi dengan tanggal saat dibuat.

Solusinya:

Isi accounting date di kedua table tersebut dan pada tabel AccountingDistribution yang berhubungan. (Link melalui table SourceDocumentHeader dan SourceDocumentLine).


Referensi dan ide:

sql server - Dynamics AX 2012: Conversion failed when converting date and/or time from character string - Stack Overflow






26 Mei 2023

Dynamics AX 2012 parameter Args with record

Suatu saat terjadi hal aneh di AX. Dimana ketika user menekan tombol proses, tetapi record yang terupdate bukan record yang dipilih. Saya coba reporduksi bagaimana error tersebut terjadi, namun tidak berhasil. Apa yang saya coba sesuai dengan yang diharapkan. Hingga suatu saat secara tidak sengaja ada rekan saat mencoba fitur baru, dia menekan sebuah tombol dimana tombol tersebut menampilkan dialog terlebih dahulu. Dialog tersebut tanpa modal, setelah dialog muncul, user tetap bisa interaksi dengan form, termasuk menggeser pilihan record yang terpilih. Ternyata ketika dialog muncul dan user menggeser pilihan row maka yang terproses adalah pilihan row yang baru dipilih. Bukan row yang dipilih sebelum dialog tersebut muncul. 

Ternyata di AX jika kita memakai arg.record() sebagai data terpilih, data tersebut bersifat byref (mengambil istilah VB). Jadi ketika user mengganti pilihan record, maka data ikut berubah.

Contoh source dibawah ini:

public static void main(Args arg)
{
    Dialog dlg = new Dialog("TEST");
    
    CustTable tbl = arg.record();
    
    dlg.addText(tbl.AccountNum);
    if (dlg.run())
    {
        info("Selected: " + tbl.AccountNum );
    }
}

Code diatas adalah dialam sebuah Class yang dipanggil oleh MenuAction, dan menu Action menempel pada form yang memiliki data source tabel "CustTable"

Ketika saya pilih baris pertama (kode: 000001), maka tampilan dialog seperti dibawah ini:


Terlihat yang ditampilkan dialog adalah sesuai. Namun kemudian saya pilih row yang lain saat dialog tersebut masih muncul (karena bukan modal).

Terlihat dialog masih menampilkan record awal. Namun saat saya tekan tombol OK maka record yang dipilih ternyata sesuai pilihan terakhir.


Ternyata berbahaya sekali. Karena bisa salah update/proses data. Solusi untuk kasus ini adalah dengan menjadikan dialog menjadi modal. Lihat caranya disini: System Modal Dialog - Microsoft Dynamics AX Forum Community Forum

Cara kedua adalah membiarkan dialog tanpa modal, namun data yang diproses benar, yaitu dengan mengubah code menjadi dibawah ini:

public static void main(Args arg)
{
    Dialog dlg = new Dialog("TEST");
    
    //OLD CODE CustTable tbl = arg.record();
    CustTable tbl = CustTable::findRecId(arg.record().RecId);
    
    dlg.addText(tbl.AccountNum);
    if (dlg.run())
    {
        info("Selected: " + tbl.AccountNum );
    }
}

Pada code yang saya warna biru terlihat variabel tbl bukan dari arg.record() lagi namun query lagi dengan mengambil arg.record().recId. Hasilnya seperti gambar dibawah ini.



13 Desember 2022

Approve Dynamics AX 2012 Workflow by Code (X++)

Untuk membuat fungsi yang melakukan approval atas Sales Order tertentu maka bisa menggunakan kode dibawah ini:


WorkflowWorkItemTable  wfItem;

SalesTable so;

so  = SalesTable::find(<Nomor SO>);

Workflow::activateFromWorkflowType(workFlowTypeStr(<Nama workflow>),  so.RecId, "Accept by x++", false, "<nama user AX>");


select wfItem  

    where wfItem.RefTableId == so.TableId && wfItem.RefRecId == so.RecId

    && wfItem.UserId == curUserId() 

    && wfItem.Status == WorkflowWorkItemStatus::Pending;

    

    if (wfItem) {

        WorkflowWorkItemActionManager::dispatchWorkItemAction(

            wfItem, 

            "Auto Approve by system",

            curUserId(),

            WorkflowWorkItemActionType::Complete,

            menuitemActionStr(<Nama Menu Approval workflow yang digunakan>),

            false); 

    }



Berdasarkan blog: How to approve workflow by Code | Mohammad Aamir Shakil (wordpress.com)

25 Juli 2022

Another instance of CIL generation is already in progress

 Ketika melakukan CIL AX kemudian keluar error seperti dibawah ini:

Another instance of CIL generation is already in progress. Please wait for the operation to complete before retrying.


dan lakukan cek pada file log di folder: C:\Program Files\Microsoft Dynamics AX\60\Server\[SERVICE NAME]\bin\XppIL\Dynamics.Ax.Application.dll.log

Cek isi nya pastikan tidak ada error:

Finished pass 1 at 7/14/2022 4:07:06 PM

Finished pass 2 at 7/14/2022 4:07:07 PM

Finished pass 3 at 7/14/2022 4:07:09 PM

Finished creating types at 7/14/2022 4:07:09 PM

Errors: 0

Warnings: 0

Maka artinya proses CIL berhasil hanya tidak berhasil menampilkan hasil di AX GUI. Untuk itu hapus tabel SYSLASTVALUE (didatabase PROD)
 
select * from SYSLASTVALUE where ELEMENTNAME =  'CIL Generation'

delete from SYSLASTVALUE where ELEMENTNAME = 'CIL Generation'

Sumber: Dynamics AX: Another instance of CIL generation is already in progress. Please wait for the operation to complete before retrying. (kiwiaxguy.blogspot.com)

29 Juli 2020

AX error: Failed to create a session; confirm that the user has the proper privileges….

Hari ini kita dikerjain sama AX!! Awalnya saya lagi bersih-bersih class yang sudah tidak dipakai lagi, karena sudah digantikan dengan class lain. 
Saya hapus lah class-class tersebut. Beberapa menit kemudian user complain ada problem ketika proses Goods Receipt. Saya cek errornya ternyata masalah class yang saya hapus tadi.
Wah ternyata ada satu class yang masih dipakai di situ. Ya sudah saya restore lah class tersebut. Setelah restore di incremental CIL. Astagfirullah..ada error. Bilangnya class tersebut sudah ada. Error duplicate. Ya sudah saya rename class tersebut dan incremental CIL lagi. Hasil nya sukses.

Balik lagi ke user tadi, saya coba lagi. Kali ini errornya beda. Yaitu Failed to create a session; confirm that the user has the proper privileges…. 
Wah apa lagi ini. Saya log off user, login lagi tetap sama. Dan parahnya user saya yang admin pun mengalami hal yang sama. Yang tidak terpengaruh hanya user Administrator. Wah mulai keringat dingin ini...
Cari di google, nemu artikel ini:
https://stoneridgesoftware.com/5-tips-to-resolve-the-ax-error-failed-to-create-a-session-confirm-that-the-user-has-the-proper-privileges/

Langkah no 1 tidak sesuai kondisi disini karena cuma ada satu partisi. Langkah no 2 tidak dikerjakan karena saya belum pahan apa maksudnya. Kemudian langkah no 3 belum dikerjakan karena akan mengganggu operasional aplikasi. Saya asumsi yang saya lakukan hanyalah hal kecil yang terjadi di luar main class AX. (Saya lupa kalau object PurchEditLines memanggil class yang saya hapus tersebut adalah sumber masalahnya). Langkah no 4 sudah saya kerjakan, hasilnya tetap nihil. Langkah no 5 juga saya coba dengan membuat user baru, namun hasil sama. 

Akhirnya setelah tidak menemukan hasil, dan user yang error tambah banyak. Kita putuskan melakukan Full CIL. Namun kembali lagi ke error Duplicate type with name ...

Di google rata-rata menyarankan untuk:

  1. Stop all AOS instances
  2. Delete all files on the AOS server under C:\Program Files\Microsoft Dynamics AX\60\Server\\bin\XppIL
  3. Connect to the model db via SQL Management studio
  4. Truncate the table SYSXPPASSEMBLY which lists all of the files found in step 2
  5. You can do this via the command: TRUNCATE TABLE SYSXPPASSEMBLY
  6. Start 1 AOS instance
  7. Run Full CIL
            Yang penting adalah pada point 4. Karena ketika point 4 tidak di jalankan maka tetap gagal.  Yang dapat dipelajari dari kejadian ini adalah: Jangan hapus object di AX kemudian restore kembali tanpa proses CIL sebelumnya. Harusnya setelah hapus object diakukan proses CIL, baru kemudian restore lagi dan CIL lagi.

            26 Maret 2020

            Koneksi External Database MS Acess di Dynamics AX 2012

            Jika dulu pernah saya post mengenai koneksi database ekseternal di Ms Dynamics AX 2012 dengan database eksternalnya SQL Server, maka kali ini saya mencoba koneksi pada database Ms Access!

            https://shindu-b-raditya.blogspot.com/2016/10/problem-koneksi-eksternal-database-sql.html

            Berbeda dengan database SQL Server dimana merupkan client-server database, maka database Access adalah File Database. Database bersifat local karena untuk membuka database tersebut harus membuka file mdb nya. Maka harus akses via network share agar dapat konek dengan database tersebut jika diakses bukan dari server/pc itu sendiri.

            Langkah-langkah nya adalah sebagai berikut.

            Pertama, persiapkan dulu agar folder lokasi file MDB tersebut dapat di akses dari luar yaitu dengan men-share folder nya. Karena PC tersebut tidak konek domain maka saya membuat user local baru di PC tersebut dan membuka share untuk user tersebut.

            Kedua, persiapkan ODBC.
            Dikarenakan AX memiliki dua mode aplikasi (mode server 64 bit, dan mode client 32 bit) maka kita perlu memilih akan menggunakan mode yang mana. Jika jalan di client maka harus membuat ODBC 32 bit. Sedang jika menggunakan run on server/batch job, maka gunakan ODBC 64 bit. Untuk ODBC 64 bit bisa download driver Access (Access Database Engine)  https://www.microsoft.com/en-us/download/details.aspx?id=54920

            Perlu di pertimbangkan, jika kita jalan di sisi Client, maka setting ODBC juga perlu di setting di setiap client AX yang menjalankan fungsi akses ke eksternal DB tersebut. Sedang jika kita jalan di sisi server, maka ODBC cukup di setting di Server AOS. Karena itu akhirnya saya putuskan untuk jalankan aplikasi di sisi server, agar juga nanti saya bisa membuat job batch yang secara periodik melakukan download data.

            Pada server AOS jika driver belum di install maka saat menambah ODBC hanya akan muncul SQL Server.

            Setelah di install maka pilihannya menjadi:

            Terlihat versi drivernya adalah 14 (office 2010). 

            Setelah driver untuk ms Access terinstall, maka dilanjutkan membuat ODBC baru dengan target ke file .mdb yang ada di PC.



            Langkahnya isi nama datasource, kemudian select untuk memilih file mdb nya. Maka isikan langsung path shared folder nya. Dan kemudian error! 

            Error tersebut terjadi karena saat akan masuk ke shared folder tersebut membutuhkan akun. Lha gimana cara ngisi akunnya gimana? Maka kita lakukan adalah dengan konek ke folder tersebut via File Explorer, maka akan ditanya user dan password untuk masuk. Masukkan user dan password kemudian jangan lupa centang Remember My Credential agar data user dan password tersimpan. Atau dengan cara manual kita dapat langsung tambah data user dan password pada Credential Manager

            Setelah user dan password disimpan, ulangi proses Select tadi. Jika semua benar, akan muncul file mdb yang ada di dalam folder sharing tersebut. Pilih file yang dimaksud.
            Selanjutnya masukkan password untuk membuka file jika pada bagian Advanced.
            Saat saya setting ODBC ini terkadang beberapa kali tampilan ODBC tertutup sendiri. Jika seperti itu maka ulangi lagi prosesnya sampai akhirnya benar-benar tersimpan odbc nya.

            Oh ya, server AX berjalan sesuai user service nya. Maka semua proses ODBC diatas dilakukan pada user service AX tersebut.

            Ketiga, coding di AX.
            Coding di AX tidak ada hal yang khusus. Untuk membuka koneksi bisa langsung menggunakan kode di bawah ini:

            // Set the information on the ODBC.
            loginProperty = new LoginProperty();

            loginProperty.setDSN(nama DSN);


            odbcConnection = new OdbcConnection(loginProperty);
            //Assert permission for executing the sql string.
            perm = new SqlStatementExecutePermission(query String);
            perm.assert();

            //Prepare the sql statement.
            statement = odbcConnection.createStatement();
            resultSet = statement.executeQuery(query String);

            while (resultSet.next()){
                //TODO: READ per ROW
                ...
                ...
            }
            resultSet.close();
            statement.close();

            Pada case ini coding tersebut saya pasang pada sebuah Class, kemudian class tersebut di panggil di class lain yang mengimplementasikan RunBaseBatch dan class ini di jalankan via batch job.

            Jika ingin memanggil fungsi tersebut di Menu, maka jangan lupa set menu tersebut run on server.


            18 Februari 2020

            Error Deploy SSRS Report (AX). The network path was not found.

            Setelah install ulang server database AX (beserta SSRS server nya) terjadi masalah saat mencoba deploy SSRS report dari luar server tersebut. Sebelumnya saya biasa mendeploy report via Laptop kerja. Namun saat ini tidak bisa. Keluar error:

            Error 1 An error occurred : The network path was not found.
            If User Account Control (UAC) is enabled on the machine, close the application, right-click the application, and then click Run as administrator.

            Error 2 The deployment was aborted. You do not have privileges to deploy to server:....

            Padahal untuk proses Build atau Rebuild normal-normal saja. Manun error saat deploy baik via Visual Studio Shell, Powershell, atau AOT Ax itu sendiri. Ketika saya coba deploy di server langsung ternyata berhasil. 

            Saya cari di internet belum menemukan cara yang ampuh. User sudah saya tambahkan sebagai administrator di server, begitu pula di SSRS Manager. Tetap tidak bisa deploy dengan error yang sama. Termasuk pula saya coba disable UAC.

            Akhirnya setelah ber minggu-minggu saya lupakan masalah ini dikarenakan sudah jarang membuat atau mengedit report SSRS, saat ini saya mendapatkan jawaban yang tepat!

            Saya teringat saat mencoba menginstall Veeam di server coba-coba. Saat akan menambah server keluar error yang mirip: The network path was not found.
            Dan permasalahannya adalah karena service file sharing nya tidak menyala!

            Ketika saya nyalakan service file sharing yang yang terletak di Network Device, maka semua berjalan dengan normal.
            Centang ini untuk enable file sharing

            30 Januari 2018

            AOS Crash setelah membuat view

            Lagi mau buat inquiry baru di AX, dimulai dengan membuat Query-nya, kemudian dimasukkan ke view baru. Tapi tidak seperti biasanya! Jika biasanya di data source nya bisa di lihat struktur query nya. Hmm, dicoba synchronize dan compile tetap tidak bisa muncul.

            Akibatnya saya ga bisa memilih field untuk ditampilkan di view itu. Kemudian saya pilih field yang sudah tersedia (standart, seperti recId, createdBy), dan disimpan. Dan...AX nya muter-muter proses...lamaaaa, dan akhirnya putus. Wow! Cek di server nya, ternyata mati service nya. Dicoba start lagi, ok bisa nyala. Terus coba buka view yang bermasalah tadi. Belum sempat buka viewnya, baru buka tree node view ax nya hang lagi dan mati.

            Browsing2 di internet, nemu ini:
            https://dynamicsuser.net/ax/f/developers/74092/how-to-delete-form-without-clicking-on-it?pi2195=1



            Sepertinya secara tidak sengaja membuat view itu menjadi circular reference. Trus solusinya? Setelah browsing2 lagi, ketemulink ini:
            https://dynamicsuser.net/ax/f/developers/65072/aos-crashing-again-and-again-after-creating-a-query-and-a-view-help-me


            Saya langsung saja eksesuksi via database, karena memang nama view nya juga tidak ingat betul. Pertama saya perlu tau element pastinya. Saya query dulu elememnt yang dibuat pada tanggal 29 Jan 2018 oleh saya:

            select * from modelelementdata where CreatedDateTime >= '2018-01-29'

            Dari situ saya dapat ElementHandle nya. Kemudian saya cek di tabel ModelElement

            select * from ModelElement where ElementHandle IN( 984094,984098,984101,984102,984103,984105)

            Disitu terlihat view yang bermasalah dan field-fieldnya. Akhirnya saya hapus langsung ModelElement dan ModelElementData atas view yang bermasalah itu.

            Dan Alhamdulillah, AX kembali seperti sediakala.

            Note: Kejadian ini berlangsung di AX Development, bukan Production. Jadi jikapun gagal, saya masih ada opsi restore database. Jika ada yang mencoba cara ini namun ternyata tidak sesuai, maka resiko ditanggung sendiri.

            13 Oktober 2016

            Problem koneksi eksternal database (SQL Server 2012) melaului AX 2012.

            Saya ada kebutuhan untuk melakukan query terhadap data di luar database AX yang kemudian dimasukkan ke dalam data AX. Membaca dari Google, ada dua contoh. Yaitu melalui Odbc dan NET.Framework (SQLClient). Namun saya hanya berhasil mencoba yang ODBC. Dan memang contoh yang diberikan oleh Microsoft sendiri melalui ODBC karena sudah bawaan AX sendiri. Gambaran proses yang akan saya buat: AX melakukan proses query terhadap database ekseternal yang dilakukan terjadwal (via batch process). Hasil query disimpan di database AX. 

            Maka saya perlu membuat class dan mendaftarkan batch nya seperti yang ada di tutorial: https://msdn.microsoft.com/en-us/library/cc636647.aspx. Di dalam class tersebut saya isikan proses query terhadap database eksternal yang tutorialnya ada di: https://msdn.microsoft.com/en-us/library/ee677510.aspx

            Namun ternyata tidak semudah yang dibayangkan. Job menghasilkan pesan error: "Data source not found and no default driver specified"

            Dari searching di google, disebutan karena tidak ditemukannya DSN di system. Karena kita menggunakan ODBC maka kita harus membuat DSN sebagai settingan koneksi. Setelah saya tambah terjadi error yang berbeda: "The specified DSN contains an architecture mismatch between the Driver and Application"

            Kali ini error tersebut karena masalah ODBC 32 bit yang digunakan untuk 64 bit. Jika kita menjalankan class itu di sisi client (via job manual) maka kita harus setting DSN di ODBC 32 bit. Namun karena kita jalankan melalui batch maka yang dipakai adalah ODBC 64 bit. Penjelasannya di: http://dynamics-ax-live.blogspot.co.id/2009/09/error-data-source-name-not-found-and-no.html

            Selanjutnya ternyata masih error sebagai berikut:[Microsoft][ODBC SQL Server Driver][SQL Server]Cannot open database "DB_finger" requested by the login. The login failed.

            Error ini cukup lama saya cari solusinya. Karena saya tidak berhasil mencari informasi jelas di google atas problem ini. Dari pesan errornya masalahnya adalah masalah login yang gagal. Di DNS saya sudah setting user/password dengan benar. (Saya check koneksinya juga ok). Saya juga sempat mengosongkan password untuk user tersebut, namun tetap tidak berhasil dengan pesan yang sama.

            Akhirnya titik terang muncul setelah saya mencoba mengganti driver ODBC menjadi SQL Server Native Client 11.0 (SQL Server 2012) karena kemudian muncul pesan yang berbeda. "Login failed for ...."


            Dari error ini menjadi jelas, karena ternyata batch server AX tidak menggunakan user & password yang di setting di DSN. Namun menggunakan user yang sama dengan user dimana AOS service digunakan. Dan ketika saya tambahkan hak akses user tersebut terhadap database yang saya tuju ternyata hasilnya berjalan dengan sempurna.


            23 Maret 2016

            Dynamics AX Error ketika melakukan Report As Finished Production Order/Batch Order

            Sebuah BO (Batch Order/Production Order) dengan tipe Rework dilakukan proses Report as Finished. Namun keluar error: 
            The quantity cannot be reduced. The number of inventory transactions on order is too low because the quantity or part of it is referenced by an output order or a production order or is marked against other transactions.
            Permasalahannya adalah karena jumlah inventory transaction dengan status Physical. Hal ini bisa dilihat di source tempat error tersebut keluar:
            Class: 
            class InventUpd_Estimated extends InventUpdate

            Method:
            protected void updateDepreciateIssue()

            Pada method tersebut terlihat dilakukan query terhadap tabel InvenTrans dengan StatusIssue adalah >= StatusIssue::ReservPhysical

            Seperti yang diketahui, untuk BO tipe rework harus dilakukan manual reservation dan tidak perlu dilakukan proses  pick saat membuat journal Picking List. Jika dilakukan proses picking maka manual reservation yang telah dibuat akan diupdate statusnya menjadi Picked.

            Saat proses Report as Finished maka AX akan melakukan clearing terhadap status-status di inventrans, Karena dengan status Report as Finished maka remainder Qty RAF akan menjadi nol. Akibat adanya status Picked maka qty yg di clear tidak sama dengan nol.


            Solusi untuk permasalahan ini adalah dengan melakukan un-pick. 


            Maka proses Report as Finished akan berhasil.


            27 Januari 2016

            Custom Emal Notifikasi Workflow AX

            Di dalam AX, fitur workflow akan menghasilkan notifikasi pada setiap step nya. Ketika submit, approve, reject, dan lainnya. Isi dari notifikasi tersebut dapat dibuat sesuai kebutuhan. Namun terbatas sesuai field-field yang telah di sediakan. Pada workflow tabel yang memiliki master dan detail maka tampilan detailnya secara standart sangat tidak informatif, yaitu memanjang ke samping, bukan per baris kebawah. Alhamdulillah, ada cara untuk mendesain notifikasi tersebut lebih bagus. Namun notifikasi via email. Pada dasarnya, yang di custom adalah tag pada mail template, bukan tag pada workflow instruction.

            Sumber blog sebagai rujukan: https://workflowax.wordpress.com/2012/12/12/customize-your-ax-workflow-email-templates/

            1. Membuat template email untuk workflow. 

            Contoh yang saya buat:
            Microsoft Dynamics AX alert
            %for%

            Alert Message
            %message%
            Additional Information:
            %lpiwflinesdescription%
            Sent by Dynamics AX Workflow System  
            Please do not reply this email

            Tag tambahan yang saya buat adalah %lpiwflinesdescription%.  Sedangkan tag-tag lain (seperti %for%) adalah standart yang ada di AX. Jika dijalankan sekarang, maka custom tag tersebut tidak akan di parsing.

            2. Melakukan modifikasi kode untuk custom tag di email template. 

            Ada dua bagian utama yang perlu di tambah, yaitu di tabel SysEmailTable dan di class EventNotificationWorkflow.
            Pada tabel SysEmailTable, lakukan modifikasi pada method htmlEncodeParameters
            (line 16)

            while (mapEnum.moveNext()) { 
             //Modified by shindu 
             //10 Nov 2015 
             //Disable htmlEncode for customEmailTag 
             //OLD code: //encodedMap.insert(mapEnum.currentKey(),SysEmailTable::htmlEncode(mapEnum.currentValue())); 
             //New Code: 
            if (subStr(mapEnum.currentKey(),1,3) == 'lpi') //All custom tag must start with lpi    encodedMap.insert(mapEnum.currentKey(), mapEnum.currentValue()); 
            else encodedMap.insert(mapEnum.currentKey(),SysEmailTable::htmlEncode(mapEnum.currentValue())); //end by shindu 
             }

            Fungsi modifikasi ini adalah agar tag HTML tidak diencode menjadi plain text. Jika standartnya semua HTML tag akan di konversi menjadi plain text. Namun tidak semua, hanya untuk tag tertentu. Dalam hal ini tag yang huruf depannya adalah lpi, karena nama tag barunya lpiwflinesdescription.

            Kemudian lakukan modifikasi pada class EventNotificationWorkflow. Tambah method baru addCustomMergeValues

            ///
            /// Function to add custom merge values.//////
            /// Created by shindu 10 Nov 2015///
            private void addCustomMergeValues(){
            SysDictTable dictTable; 
            ExecutePermission perm; 
            str description; ; 
            // 
            if (!record) 
            return; 
            dictTable = new SysDictTable(record.tableid); 
            if (!dictTable) return; 
            if (dictTable.isMethodActual('lpiWFLinesDescription')) 
            { 
            // Grants permission to execute the DictClass.callObject method. // DictClass.callObject is protected by code access security. 
            perm = new ExecutePermission(); 
            perm.assert(); 
            try
            { 
            description = dictTable.callObject('lpiWFLinesDescription',record); 
            } catch (Exception::Error){ 
            description = ""; 
            } // // Closes the code access permission scope. 
            CodeAccessPermission::revertAssert(); 
            } else { 
            description = ""; 
            } this.addMergeValue("lpiwflinesdescription", description);
            }

            Method baru ini digunakan untuk mengisi data di tag baru yang telah dibuat. Karena tujuannya mencustom semua message dari workflow yang tabelnya berbeda-beda maka di method ini terlihat dilakukan proses call ke object table referensi ke method: lpiWFLinesDescription. Contoh jika refernsinya PurchTable maka akan dipanggil methode  lpiWFLinesDescription di tabel PurchTable. Untuk itu di langkah nomor 3 dibuat method tersebut pada setiap tabel yang ada workflownya.

            Setelah dibuat method baru di class ini, pada method sendMail dilakukan modifikasi sehingga custom tag yang kita buat dimasukkan di list xml yang dikirim ke template email.
            (line 25)

             if (sysUserInfo && userInfo && SysEmailDistributor::validateEmail(sysUserInfo.emailDisplay()))
                {
                    this.addBaseMergeValues();
                    //
                    //Add by Shindu
                    //to enable custom merge values
                    //6 Nov 2015
                    this.addCustomMergeValues();
                    //endd add


                    mergeValuesXml = EventActionEmail::createEmailParameterXml(mergeValues);

            3. Tambah method lpiWFLinesDescription di semua tabel yang memiliki workflow. 

            Seperti yang telah dijelaskan dilangkah 2, dibagian ini lah isi message custom yang kita buat harus ditambahkan. Kita ambil contoh kasus workflow untuk Purchase Order. Maka kita buat method baru ini di tabel PurchTable.



            Kita lakukan formating di bagian ini. 

            Hasil akhir

            Setelah semua proses compile dilakukan, maka hasilnya akan seperti dabawah ini:







            12 November 2015

            Export EFaktur di Dynamics AX 2012

            Masa EFaktur telah tiba, divisi IT di seluruh perusahaan mendapat tugas baru: Export data dari aplikasi perusahaan ke aplikasi EFaktur!

            Nah kali ini saya akan berbagi cerita untuk export data dari Microsoft Dynamics AX 2012.

            Dalam aplikasi EFaktur ada tiga hal yang perlu proses Export/Import:
            1. Data Lawan Transaksi (Master Vendor/Supplier)
            2. Pajak Keluaran
            3. Pajak Masukan

            Lawan Transaksi

            Untuk data lawan transaksi, untuk saat ini tidak dibuatkan data exporter nya ke EFaktur, karena data Nama dan Alamat di AX ternyata masih banyak yang salah/tidak sesuai dengan data Nama dan Alamat menurut NPWP. Jadi malah dari EFaktur di export ke AX.
            Namun hanya untuk proses awal, untuk customer/vendor baru saya minta agar user di bagian masing-masing yang mengupdate data di AX sesuai data EFaktur. 

            Saya simpan data nama dan alamat efaktur tersebut di tabel TaxVATNumTable dengan menambah satu field untuk menyimpan alamat. (LPI_Address)
            Format file csv nya:
            "LT","NPWP","NAMA","JALAN","BLOK","NOMOR","RT","RW","KECAMATAN","KELURAHAN","KABUPATEN","PROPINSI","KODE_POS","NOMOR_TELEPON"

            Field pertama selalu "LT", kemudian nomor NPWP tanpa tanda penghubung (- dan .). Selanjutnya Nama sesuai NPWP. Untuk alamat di pisahkan antara jalan, blok, nomor, rt, rw, kecamatan, kelurahan, kabupaten, propinsi, dan kode pos. Terakhir adalah nomor telepon.


            Pajak Keluaran

            Adalah faktur pajak yang dikeluarkan ke Customer. Biasanya konsultan ax di Indonesia akan membuatkan modul pajak indonesia, termasuk juga konsultan yang saya gunakan. Maka data yang saya ambil adalah data dari modul custom tersebut. Jika tidak ada modul custom tersebut langsung ambil dari data invoice juga bisa. Yang terpenting kita lihat dulu data apa yang dibutuhkan oleh aplikasi EFaktur.

            Untuk pajak keluaran, format CSV nya adalah sebagai berikut: 
            Satu file CSV ini dapat berisi lebih dari satu data faktur pajak

            line 1: Header FK, fix seperti dibawah ini:
            "FK","KD_JENIS_TRANSAKSI","FG_PENGGANTI","NOMOR_FAKTUR","MASA_PAJAK","TAHUN_PAJAK","TANGGAL_FAKTUR","NPWP","NAMA","ALAMAT_LENGKAP","JUMLAH_DPP","JUMLAH_PPN","JUMLAH_PPNBM","ID_KETERANGAN_TAMBAHAN","FG_UANG_MUKA","UANG_MUKA_DPP","UANG_MUKA_PPN","UANG_MUKA_PPNBM","REFERENSI"

            line 2: Header LT, fix seperti dibawah ini:
            "LT","NPWP","NAMA","JALAN","BLOK","NOMOR","RT","RW","KECAMATAN","KELURAHAN","KABUPATEN","PROPINSI","KODE_POS","NOMOR_TELEPON"

            line 3: Header OF, fix seperti dibawah ini:
            "OF","KODE_OBJEK","NAMA","HARGA_SATUAN","JUMLAH_BARANG","HARGA_TOTAL","DISKON","DPP","PPN","TARIF_PPNBM","PPNBM"

            Kemudian line 4 dan seterusnya itu adalah faktur dan isinya.
            Setiap faktur maka akan berisi:

            line 4: Data FK (Faktur Keluaran), berisi data sesuai heder FK di line 1. Contoh:
            "FK","01","0","1234567890","10","2015","06/10/2015","000000000000","PT.XXX","JL Jalan",1000,100,0,"",0,0,0,0,""
            Field pertama adalah flag, selalu  "FK". Nomor NWPW tanpa tanda pemisah. 

            line 5: Data  OF (Object Faktur), berisi detail data dari faktur pajak.
            "OF","KODE1","ITEM 1",10,100,1000,0,1000,100,0,0
            Field pertama selalu OF diikuti kode item dan nama item. Jika satu faktur pajak terdiri dari banyak item/line maka line selanjutnya (6 dan seterusnya) tetap berisi data OF. Setelah itu dilanjutkan dengan baris data FK lagi jika memang dalam satu file csv terdapat lebih dari satu data faktur pajak. 

            Contoh file hasil export pajak keluaran dengan data 1 faktur pajak dan 1 item

            Pajak Masukan

            Adalah faktur pajak dari vendor/supplier. Format nya lebih sederhana daripada pajak keluaran.

            Line 1: Heder FM, fix seperti dibawah ini:
            "FM","KD_JENIS_TRANSAKSI","FG_PENGGANTI","NOMOR_FAKTUR","MASA_PAJAK","TAHUN_PAJAK","TANGGAL_FAKTUR","NPWP","NAMA","ALAMAT_LENGKAP","JUMLAH_DPP","JUMLAH_PPN","JUMLAH_PPNBM","IS_CREDITABLE"

            Line 2: Data FM (Faktur Masukan). Pada pajak masukan, tidak ada data detail yang di inputkan. Kita hanya perlu input data per faktur pajak. Sehingga dari line 2 dan seterusnya akan di isikan data faktur pajak.  Formatnya:
            "FM","01","0","000000000","10","2015","01/10/2015","00000000","PT XXX","JL. Alamat lengkap",10000,1000,0,"1"
            Field pertama selalu "FM". Nomor NWPW tanpa tanda penghubung.
            Contoh file hasil export pajak masukan

            Custom di Dynamics AX

            Setelah jelas format dan data yang dibutuhkan, maka proses exportnya tinggal menyesuaikan. Tinggal di cari data asal yang akan diambil.

            Skenario yang saya gunakan,  tersedia form yang berisi datagrid data pajak yang akan diexport. Kemudian user memilih data di grid tersebut (bisa multiselect) dan menekan tombol export. 

            Parameter class:
            currentFileName, untuk set nama file hasil outputnya
            currentHelper, untuk set MultiSelectionHelper
            currentTaxType, untuk set tipe tax Pajak Masukan atau Keluar

            Secara garis besar algoritma exportnya:
            1. getHeaders, menuliskan header sesuai tipe tax nya (in atau out)
            2. getFakturData, menuliksan data FK/FM
                Untuk setiap line dari data maka:
                2.1. getOFs, menuliksan OF (khusus untuk pajak keluaran)
            3. Kembali ke nomor 2 jika masih ada data faktur
            4. Selesai

            Penutup

            Dari aplikasi EFaktur saat ini menurut saya masih ada kekurangan. 
            Pertama, seharusnya data yang di export ke Efaktur itu cukup nomor NPWP tanpa data nama dan alamat. Kalau pun data nama dan alamat di masukkan itu hanya sebagai refernsi agar tidak salah. Namun saat ini jika data nama dan alamat tidak sama dengan data sesuai NPWP di server pajak, maka akan ditolak. 
            Kedua akan lebih baik jika aplikasi yang digunakan adalah full web online. Jadi para wajipb pajak hanya meng upload data-data csv hasil export aplikasi internal.