Kamis, 05 Desember 2019

Custom notification

If you want to try custom your notification, 
AX Standard can bring the user to the form where the information exist but when the form was open system show all the records. try modify this class EventContextInformation to get just only selected record show front of your desk.

this custom method found by Rony.

Jumat, 01 November 2019

Create record Purchase Agreement through x++

My code here is to copy Purchase Agreement line from reference Purchase Agreement to new Purchase Agreement.

static void PSMCopydirecttoagreementline(Args _args)
{
    AgreementLineQuantityCommitment agreementLineQuantity;
    AgreementLineQuantityCommitment xagreementLineQuantity;
    AgreementLineVolumeCommitment   agreementlinevolume;
    AgreementLineVolumeCommitment   xagreementlinevolume;
    PurchAgreementHeader            purchAgreementHeader = PurchAgreementHeader::findAgreementId("PSM-000020");//Header reference
    purchAgreementHeader            xpurchagreementheader =  PurchAgreementHeader::findAgreementId("PSM-000078");//Header baru



    //Jika Komitment Purchase Agreement berdasaran kuantity
    if(purchAgreementHeader.DefaultAgreementLineType == CommitmentType::ProductQuantity)
    {
        info("Quantity based");
        //copy line AgrementLIneQuanity menjadi line baru
        while select agreementLineQuantity
            where agreementLineQuantity.Agreement == purchAgreementHeader.RecId
        {
            xagreementLineQuantity.clear();
            xagreementLineQuantity.data(agreementLineQuantity);
            xagreementLineQuantity.Agreement = xpurchagreementheader.RecId;
            xagreementLineQuantity.doInsert();
        }
    }
    else
    {
        //Jika Komitment Purchase Agreement BUKAN berdasaran kuantity
        info("value based");
        while select agreementlinevolume
            where agreementlinevolume.Agreement == purchAgreementHeader.RecId
        {

            xagreementlinevolume.clear();
            xagreementlinevolume.data(agreementlinevolume);
            xagreementlinevolume.Agreement = xpurchagreementheader.RecId;
            xagreementlinevolume.doInsert();
        }
    }

}

below is how to setup and create new Purchase Agreement(header) from reference Purchase Agreement(header) through x++

void createDuplicate()
{
    ttsBegin;
    this.setHeader();
    this.createPurchAgreementHeader();
    this.setLine();
    //this.createAgreementLine();
    ttsCommit;

    info("done");
}

void setHeader()
{
    PurchAgreementId    tmpAgreementId;
    NumberSeq           num;

    xpurchagreementheader.clear();
    xpurchagreementheader.data(purchAgreementHeader);
    xpurchagreementheader.WorkflowStatus_PSN = PurchAgreementWorkflowStatus::NotSubmitted;
    xpurchagreementheader.PSMTotalNetAmount = 0;


    num = NumberSeq::newGetNum(PurchParameters::numRefPurchAgreementId());
    tmpAgreementId = num.num();

    info(strFmt("num %1",tmpAgreementId));
    if (PurchAgreementHeader::findAgreementId(tmpAgreementId).RecId)
    {
        num.abort();
        checkFailed("@SYS19304");
        checkFailed(strfmt("@SYS24176", tmpAgreementId));
        throw error("@SYS23020");
    }

    xpurchagreementheader.PurchNumberSequence = tmpAgreementId;
    num.used();

    agreementHeaderDefault = AgreementHeaderDefault::findAgreementHeader(purchAgreementHeader.RecId);
    if(agreementHeaderDefault.RecId)
    {
    xgreementHeaderDefault.clear();
    xgreementHeaderDefault.data(agreementHeaderDefault);

    }
    purchAgreementHeaderDefault = PurchAgreementHeaderDefault::findPurchAgreementHeader(purchAgreementHeader.RecId);
    if(purchAgreementHeaderDefault.RecId)
    {
    xpurchAgreementHeaderDefault.clear();
    xpurchAgreementHeaderDefault.data(purchAgreementHeaderDefault);

    }

void createPurchAgreementHeader()
{
    xpurchagreementheader.insert();

    xgreementHeaderDefault.AgreementHeader = xpurchagreementheader.RecId;
    xgreementHeaderDefault.insert();

    xpurchAgreementHeaderDefault.PurchaseAgreementHeader = xpurchagreementheader.RecId;
    xpurchAgreementHeaderDefault.insert();
}

note :
u must define/create those 3 method createDuplicate(),setHeader() and createPurchAgreementheader() in the class. for me i called those three methods in run() method.




Selasa, 29 Oktober 2019

Opening balance on report Summary trial balance showing 0

Ada case dimana pada saat kita mengenerate report summary trial balance value dari opening balance = 0.

anda bisa coba jalankan job berikut :

static void ClearCache(Args _args)

{

    LedgerCache::clearAllScopes();

    pause;

}

Minggu, 18 Agustus 2019

Create InventDim otomatis

Disini akan diperlihatkan bagaimana kita membuat/memakai nomor InventdimId secara otomatis.

Sebagai contoh, buatlah satu Table yang mempunyai field inventdimId. disini saya buat contoh table HYInvetdimDisplay.
dengan field IDHY,InventDimId,ItemId

Relasi :
HYNInventdimDisplay.InvetDimId <> InventDim.InventDimId
HYNInventdimDisplay.ItemId<> InventTable.ItemId

ketik method2 berikut ditable kamu :
public InventDim inventDim(boolean _forUpdate = false)
{
    return InventDim::find(this.InventDimId,_forUpdate);
}

public server void modifyInventDim(InventDim _inventDim, FieldId _tableField)
{
    InventDim   inventDimLocal = InventDim::findOrCreate(_inventDim);

    ;

    this.setInventDimId(inventDimLocal.InventDimId, _tableField, inventDimLocal);
}

public void setInventDimId(InventDimId _inventDimId, FieldId _tableField, InventDim _inventDim = InventDim::find(_inventDimId))
{
    InventDim   currentInventDim = this.(_tableField) == _inventDimId ? _inventDim : this.inventDim(_tableField);

    this.(_tableField) = _inventDimId;
}

Kita menuju ke pembuatan GUI :

buat sebuah form dengan DataSource
>HYNInventdimDisplay
>InventDim
Property InventDim :


Tambahkan method berikut di Datasource InventDim :

public void initValue()
{
    InventDim.data(InventDim::find(HYNInventdimdisplay.InventDimId));
    super();
}

void inventDimModified()
{
    HYNInventdimdisplay.modifyInventDim(InventDim, fieldNum(HYNInventdimdisplay, InventDimId));
    InventDim.data(InventDim::find(HYNInventdimdisplay.InventDimId));
    InventDim_ds.setCurrent();
    InventDim_ds.reread();
    InventDim_ds.refresh();
}

Tambahkan method berikut pada setiap field yang akan dijadikan sebagai dimension sebuah Item :
public void modified()
{
    super();
    InventDim_ds.inventDimModified();
}


Minggu, 28 Juli 2019

Error "Object reference not to set to an instance of an object" SSRS AX 2012 (versi 2)

Error "Object reference not to set to an instance of an object" SSRS AX 2012


Sekali lagi saya akan menceritakan (saya pakai kata "menceritakan" karena ..saya ingin pakai daripda saya menggunakan kata "menjelaskan") bagaimana menangani error diatas. Sebelumnya saya juga sudah pernah mengceritakan penanganan error tersebut dipostingan saya sebelumnya.

Kali ini, error ini muncul pada saat kita mau test hasil deploy SSRSReport dari Environment DEV ke LIVE. (sumpah ini error ini emang bikin jengkel, kenapa harus selalu muncul di SSRS).

Pertama :
Setelah deploy element SSRSReport kita di AOT .
Masuk ke \\Users\[folder user]\[appdata]
 delete semua file *.uac
Masuk ke AOT lagi.
 Refresh report server , clear chace Dsb.

Coba test print.

Rabu, 03 Juli 2019

/DynamicsAx/PurchPurchaseOrderreport.Report4´ cannot be found (rsItemNotFound)

"Error while setting server report parameters. Error Message: The item ´/DynamicsAx/PurchPurchaseOrderreport.Report4´ cannot be found (rsItemNotFound)"


Error ini muncul jika custom design report yang kita buat belum sepenuhnya terdeploy di environment yang kita tuju.
pada kasus saya, di Visual studio sudah berhasil dideploy. Tetapi pada saat aplikasi akan mengupdate database report akun yang saya pakai ternyata tidak mempunyai permision untuk merubah table report yang ada di server SSRS.
maka error selanjutnya jika kamu lanjutkan 'klik kanan pada object ssrs > Deploy element' akan mendapatkan error "you dont have permision... bla.. bla... contact your administrator".

Biasanya ini terjadi jika kita mempunyai 2 Environment atau 2 AOS.
Ex : AOS1 dan Visual Studio yang konek ke AOS1
       AOS2

Saat kita memakai client yang berseting AOS1 tetapi Configurasi AX ke AOS2. maka error ini akan muncul saat kita mencoba untuk deploy report SSRS. Maka arahkan configurasi ke AOS1.



Blank page/paper diawal/antara/akhir halaman report

Terkadang report SSRS yang diexport atau disave dalam format PDF akan membuat halaman kosong pada awal/antara/akhir perhalaman report. walaupun diScreen report AX report tsb baik-baik saja.

Cara pertama :
beri warna semua field object direport. karena kamu tidak akan menemukan sesuatu pada report kamu jika feld border tersebut tdak berwana. Jika field borderline kamu berwarna, pada saat dieksport ke PDF kita akan melihat kelebihan2 dari field yang kepanjangan sampai ke halaman berikutnya.




Cara kedua :
Buat semua margin = 0cm
Jangan sisakan ruang kosong pada Page Properties report kamu.

Selamat mencoba.

Selasa, 02 Juli 2019

Cara mengetahui regionId

coba dan tambahkan code berikut diJob baru kalian.

static void PSMcobacountryregionID(Args _args)
{
    LogisticsAddressCountryRegionISOCode isoCountryCode = SysCountryRegionCode::countryInfo();
    
    LogisticsAddressCountryRegionId countryRegionId = SysCountryRegionCode::getCountryRegionIdByIsoCode(isoCountryCode);
    
    ;
    
    info(isoCountryCode);
    info(countryRegionId);
}

ini biasanya bisa dipakai untuk mengidentifikasi/custom Report Purchase Order/Sales Order 

Mencetak price pada report Purchase Order

https://community.dynamics.com/ax/f/microsoft-dynamics-ax-forum/258358/how-do-you-print-a-purchase-order

Custom Purchase Order Report AX2012

Class pembentuk untuk report Purchase Order :
PurchasePurchaseOrderController class. 
PurchPurchaseOrderContract class.
PurchPurchaseOrderDP class.

Table temporary untuk datanya :
PurchPurchaseOrderTmp 



Untuk merubah design atau menambah format design report purchase order tidak hanya dilakukan pada Code classnya saja tetapi harus melalui :
Menu 
Procurement and Sourching > Setup > Forms > Form Setup
di Form Setup, menu General klik tombol Print Management.



Buka node Purchase Order. pada panel sebelah kanan dropdown field report format.
Jika tidak ada design baru yang kamu buat. maka, temukan tabel PrintMgmtReportFormat method Populate

PrintMgmtReportFormat::populate

tambahkan code berikut :(yang italic dan bold, saya menambahkan design Report4)

//
    switch (isoCountryCode)
    {
        case #isoCZ, #isoHU:
            addAX(PrintMgmtDocumentType::PurchaseOrderRequisition, countryRegionId);
            break;

        default:
    //
        addAX(PrintMgmtDocumentType::PurchaseOrderRequisition);
    //
       //husna
       addOther(PrintMgmtDocumentType::PurchaseOrderRequisition, ssrsReportStr(PurchPurchaseOrder, Report4), ssrsReportStr(PurchPurchaseOrder, Report4),countryRegionId);
            //husna
    }


Referensi :
https://community.dynamics.com/ax/f/microsoft-dynamics-ax-forum/137972/customize-the-purchase-order-report

https://cloudblogs.microsoft.com/dynamics365/no-audience/2012/05/24/dynamics-ax-2012-reporting-how-to-specify-new-design-for-sales-order-confirmation/



Jumat, 28 Juni 2019

Membuat proses yang bekerja menggunakan batch job


Proses ini akan bekerja berdasarkan batch job. 
Contoh :
Kita akan membuat suatu proses update pada sebuah table. ex ItemHusna, table master untuk data Item yang datasourcenya dari InventTable

buatlah class. contoh HYNmahasiswa.
class HYNmahasiswa
{
    InventTable         itemTable;
}

buat method : processRecords

[SysEntryPointAttribute(false)]
public void processRecords()
{
    int             counter = 0;
    InventTable       tableInvent;


    //Determines the runtime
    if (xSession::isCLRSession())
    {
        info('Running in a CLR session.');
    }
    else
    {
        info('Running in an interpreter session.');

        //Determines the tier
        if (isRunningOnServer())
        {
            info('Running on the AOS.');
        }
        else
        {
            info('Running on the Client.');
        }
    }
     
//panggil method yang akan mengupdate table ItemHusna

While select tableInvent
{
      this.getDataitem(tableInvent.ItemId);
}

    info(strFmt("Successfully processed %1 records.", counter));
}

//buat mehtod getDataitem([parameter dengan extended data type ItemId]
public void getLeadtime(ItemId  _itemId)
{
    ItemHusna               dataitemhusna;
;

select forupdate dataitemhusna;
ttsbegin;
     dataitemhusna.itemid = _itemid.itemid;
     dataitemhusna.insert();
ttscommit;
}

Buat menuitem Output dengan propertis sebegai berikut.

Label            : [nama label akan muncul di batch queue]
Object type  : Class
Object          : SysOperationServiceController
Parameters   : HYNmahasiswa.getLeadtime

FULL CILL Aplikasi AX.

Pada menu Item action HYNmahasiswa > klik kanan > Open.

maka terbuka form dialog untuk menjalankan batch job. pilih group batch jobnya, atur recurencenya klik OK.

Selasa, 14 Mei 2019

About UTCDATETIME

Saat kita membuat suatu parameter query berdasarkan date tetapi yang akan dijadikan sql statement itu mempunyai tipe data UtcDateTime.
yang meminta proggrammer bukannya value date tetapi juga value time.

Bisa kita pakai logic pendefinsian seperti ini :

date             fromdate;
date             todate;
TimeOfDay               starttime;
TimeOfDay               endtime;
utcDateTime         fromutc;
utcDateTime         toutc;

;

fromdate = 08\01\2019;
todate = 09\01\2019;
starttime = str2time("00:00:00");
endtime = str2time("00:00:00");

fromutc = DateTimeUtil::newDateTime(fromdate,starttime);
toutc = DateTimeUtil::newDateTime(todate,endtime);

kita lihat disini UTCDATETIME bisa dibentuk dari dua buah variable, Date dan juga Timeofday.

Senin, 13 Mei 2019

Membuat Credit Note di PO

Ada kalanya kita salah input untuk Product Receipt, hingga berimbas ke Invoice PO.
Di Ax sebelumya kita bisa memperbaiki hal tsb dengan entri baru Product receipt dengan nilai qty minus. Sedangkan di AX2012 fitur tersebut sudah dihilangkan.

Gantinya AX2012 menggunakan Credit Note.
Berikut cara2nya.



  1. Pilih no PO yang bermaslah dengan product receipt dan invoice tsb.
  2. Create PO baru dengan vendor dari PO bermasalah tersebut.
  3. setelah terbuat pilih menu/tombol 'Credit note' 
  4. pilih Invoice yang muncul berdasarkan Vendor yang dipakai
  5. mark invoicenya dan juga line yang ingin didelete.
  6. klik OK
  7. maka PO tersebut mempunyai nilai Qty minus.
selamat mencoba.

Kamis, 02 Mei 2019

The SQL Server Reporting Services Server name does not exist or the Web Service URL is not valid

"The SQL Server Reporting Services Server name does not exist or the Web Service URL is not valid"

Hari ini aku menemukan error pada saat validasi konfigrasi report server.
bisa disebabkan karena beberapa hal.
1. Pastikan Report Manager URL dan WEB service URL sama dengan alamat yang ada di Reporting Services Configuration manager.
jika masih belum "success"
2. coba buka firewall di report server. maka cek di Windows Firewall advance security.
https://community.dynamics.com/ax/b/fsilvajunior/archive/2016/10/28/dynamics-ax2012-relat-rios-erro-ao-validar-configura-es
3. Jika masih saja muncul coba mengubah alamat Report Manager URL dan WEB service URL yang tadinya oleh alamat IP menjadi alamat HostName:

http://setspn.blogspot.com/2013/07/ax-2012-validate-settings-fails-for.html

Sabtu, 27 April 2019

Create Header Detail without define relation table

Requirement :
James sebagai directur perusahaan tidak mau melihat comment workflow yang tersimpan di Form Workflow. James menginginkan informasi workitem dan comment ada diform utama.

Req ini bisa kita kerjakan dengan metode QUERY,VIEW, Query table/view dengan QUERY CLASS

Pertama kita harus membuat QUERY yang terbuat dari Table-table workflow dan tentunya berelasi dengan table document entah itu jurnal,PO atau apapun.

Sebagai contoh disini adalah table SQ.

CREATE QUERY : SQ2WFQuery
SQ berelasi dengan WorkflowTrackingStatusTable,
melalui :
              SQ.dataareaId <> WorkflowTrackingStatusTable.ContexCompanyId
              SQ.RecId        <> WorkflowTrackingStatusTable.ContectRecId
              SQ.TableId      <> WorkflowTrackingStatusTable.ContextTableId

WorkflowTrackingStatusTable berelasi dengan WorkflowTrackingTable,
melalui :
       WorkflowTrackingStatusTable.RecId <> WorkflowTrackingTable.WorkflowTrackingStatusTable

WorkflowTrackingTable berelasi dengan WorkflowTrackingCommentTable
melalui :
       WorkflowTrackingTable.RecId <>  WorkflowTrackingCommentTable.WorkflowTrackingTable

CREATE VIEW : SQ2WFView
VIEW yang sudah dibuat dengan nama SQ2WFview dengan Query SQ2WFQuery.
Definisikan field mana saja yang akan dibawa sebagai field SQ2WFView
ex : SQnum, TrackingStatus, User, TrackingType, Comment.
Defisinikan Field2 yang akan dipakai dengan cara memasukannnya keGroup

DIform SQTable. Tambah Datasourcenya dari SQ2WFView.
Dikarenkaan source yang kita pakai berasal dari VIEW sehingga kita membutuhkan codes yang akan membuat SQ2WFView berelasi ke SQTable.di Method Exceute Query table SQ2WFView harus didefisikan code berikut :


public void executeQuery()
{
    //mendefinisikan variable qbds
    QueryBuildDataSource    qbds;

    //qbds tersebut adalah Datasourcenya sendiri(yang diadd di form)
    qbds = this.queryBuildDataSource();
   
    //qbds membersihkan chace range query agar default selalu dalam keadaan kosong
    qbds.clearRanges();
    //qbds melakukan query seperti "while select" berdasarkan paramater SQTable.SQNum
    qbds.addRange(fieldNum(PSMWF2SQtableView, SQNum)).value(SysQuery::value(SQTable.SQNum));

   //maka Datasource SQ2WFView berisi hasil Query = While select * from SQ2WFView where  SQ2WFView.SQnum == SQTable.SQNum

    super();
//setelah super() maka hasil Query ditampilkan di Grid
}





Senin, 22 April 2019

Relasi antara Worfklow dan Table document

Berikut Relasi antara Workflow dengan Table docment yang memakai workflow:

WorkflowTrackingStatusTable.ContextCompanyId <> [tabledocument].DataAreaId
WorkflowTrackingStatusTable.ContextRecId          <> [tabledocument].RecId
 WorkflowTrackingStatusTable.ContextTableId      <>  tabledocument].TableId

Sample :
Asumsi saya mempunyai table dengan nama RFPTable
 

WorkflowTrackingStatusTable             wfstatustable;
WorkflowTrackingTable                      wftrackingtable;
Description                                           descriptwf;
RFPTable                                              rfpTable;
    ;

    select * from rfpTable
    where rfpTable.TransNum == _dfpnumber;

    select * from wfstatustable
    where wfstatustable.ContextCompanyId == rfpTable.dataAreaId
    && wfstatustable.ContextRecId == rfpTable.RecId
    && wfstatustable.ContextTableId == rfpTable.TableId
    && (wfstatustable.TrackingStatus == WorkflowTrackingStatus::Completed || wfstatustable.TrackingStatus == WorkflowTrackingStatus::Pending);

    while select * from wftrackingtable
        order by createdDateTime asc
        where wftrackingtable.WorkflowTrackingStatusTable == wfstatustable.RecId
        && (wftrackingtable.TrackingType == WorkflowTrackingType::Submission || wftrackingtable.TrackingType == WorkflowTrackingType::Approval)
    {
        descriptwf += strFmt("%1 (%2).",wftrackingtable.User,wftrackingtable.TrackingType);
    }

    return descriptwf;

Cannot save the record because the Number Sequence already Exist

Ada kalanya saya menemukan system memakai Nomor sequence yang sama/duplicate pada saat menyimpan/create record baru. dan akhirnya sistem sendiri mengeluarkan info
"cannot save the record because the number sequence already exist".

Trouble solving :
Masuk ke menu :
Organization and Administration - Common - Number Squences - Number Sequences

Pilih nomor sequencenya.
Klik tombol Status Listnya.
Form status list akan tampak.


Maka akan kita temukan satu atau beberpa nomor disana.
Nomor-nomor tersebut adalah yang muncul pada saat user create record ditable yang bersangkutan.
Jika memang nomor yang selalu muncul/duplicate pada saat create record itu tidak akan digunakan lagi, kta bisa mendeletenya.

untuk detailnya untuk apa form ini?
saya juga blum tahu. :D

error ax 2012 sysdictfieldgroup object not initialized.

error ax 2012 sysdictfieldgroup object not initialized

Pada saat saya akan test Pengkondisian di Workflow, error ini muncul.
Trouble solving untuk seperti ini bisa dengan menambahkan Field(bebas) di Group Table yang dijadikan parameter di workflow kita. 
tambahkan Field apa saya diGroup Auto Report. 

Minggu, 14 April 2019

simple Logic for Grouping some records

Check this out :

thanks to Tukang Ojek ASP who create this simple logic.

ListPaymentGenralJournalAccount2V       viewPayment;
    CustVendAC                              CustVendAC,lastvalue;
    Amount                                  sumAmount;
    int                                     i=1;
    int                                     numofrecord;
    

while select viewPayment
    where viewPayment.JournalNum == ListPaymentGenralJournalAccount2V.JournalNum
    {
        CustVendAC = viewPayment.CustVendACcount();
        numofrecord += 1;
        if(CustVendAC == lastvalue)
        {
            sumAmount += viewPayment.AccountingCurrencyAmount;
            info(strFmt("%1",sumAmount));

        }
        else if(CustVendAC != lastvalue && i != 1)
        {
            info("beda");
            sumAmount = viewPayment.AccountingCurrencyAmount;
            info(strFmt("%1",sumAmount));
        }
        lastvalue = CustVendAC;
        i += 1;
    }

Kamis, 21 Februari 2019

Relasi tabel Finansial Dimension dengan PurchReqLine

Berikut ini adalah relasi antara Tabel PurchReqLine dengan Finansial Dimension.
ada beberapa tabel yang terlibat, diantaranya :

PurchReqLine             
DimensionAttributeValueSet 
DimensionAttributeValueSetItem
DimensionAttributeValue
DimensionAttribute
DimensionValue


Minggu, 03 Februari 2019

error http://tempuri.org/:queryBuilderArgs dan The remote server returned an error: (500) Internal Server Error.

Selamat Pagi,

Disini ada salah satu cara untuk solusi menangani error "http://tempuri.org/:queryBuilderArgs" dan "The remote server returned an error: (500) Internal Server Error" ...

bisa dilakukan secara technical :
1. Clear all chace
2. AOT-->Service Groups-->Klik kanan BLService-->Deploy Service Group

bisa dilakukan secara functional :
Sytem administration > Setup > Services and Aplication Integration Framework > inbound ports.
cari BIServices, bikin Deactive lalu aktifkan lagi.

Selamat mencoba.
jangan lupa Bismillah.

Erorr CS1963 - An expression tree may not contain a dynamic operation.

Kali ini saya mendapatkan erorr dengan code CS1963, padahal sebelumnya saya sudah mendefinisikan 'var item in Model' di @foreach(var...