Minggu, 01 November 2020

Custom form Listpage

Jangan kaget jika kita mendapati form Listpage yang kita kerjakan tidak mempunyai fitur Overwrite method. 
untuk mengcustom atau menambah method di form listpage kita bisa merubahnya di class yang memanage form listpage itu. seperti class controlnya.
contoh untuk mengcustom form PurchTableListPage maka maka custom classnya ada di PurchTableListPageInteraction.

mari kita sebut class ini, class interaction.

setujruh??

Membuat custom workflow dari awal

Ada beberapa referensi untuk membuat workflow untuk form yang kita buat.
Saya menggunakan referensi dari link ini :

https://www.tech.alirazazaidi.com/custom-workflow-from-scratch-dynamics-ax-2012/

Minggu, 11 Oktober 2020

Get value VendTransOpen.Duedate and update LedgerJournalLines.Due with VendTransOpen.Duedate

Classes CustVendOpenTransManager
Classes VendOpenTransform

Jadi kita akan melakukan custom pada modul AP-Journal payment. terutama pada VendTransOpen.Duedate.

Skenario :
pada saat user memilih Open Settlement (VendTransOpen form), value VendTransOpen.duedate dapat dikopi dan masukan ke table LedgerjournalTrans.Due.

Caranya adalah.
custom class CustVendOpenTransManager.updateOriginatorForMarkedTrans

LedgerJournalTrans ledgerJournalTrans;
    BankThirdPartyAccountId firstVendBank;
    SalesTable salesTable;
    PurchTable purchTable;
    NoYes autoSettlement;

    // <GIN>
    LedgerJournalType           ledgerJournalType;
    TaxWithholdAuthorities_IN   taxWithholdAuthorities;
    // </GIN>

    // <GEEU>
    CustInvoiceJour custInvoiceJour;
    CustInvoiceJour_RU custInvoiceJourRU;
    // </GEEU>

    DueDate         duedateAP;//Add husna 20201011

    if (specTransManager.getSpecTransCount() > 0)
    {
        // If transactions were marked, write data back to the originating record.
        switch(originator.TableId)
        {
            case tableNum(LedgerJournalTrans):
                ledgerJournalTrans = originator;
                duedateAP = vendOpenTransForm.getDuedatesettlement();//add husna 20201011
                ledgerJournalTrans.Due = duedateAP;//add husna 20201011

lalu
di class VendOpenTransform buat sebuah method getDuedatesettlement()
public DueDate getDuedatesettlement()
{
    DueDate             duedatesettlement;
    SpecTrans               specTrans;

    if (!diffVendBankExist)
    {
        select firstOnly RecId, RefTableId, RefCompany, RefRecId from specTrans
            where specTrans.SpecRecId == originator.RecId;

        duedatesettlement = specTrans.vendTransOpen().DueDate;
    }

    return duedatesettlement;
}

Selasa, 22 September 2020

Filter datasource in form

Sample code :

Override ExecuteQuery method in datasorce and put this query before Super()

this.query().dataSourceTable(tableNum("RsPcm_EmployeeReqPaymentTable")).addRange(fieldNum(RsPcm_EmployeeReqPaymentTable,Status)).value(SysQuery::value(RsPcm_VendorActivityPaymentStatus::Draft)); 

Senin, 21 September 2020

Cannot edit a record in User to person relationship (DirPersonUser). Update on a valid time state table is not allowed without specifying a ValidTimeStateUpdateMode.

This table need update in validTimeStateUpdateMode field.
while you update the record you need to define [table].validTimeStateUpdateMode also.

sample code :

DirPersonUser           personusertable;
    ;
    
    select forUpdate personusertable
    where personusertable.RecId == 5637174578;
    ttsBegin;
        personusertable.PersonParty = 5637286583;
        personusertable.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);
        personusertable.update();
    ttsCommit;

https://hellodax.com/2015/06/25/error-update-is-not-allowed-without-specifying-validtimestateupdatemode/

Rabu, 02 September 2020

Senin, 27 Juli 2020

How to Range or filter your Data's on your form

Example :
You have a form with datasource : Custtable.
and youwant to show only "v000001"
Override your Custtable.ExecuteQuery with your code, before Super().

CustTable_ds.query().dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable, CustId)).value(queryValue('v000001'));

see the detail in ":

Senin, 29 Juni 2020

Lookup based on Fromdate Todate

public void lookup()
{
   
    Query                       query = new Query();
    QueryBuildDataSource        queryBuildDataSource;
    QueryBuildRange             queryBuildRange;
    SysTableLookup              sysTableLookup = SysTableLookup::newParameters(tableNum(CustPaymFee), This);
    ;
    //2daydate  = today();
    sysTableLookup.addLookupField(fieldNum(CustPaymFee, FeeId));
    sysTableLookup.addLookupField(fieldNum(CustPaymFee, Description));
    sysTableLookup.addLookupField(fieldNum(CustPaymFee, LedgerJournalType));
   
    queryBuildDataSource = query.addDataSource(tableNum(CustPaymFee));
    queryBuildDataSource.addRange(fieldNum(CustPaymFee, PSMFromdate)).value("<"+SysQuery::value(today()));
    //queryBuildRange.value('<='+SysQuery::value(today())); <= its not working
    queryBuildDataSource.addRange(fieldNum(CustPaymFee, PSMtodate)).value(">"+SysQuery::value(today()));
    //queryBuildRange.value('>='+SysQuery::value(today())); >= its not working
   
    sysTableLookup.parmQuery(query);
    // Perform lookup
    sysTableLookup.performFormLookup();
   
}

Senin, 22 Juni 2020

How to get last Approval

static void dtGetLastApproverName(Args _args) 
 { 
    WorkflowTrackingStatusTable workflowTrackingStatus; 
    WorkflowTrackingTable workflowTrackingTable; 
    WorkflowTrackingCommentTable workflowTrackingCommentTable; 
    UserInfo userInfo; 

    select firstFast RecId, User from workflowTrackingTable 
     order by RecId desc 
     join workflowTrackingCommentTable 
    where workflowTrackingCommentTable.WorkflowTrackingTable == 
          workflowTrackingTable.RecId 
    join UserInfo where UserInfo.id == WorkflowTrackingTable.User 
    exists join workflowTrackingStatus 
    where workflowTrackingTable.WorkflowTrackingStatusTable == 
    workflowTrackingStatus.RecId 
    && workflowTrackingStatus.ContextRecId == _salesRecId //PurchRecID 
    && workflowTrackingStatus.ContextTableId == tableNum(SalesTable) //SalesTable 
    && workflowTrackingTable.TrackingType == WorkflowTrackingType::Approval; 

    if (workflowTrackingTable.RecId > 0) 
    { 
      info(strFmt(“%1 – %2 “,userInfo.name, workflowTrackingCommentTable.RecId)); 
    } 
 } 

You can get this code from : https://allaboutax.blogspot.com/2018/06/retrieve-last-approver-name-for-workflow.html?showComment=1592880782308#c5936258997657022271


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

  


  

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...