Indicating mandatory field in a dialog (RunBase) class.

A classical problem is indicating that a field is mandatory in a dialog, when the field is not bound to a datasource/field in a datasource.

We can do this by code, but you must forcing the method !

    DialogRunbase       dialog = super();
    ;

    dialog.addGroup("@SYS22142");
    dFromDate       = dialog.addFieldValue(typeId(FromDate), fromDate);
    dToDate         = dialog.addFieldValue(typeId(ToDate), toDate);

    dFromDate.fieldControl().mandatory(true);
    dToDate.fieldControl().mandatory(true);

    return dialog;

File listing – List all file in a folder

There is code for make a listing of all file in a folder :

static void myFileList(Args _args)
{
    FilePath                sFilePath;

    System.IO.DirectoryInfo di;
    System.IO.FileInfo[]    fis;
    System.IO.FileInfo      fi;
    int                     i;
    int                     l;
    ;

    sFilePath   = WinAPI::getTempPath();
    di          = new System.IO.DirectoryInfo(sFilePath);
    fis         = di.GetFiles();
    l           = fis.get_Length();
    
    for (i = 0; i < l; i++)
    {
        fi = fis.GetValue(i);
        info(fi.get_FullName());
    }
}

Lettrer une facture

Applicable pour la version 2009

Première manière

Voici comment lettrer une facture (client ou fournisseur).

Nous avons besoin du record dans LedgerJournalTrans et CustTransOpen ou VendTransOpen ou encore, comme l’exemple ci-dessous, la Map CustVendTransOpen. Ce qui est une meilleur solution.

Ici j’ai également rajouté un boolean pour voir si l’on devait lettrer ou pas.

protected void settle()
{
    SpecTrans           specTrans;
    ;

    if (!settle)
    {
        return;
    }

    if (!this.custVendTransOpen())
    {
        return; 
    }

    settle                  = false;

    //init table id and recid
    specTrans.SpecTableId   =  ledgerJournalTrans.TableId;
    specTrans.SpecRecId     =  ledgerJournalTrans.RecId;
    specTrans.SpecCompany   =  ledgerJournalTrans.dataAreaId;

    //init table id and recid
    specTrans.RefTableId    =  this.custVendTransOpen().TableId;
    specTrans.RefRecId      =  this.custVendTransOpen().RecId;
    specTrans.RefCompany    =  this.custVendTransOpen().dataAreaId;

    //init currency and amount
    specTrans.Code          =  ledgerJournalTrans.CurrencyCode;
    specTrans.Balance01     =  ledgerJournalTrans.AmountCurCredit
                            ?  ledgerJournalTrans.AmountCurCredit
                            : (ledgerJournalTrans.AmountCurDebit) * -1;

    //add line
    specTrans.insert();
}

Seconde manière

Achat
static void settleVend(Args _args)
{
    VendTrans      vendTrans1, vendTrans2;
    VendTable      vendTable;
    ;

    while select vendTrans1
    where vendTrans1.PaymReference != ""
    {
            select firstOnly vendTrans2
            where vendTrans2.PaymReference == vendTrans1.PaymReference
            &&    vendTrans2.AmountCur == vendTrans1.AmountCur * -1;
            if(vendTrans2 && (vendTrans1.AmountCur + vendTrans2.AmountCur == 0))
            {
                vendTable = VendTable::find(vendTrans1.AccountNum);
                vendTrans1.transData().markForSettlement(vendTable);
                vendTrans2.transData().markForSettlement(vendTable);
                vendTrans::settleTransact(vendTable);
            }
 
    }
}
Vente
static void settleCust(Args _args)
{
    CustTrans      custTrans1, custTrans2;
    CustTable      custTable;
    ;

    while select custTrans1
    where custTrans1.PaymReference != ""
    {
       if(custTrans1.isPayment())
       {
            select firstOnly custTrans2
            where custTrans2.PaymReference == custTrans1.PaymReference
            &&    custTrans2.AmountCur == CustTrans1.AmountCur * -1;
            if(custTrans2 && (custTrans1.AmountCur + custTrans2.AmountCur == 0))
            {
                custTable = CustTable::find(CustTrans1.AccountNum);
                custTrans1.transData().markForSettlement(custTable);
                custTrans2.transData().markForSettlement(custTable);
                CustTrans::settleTransact(custTable);
            }
        }
    }
}

Applicable pour la version 3 et 4

Pour la version 3 et 4 d’Ax. C’est le même code SAUF qu’il n’y a pas de champ specTrans.RefCompany et specTrans.SpecCompany utilisé pour l’intersociété.

Overlap between the record

Voici la méthode pour contrôle s’il y a un overlap de date entre deux enregistrements.

Dans la méthode validateWrite():

    if (this.mCheckOverlapDate())
    {
        ret = checkFailed("@SYS39599");
    }

Maintenant dans la méthode mCheckOverlapDate:

// Control the overlapping with the FromDate and ToDate with other record in this table.
public boolean mCheckOverlapDate(boolean _checkOtherRecordOverlap = true)
{
    Table       mTable;

    boolean     ret;
    boolean     fromDateOverlapped;
    boolean     toDateOverlapped;
    boolean     ourRangeOverlapped;
    ;

    //  We loop over the record for the same paym term condition
    while select mFromDate, mToDate from mTable
    where mTable.RecId != this.RecId
    {
        //  First we control if there are no overlapping for the MyFromDate field
        if (this.MyFromDate >= mPaymTerm.MyFromDate && this.MyFromDate <= mPaymTerm.MyToDate)
        {
            fromDateOverlapped = true;
            break;
        }

        //  Second time, we control if there are no overlapping for the MyToDate field
        if (this.MyToDate >= mPaymTerm.MyFromDate && this.MyToDate <= mPaymTerm.MyToDate)
        {
            toDateOverlapped = true;
            break;
        }
    }

    if (fromDateOverlapped || toDateOverlapped)
    {
        ret = true;
    }

    if (_checkOtherRecordOverlap)
    {
        //  Now we will control if each other record are not in our range !
        while select mTable
        where mTable.RecId != this.RecId
        {
            if (mPaymTerm.mCheckOverlapDate(false))
            {
                ourRangeOverlapped = true;
            }
        }

        if (ourRangeOverlapped)
        {
            ret = true;
        }
    }

    return ret;
}

New number sequence

We need to go to the class NumberSequence which manage the automatique numbering for group. We will make as example a new number sequence for the group CRM for the EDT CRMId.

Don’t forget to create the new EDT. For the sortField, always begin at 100.

Go to the class NumberSeqReference_CRM. In the method loadModule, we will put the following code:

protected void loadModule() 
{
   numRef.DataTypeId              = typeId2ExtendedTypeId(typeId(CRMId));
   numRef.ConfigurationKeyId      = configurationKeyNum(smmCRM);
   numRef.ReferenceHelp           = literalStr("@SYS81568"); 
   numRef.WizardContinuous        = true;
   numRef.WizardManual            = NoYes::No;
   numRef.WizardAllowChangeDown   = NoYes::No;
   numRef.WizardAllowChangeUp     = NoYes::No;
   numRef.SortField               = 100;
   numRef.WizardHighest           = 999999;
   this.create(numRef);
}

After that, the table smmParametersTable (setup table for the CRM), we will create the new method like this:

public client server static NumberSequenceReference numRefCRMId() 
{
   return NumberSeqReference::findReference(typeId2ExtendedTypeId(typeId(CRMId)));
}

We need to quit and restart the client for enable the new changement.
Once AX restarted, go to the module CRM > Configuration > Setup and go to the last tab. There are all number sequence for each EDT, go to the line for our CRMId field and make ‘Go to main table’. We will create a new number sequence called CRMIdSouche and as code we will write CRM######.
We come back to the other table and fill-in with our new number sequence id.

After that, we must specify to the table to increase the EDT. And put the following code in the method create or initValue:

public void initValue() 
{
   NumberSeq   numberSeq;
   ;
   numberSeq = NumberSeq::newGetNum(CRMParameters::numRefCRMId());
   if (numberSeq)
   {
       this.CRMId        = numberSeq.num();
   }
}