Thursday 28 November 2013

AX2012 R2 : Adding new fields on list page grid using new data source

Hi Friends,
Recently I was adding new fields on a positions list page grid in payroll module and these fields were coming from a new custom table. The steps are simple with one tricky part:

1. Create new table, define proper relations with other tables.




2. Add the table in the query used on the list page.


3. This is a tricky part: When you come back to list page and try to restore the form you will not be able to see the new data source. To do this right click on the data source node and again define the name of the query. This will reload the new structure from the query.



4. Then you can view the data source which you added in the query and then can drag the fields in the grid.



Thanks for reading the blog.



Wednesday 27 November 2013

AX2012 R2: Adding generic custom validations when posting sales orders

Hi Friends,
It is good to keep this information handy so I posted on the blog.
If we need to add our own custom validation for salesTable/Customer record when performing posting on sales orders, then the best place to write the logic is \Classes\SalesFormletterProvider\checkHeading().
This function is called to check some generic rules  for salesTable or Customer during any type of posting (Confirmation/Picking/Packing/Invoicing) process of sales order.

See below the way  standard AX does it.



You can create a method on salesTable which returns a boolean value and call it along with other standard AX validations.
You can check the posting type by using the function this.parmDocumentStatus() so that if you want to run  validation only for specific posting type you can run it.
Note this approach should only be taken when you have to add some generic validations applicable on all types of posting.

Thanks for reading the blog.




Friday 22 November 2013

AX2012 R2 : X++ Code to create picking list journal for a production order

Hi Friends,
Below is the sample of X++ code which can be used to create a picking list journal for a production order.
The journal header table is ProdJournalTable and the lines are stored in ProdJournalBOM table.
The table are related on the basis of Journal Type and Journal ID. The relation is defined on ProdJournalBOM table as shown below:


If you take a closer look, the 0 element in Base Enum of journal type field is "Picking list"




So the header table for all the journal types of production orders is ProdJournalTable. The lines table differ and can be easily traced from the forms and relations.

For illustration purpose I have hard coded some values but in real time u can get these form your functions/parameters/maps/list etc. Also I have created only one line, in real time scenarios you can have a list/function/while loop to create the lines for multiple items.



















The difference see from AX2009 is the way we initialize voucherSeqRecId field of the journal header as it now stores the RecId of the voucher number sequenceID.

There are more fields in the prodJournalBOM table but with the minimum fields I included in the job, journal can be created and posted. In case you have record of ProdBOM table available for which you want to create the journal line then the task becomes more easy as you can call initFromProdBOM() function of the prodJournalBOM table as it can initialize the following fields and we can eliminate these lines from our job:





If you want to quickly reuse the code, here it is:

static void samplePickingListJournal(Args _args)
{
    ProdJournalTable    prodJournalTable;
    ProdJournalBOM      prodJournalBOM;
    ProdTable           prodTable = prodTable::find("PO-001159");

    prodJournalTable.clear();
    prodJournalTable.initValue();
    prodJournalTable.JournalType    = ProdJournalType::Picklist;
    prodJournalTable.JournalNameId  = 'pickJrnl';
    prodJournalTable.Description    = " Prod pick list journal";
    prodJournalTable.ProdId         = prodTable.ProdId;
    prodJournalTable.VoucherDraw    = JournalVoucherDraw::Post;
    prodJournalTable.VoucherSeqRecId = NumberSequenceTable::find(ProdParameters::numRefProdJournalVoucherId().NumberSequenceId).RecId;
    prodJournalTable.insert();

    prodJournalBOM.clear();
    prodJournalBOM.initValue();
    prodJournalBOM.JournalId        = prodJournalTable.JournalId;
    prodJournalBOM.initFromInventTable(InventTable::find("MAT001"));
    prodJournalBom.ProdId           = prodTable.ProdId;
    prodJournalBom.LineNum          = 1;
    prodJournalBom.InventDimId      = "DIMID-99876";
    prodJournalBom.TransDate        = systemDateGet();
    prodJournalBom.BOMUnitId        = "Pcs";
    prodJournalBom.BOMConsump       = 10;
    prodJournalBom.InventConsump    = 10;
    prodJournalBom.insert();
    ttsBegin;
    prodJournalTable.selectForUpdate(true);
    prodJournalTable.NumOfLines = 1;
    prodJournalTable.update();
    ttsCommit;
    info(strFmt("Journal %1 created",prodJournalTable.JournalId));
}

Thanks for reading the blog.