Subscribe

RSS Feed (xml)

Powered By

Skin Design:
Free Blogger Skins

Powered by Blogger

Rabu, 12 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.


Rabu, 05 Oktober 2016

Temperature & Humidity Monitoring

Ruang server seharusnya memiliki suhu ruangan antara 18-27 derajat celcius. Tentu untuk mencapai range suhu tersebut dibutuhkan sistem pendingin. Baik itu mengguakan AC, atau pun pengaturan aliran udara. Kadangkala sistem pendingin tersebut tidak berjalan dengan baik. Terutama jika pendingin ruang server menggunakan AC standart. Saya sendiri pernah mengalami kejadian dimana AC yang digunakan tidak bekerja dengan baik, sehingga tidak dapat mendinginkan suhu ruang server. Akibatnya fatal, server overheat dan menshutdown dirinya.
Dengan pengalaman tersebut, saya terpikir untuk implementasi Temperature & Humidity Monitoring, sehingga suhu ruang server dapat dimonitor 24 jam. Langkah pertama, saya membutuhkan display yang dapat menampilkan suhu ruang server. Display tersebut harus dapat dilihat oleh team security yang rutin melakukan patroli di area pabrik dan dicatat dalam log book. Saya juga buatkan SOP terkait suhu ruang server. Apa yang harus dilakukan team security ketika suhu ruang server pada tiap levelnya.

Dari beberapa penawaran vendor, ada satu vendor yang cukup menarik penawarannya. Selain display (dan sensornya tentunya) temperature dan humidity, terdapat fitur wifi di alat tersebut. Sehingga mengambil data dari alat melalui jaringan komputer.
Penampakan alat

Secara tampilan dan fungsional alat ini cukup baik. Pengerjaannya masih belum terlalu profesional. Terlihat pemasangan plat-plat nya tidak sempurna. Selain itu, tidak disertakan buku paduan/petunjuk mengenai alat ini. Paduan dan petunjuk akhirnya diberikan via email setelah saya komplain. Itu pun masih kurang jelas. Saya harus kontak berkali-kali untuk dapat membuat alat ini dapat tersambung dengan jaringan kantor.
Penampakan software nya
Untuk sofware bawaannya, secara fungsi sudah ok. Bisa menampilkan data. Namun tidak user firendly. Karena setiap kali buka aplikasi nya, saya harus ganti IP address nya. Harusnya ada fasilitas simpan setting. Dan ada hal penting buat saya yang tidak ada di aplikasi ini. Yaitu fasilitas logging atau menyimpan data-data yang telah lalu. 

Sayapun memutuskan untuk membuat sendiri aplikasi monitoring ini. Dengan melakukan koneksi (socket programming) ke port 80, kemudian menjalankan command tertentu, maka response nya berupa tampilan "Temperature : xx || Humidity : yy". Saya tinggal melakukan parse atas hasil tersebut untuk mendapatkan nilai temperatur dan humidity. 

Buatan sendiri
Cara kerjanya adalah pada setiap waktu tertentu akan menampilkan data, dan pada waktu tertentu lainnya menyimpan value tersebut ke database. Jadi tidak semua value disimpan. Pertimbangannya untuk penghematan dan tidak perlu juga harus menyimpan data terlalu banyak. Saya setting 10 menit sekali data disimpan. Saya pilih database nya menggunakan MySQL karena rencananya saya akan integrasikan ke website internal perusahaan. Saat ini saya sudah membuat web page untuk menampilkan secara grafis history temperature dan humidity.



Oh ya, alat ini menggunakan Ardunio sebagai processornya. Referensi yang berguna:
http://www.instructables.com/id/Temperature-and-Humidity-Datalogger-Webserver

Dengan cara diatas tidak perlu lagi membuat program logger sendiri, karena sudah di kerjakan langsung di perangkatnya.




Selasa, 22 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.


Rabu, 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: