Rabu, 27 Mei 2020

Error http://tempuri.org

when you got an error in AX and you start looking forward for solution in the internet you will found the same way how to "cure" the illness.
going to AOS Service > restart the service. or Redeploy the BIService.
and sometimes those solutions is not working at all. 
the error "The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:queryBuilderArgs..bla..bla..bla.." we found that its because the BIService failed but its caused your drive where the SQL Server SSRS installed is getting full. its not have enough space to process all the request.

Rabu, 29 April 2020

System does not support setup 'continuous' of number sequence

When we work with entries data that contain sequence number sometime we need an improvement to create in another way, a Generate perhaps.

Usually we can use the code like this :

//number sequence MRIS
    NumberSeq                       num;
;

num = NumberSeq::newGetNum(InventParameters::[method for Sequence number]);

it can be work if the continuous cekbox, in Sequence number master is false.

but fi the continuous cekbox, in Sequence number master is True, the system will give a message "System does not support setup 'continuous' of number sequence"

so you need to put ttsbegin and ttscommit on your codes :

NumberSeq                       num;
Sampletable                      sampletable;
;
ttsbegin;

num = NumberSeq::newGetNum(InventParameters::[method for Sequence number]);
sampletable.clear();
sampletable.number =  num.num();
sampletable.insert();

ttscommit;

  

Selasa, 07 April 2020

Show Active bank account

In Ax2012 there is VendBankAccount table.
there's one field shown on our screen that gives us information the state of bank account. Active or inactive.
unfortunately this information made by a method.

so how to make a query to filter or specify the record, active or inactive?
Activedate and Expiredate in VendBankAccount, both made by UTCDateTime
Bank account state made by method.

i guess for some programmer it is gonna be tricky.

Working with UTCDateTime is need call another method dan extended data type especially to get current date and time.

this is my example method how to filter/specify whether the Bank Account is active or expired.
i applied this method when user Lookup Bank Account.

static void lookupVendBankAccountId(FormStringControl _formControl, VendAccount _vendAccount)
{
    SysTableLookup          sysTableLookup;
    Query                   query;
    QueryBuildDataSource    qbds;
    
    //Working with UTCDateTime
    date                    currentdate;
    TimeOfDay               currenttime;
    utcDateTime             rangedate;
    //macro for define Expire date condition
    #localmacro.ExpiryDateCriteria "((ExpiryDate == \%1) || (ExpiryDate > \%2))" #endmacro
    #localmacro.ActiveDateCriteria "(ActiveDate <= \%1)" #endmacro
    
    
    ;
    
    //Working With UTCDatetime
    currentdate = today();
    currenttime = timeNow();
    rangedate = DateTimeUtil::newDateTime(currentdate,currenttime,DateTimeUtil::getUserPreferredTimeZone());

    sysTableLookup = SysTableLookup::newParameters(tableNum(VendBankAccount), _formControl);

    query = new Query();
    qbds = query.addDataSource(tableNum(VendBankAccount));
    qbds.addRange(fieldNum(VendBankAccount, VendAccount)).value(SysQuery::value(_vendAccount));
    //specify the active or inactive bank account 
    qbds.addRange(fieldNum(VendBankAccount, ActiveDate)).value(strFmt(#ExpiryDateCriteria, date2StrXpp(dateNull()) , DateTimeUtil::toStr(rangedate)));
    
    
    
    sysTableLookup.addLookupfield(fieldNum(VendBankAccount, AccountId));
    sysTableLookup.addLookupfield(fieldNum(VendBankAccount, Name));
    sysTableLookup.addLookupfield(fieldNum(VendBankAccount, AccountNum));
    sysTableLookup.addLookupfield(fieldNum(VendBankAccount, ContactPerson));
    sysTableLookup.addLookupfield(fieldNum(VendBankAccount, VendAccount));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}

  


  

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();
}


Cloud hosted environment di D365

Biasanya kita menginginkan sebuah environment yang sama dengan LIVE/PROD untuk mengtest sebuah proses. Maka kita bisa menggunakan fitur Clou...