miércoles, 18 de abril de 2012

BI in AX with TMP


Working with Business Intelligence / Analysis Services I've come to realise how much we rely on temporary tables to do our work within Ax.  When only working at the database level we can't call Ax classes to generate our data.  My most recent issue was developing reports for budgeting purposes within the accounting module, when looking up budgetary balances within a financial period for example.  The LedgerPeriodTimeDimensions entity comes to our aid by generating a complete breakdown of those financial periods but this is a snap-shot of time and will not be updated as new periods are added.  As Sebastian Ohlsson points out:

...the recommendation from Microsoft is to make a backup of your database...
You have a table in Ax called LedgerPeriodTimeDimensions, it reflects Ax' ledger periods. This table needs to be updated as soon as you have modified the ledger periods. You update this table by going to Administration » Setup » Business analysis » OLAP Administration. Mark the OLAP server that should be updated.
Go to the Advanced tab and mark Update BI data  and click the Update databases button. After you have updated this table you need to process your cubes.

I had been relying on this entity for my work but didn't realise this dependency until I read the LedgerPeriodTimeDimensions table description within MSDN.  Why was this entity not prepended with the 'BI' or the 'SRS' label?

Edit: Execute the following in a job to just update those Enum changes in the SRSANALYSISENUMS table.
BIGenerator::PopulateSRSAnalysisEnums();

lunes, 9 de abril de 2012

Adding a secondary Cust/Vend address via X++

We're integrating with an external system once more.  This time we need to add an invoice address to the clients we are importing.  We already have a primary mail address, but on some occasions the invoices are directed to a department full of some patient ladies with very thick skin.
 
I find the way Ax 2009 deals with the global address book quite complicated but help is on hand in the form of a white paper (AX 2012 version).  However, I started by looking at the CustTable.deliveryAddress() and the Address.insert(..., ...) methods.

Below is an example of adding and editing the secondary invoice address:

static void Job1(Args _args)
{
    CustTable       custTable;
    DirPartyTable   dirPartyTable;
    Address         invoiceAddress;
    ;
    
    custTable       = CustTable::find("1");
    dirPartyTable   = DirPartyTable::find( custTable.PartyId );
    
    // Find private address for invoicing
    invoiceAddress = Address::find(dirPartyTable.TableId, dirPartyTable.RecId, AddressType::Invoice, true);
    if (!invoiceAddress)
    {
        invoiceAddress.AddrRecId    = dirPartyTable.RecId;
        invoiceAddress.AddrTableId  = dirPartyTable.TableId;
        invoiceAddress.type         = AddressType::Invoice;
        invoiceAddress.IsPrimary    = NoYes::No;
    }

    invoiceAddress.Name             = "Invoice Addressee";
    invoiceAddress.CountryRegionId  = "ES";
    invoiceAddress.Street           = "Calle de los perdidos";
    invoiceAddress.ZipCode          = "50000";
    invoiceAddress.City             = "Zaragoza";
    invoiceAddress.County           = "ZARAGOZA";
    invoiceAddress.State            = "AR";

    invoiceAddress.AddressMap::formatAddress();
    if (invoiceAddress.RecId == 0)
    {
        invoiceAddress.insert(true, false);
    }
    else
    {
        invoiceAddress.update(true, false);
    }
}