Thursday 26 June 2014

Cannot insert multiple records in Security user role (SecurityUserRole). The record already exists in ax 2012

Delete the records from this table "SecurityUserRole" in the database user this Query:-
DELETE FROM table_name WHERE some_column = some_value

Types of Dimensions:
The inventory dimensions can be assigned to inventory dimension groups:
Product dimension group:
1.Configuration
2.Color
3.Size
Storage dimension group:
1.Site
2.Warehouse
3.Location
4.Pallet ID
Tracking dimension group:
1.Batch number
2.Serial number
Storage dimension groups and tracking dimension groups are set up in a similar manner.
However, product dimension groups are configured and used differently.

Run base batch in ax 2009

class ListBatch extends RunBaseBatch
{
    transdate  fromdate,Todate;
}

public container pack()
{
   return conNull();
}
public boolean unpack(container packedClass)
{
   return true;
}

server static ListBatch construct()
{
    return new ListBatch();
}

static ClassDescription description()
{
    return "Inquiry Batch";
}

public static void main(Args _args)
{
    ListBatch    listBatch;
    ;
    listBatch=  ListBatch::construct();

    if (listBatch.prompt())
        listBatch.run();
}
public void run()
{
    int                         i,j;
    TMLCartonInfo   TMLCartonInfo,TMLCartonInfolocal1,TMLCartonInfosmall;
    transdate              Datevalue;
    utcdatetime           formdate1 ,Todate1;
    int                         counter;
    date                      dateInUserTimeZone;
    TMLCartonInfo   TMLCartonInfolocal;
    timeOfDay            time1,time2;
    utcdatetime           fromshiftdate1,toshiftdate1;
    ;

    select firstonly TMLCartonInfolocal1 order by PackDateTime asc;
    fromdate      = DateTimeUtil::date(applyUserTimeZone(TMLCartonInfolocal1.PackDateTime));
    select firstonly TMLCartonInfosmall order by PackDateTime desc;
    Todate        = DateTimeUtil::date(applyUserTimeZone(TMLCartonInfosmall.PackDateTime));

    time1         = str2time( "00:00:00" );
    time2         = str2time( "23:59:59" );
    formdate1 = DateTimeUtil ::newDateTime( fromdate, time1);
    Todate1   = DateTimeUtil ::newDateTime( Todate, time2);

    fromshiftdate1 = DateTimeUtil::addDays(DateTimeUtil::newDateTime(fromdate, time1),-1);
    toshiftdate1   = DateTimeUtil::addDays(DateTimeUtil::newDateTime(Todate, time2),1);

        while SELECT * FROM TMLCartonInfo index hint SerialIdX order by PackDateTime asc where TMLCartonInfo.PackDateTime >= fromshiftdate1
                                                                      &&  TMLCartonInfo.PackDateTime <= toshiftdate1
                                                                      &&  TMLCartonInfo.PackDate == Datevalue
        {
            if(applyUserTimeZone( TMLCartonInfo.PackDateTime) >= formdate1 && applyUserTimeZone(TMLCartonInfo.PackDateTime)<= Todate1 )
            {
                dateInUserTimeZone = DateTimeUtil::date(applyUserTimeZone( TMLCartonInfo.PackDateTime));


                if(!TMLCartonInfo.PackDate)
                {
                    counter++;
                    //info(strFmt('%1-%2',dateInUserTimeZone,TMLCartonInfo.RecId));
                    ttsBegin;
                    select forupdate TMLCartonInfolocal index hint SerialIdX  where TMLCartonInfolocal.RecId == TMLCartonInfo.RecId;
                    TMLCartonInfolocal.PackDate = dateInUserTimeZone;
                    TMLCartonInfolocal.doUpdate();
                    ttsCommit;
                }
                else
                {
                    break;
                }
            }
        }
        info(strFmt('%1',counter));
}
public boolean runsImpersonated()
{
    // false means that the batch must run on a client.
    return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class EmailsendWithAttachmentBatch extends RunBaseBatch
{
 
    TransDate                       date1;
}
public container pack()
{
   return conNull();
}

public void run()
{
    str                         messageBody;
    InteropPermission           permission = new InteropPermission(InteropKind::ComInterop);
    SysMailer                   mailer;
    str                         Body;
    str                         ToAddress;
    str                         FromAddress = "aslam.p@infotech.net";
    str                         Subject = "Alerts";
    str                         pdfFileName;
    ;

    pdfFileName = strfmt('C:\\Users\\adminsystem\\Desktop\\A.txt'); //Create file in server system or share folder
    messageBody = "Test";
    toaddress   =  "aslam.p@infotech.net";
    Body = strfmt("%1", messageBody) ;
    CodeAccessPermission::revertAssert();
    permission.assert();
    mailer = new SysMailer();
    mailer.quickSend(fromaddress,toaddress,subject,Body,"",pdfFileName);
}

public boolean unpack(container packedClass)
{
   return true;
}

server static EmailsendWithAttachmentBatch construct()
{
    return new  EmailsendWithAttachmentBatch();
}

// Here goes a description of the class
static ClassDescription description()
{
    return "@SYS70984";
}

static void main(Args args)
{
    EmailsendWithAttachmentBatch emailsendWithAttachment;
;
    emailsendWithAttachment= EmailsendWithAttachmentBatch::construct();

    if (emailsendWithAttachment.prompt())
        emailsendWithAttachment.run();
}

https://community.dynamics.com/ax/f/33/t/78511.aspx

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static void scheduleBatch()
{
    BatchHeader           batchHeader;
    BatchInfo             localBatchInfo;
    YourRunBaseBatchClass yourRunBaseBatchClass;
    SysRecurrenceData     sysRecurrenceData =
             SysRecurrence::defaultRecurrence();
    ;

    yourRunBaseBatchClass =
        YourRunBaseBatchClass::construct();

    // retry 3 times
    sysRecurrenceData =
        SysRecurrence::setRecurrenceEndAfter(
                        sysRecurrenceData, 3);
    // retry after 1 minute
    sysRecurrenceData =
        SysRecurrence::setRecurrenceUnit(sysRecurrenceData,
                             SysRecurrenceUnit::Minute, 1);
 
    localBatchInfo = yourRunBaseBatchClass.batchinfo();
    localBatchInfo.parmGroupId("YourBatchGroupId");
    batchHeader = batchHeader::construct();
    batchHeader.addTask(yourRunBaseBatchClass);
    batchHeader.parmRecurrenceData(sysRecurrenceData);
    batchHeader.save();
}

.........................................................................................................................................
static void SR_SetupServerBatchJobs(Args _args)
{
BatchHeader header;
SysRecurrenceData sysRecurrenceData;
Batch batch;
BatchJob batchJob;
Tutorial_RunBaseBatch tutorial_rbb;
BatchInfo processBatchInfo;
BatchRetries noOfRetriesOnFailure = 4;
;

// Create the tutorial_RunBaseBatch job, only if one does not exist
select batch where batch.ClassNumber == classnum(Tutorial_RunBaseBatch);
if(!batch)
{
// Setup the tutorial_RunBaseBatch Job
header = BatchHeader::construct();
tutorial_rbb = Tutorial_RunbaseBatch::construct();
processBatchInfo = tutorial_rbb.batchInfo();
processBatchInfo.parmRetriesOnFailure(noOfRetriesOnFailure);
header.addTask(tutorial_rbb);

// Set the recurrence data
sysRecurrenceData = SysRecurrence::defaultRecurrence();
SysRecurrence::setRecurrenceStartDateTime(sysRecurrenceData, DateTimeUtil::addSeconds(DateTimeUtil::utcNow(), 20));
SysRecurrence::setRecurrenceNoEnd(sysRecurrenceData);
SysRecurrence::setRecurrenceUnit(sysRecurrenceData, SysRecurrenceUnit::Minute);
header.parmRecurrenceData(sysRecurrenceData);
// Set the batch alert configurations
header.parmAlerts(NoYes::No, NoYes::Yes, NoYes::No, NoYes::Yes, NoYes::Yes);
header.save();

// Update the frequency to run the job to every two minutes
ttsbegin;
select forupdate batchJob
join batch
where batchJob.RecId == batch.BatchJobId
&& batch.ClassNumber == classnum(Tutorial_RunBaseBatch);

sysRecurrenceData = batchJob.RecurrenceData;
sysRecurrenceData = conpoke(sysRecurrenceData, 8, [2]);
batchJob.RecurrenceData = sysRecurrenceData;
batchJob.update();
ttscommit;
}

}

.........................................................................................................................................
class Test_runbase extends RunBaseBatch
{
     #define.CurrentVersion(1)
    #define.Version1(1)
    #localmacro.CurrentList

    #endmacro
}

public boolean canGoBatchJournal()
{
    return true;
}

public container pack()
{
    return conNull();
}

public boolean unpack(container packedClass)
{
 
    return true;
}

static ClassDescription description()
{
    return "Test posting";
}

public static void main(Args _args)
{
    Test_runbase    test_runbase= new Test_runbase();
    ;
    if(test_runbase.prompt())
        test_runbase.run();

}

public void run()
{
    LedgerJournalTable      jourTable;
    LedgerJournalTrans      jourTrans;
    LedgerJournalTableData  jourTableData;
    LedgerJournalTransData  jourTransData;
    LedgerJournalStatic     jourStatic;
    DimensionDynamicAccount ledgerDim;
    DimensionDynamicAccount offsetLedgerDim;
    LedgerjournalCheckPost  LedgerjournalCheckPost;
    CustReceipts            custreceipts;
    ;

    //info("Batch starting");
    while select forupdate custreceipts
      where custreceipts.Posted == NoYes::No
    {
        ttsBegin;
        ledgerDim = DimensionStorage::getDynamicAccount(custreceipts.CustId,LedgerJournalACType::Cust);
        offsetLedgerDim = DimensionStorage::getDynamicAccount("USA OPER",LedgerJournalACType::Bank);
        jourTableData = JournalTableData::newTable(jourTable);
        jourTable.JournalNum = jourTableData.nextJournalId();
        jourTable.JournalType = LedgerJournalType::Payment;
        jourTable.JournalName = 'ARPay';
        jourTableData.initFromJournalName(LedgerJournalName::find(jourTable.JournalName));
        jourStatic = jourTableData.journalStatic();
        jourTransData = jourStatic.newJournalTransData(jourTrans,jourTableData);
        jourTransData.initFromJournalTable();
        jourTrans.CurrencyCode = 'USD';
        jourTrans.initValue();
        jourTrans.TransDate = systemDateGet();
        jourTrans.AccountType = LedgerJournalACType::Cust;
        jourTrans.LedgerDimension = ledgerDim;
        //jourTrans.Txt = TransTxt.valueStr();
        jourTrans.OffsetAccountType = LedgerJournalACType::Bank;
        jourTrans.OffsetLedgerDimension = offsetLedgerDim;
        jourTrans.AmountCurCredit = any2real(custreceipts.Amount);
        jourTransData.create();
        jourTable.insert();
        ttsCommit;


        LedgerjournalCheckPost      =   LedgerjournalCheckPost::newLedgerJournalTable(jourTable,NoYes::Yes);
        LedgerjournalCheckPost.run();
        info(strFmt("Journal '%1' has been created", jourTable.JournalNum));

         ttsBegin;
        custreceipts.Posted = NoYes::Yes;
        custreceipts.doUpdate();
        ttsCommit;
        Info("posted");

    }
}
public boolean runsImpersonated()
{
    // false means that the batch must run on a client.
    return true;
}
.............................................................................................................................
Class Runbasebatch extends RunBaseBatch
{
    RunBase_UpdateTable             rBUpdateTable;
    TransDate                       date1;
}

public container pack()
{
   return conNull();
}

public void run()
{
    //super();
 date   dateInUserTimeZone;
    ;
    ttsBegin;


    while select forupdate rBUpdateTable
    {
        dateInUserTimeZone = DateTimeUtil::date(applyUserTimeZone(rBUpdateTable.ValidDateTime));
        rBUpdateTable.NewDate = dateInUserTimeZone; //DateTimeUtil::date(applyUserTimeZone(rBUpdateTable.ValidDateTime));
        rBUpdateTable.update();
    }

    ttsCommit;


}

public boolean runsImpersonated()
{
    // false means that the batch must run on a client.
    return true;
}

public boolean unpack(container packedClass)
{
   return true;
}

server static Runbasebatch construct()
{
    return new Runbasebatch();
}

static void main(Args args)
{
    Runbasebatch    runbasebatch;
;
    runbasebatch=  Runbasebatch::construct();

    if (runbasebatch.prompt())
        runbasebatch.run();
}

Wednesday 25 June 2014

TimeConsumed() function in ax 2012

timeConsumed()–a very useful function in Global class in AX 2012 [x++]

There is a very useful function timeConsumed() in Global class which we can use to calculate the time taken to execute business logic in AX 2012.

This function will return time consumed string in the form of X hours X minutes X seconds. If X is 0 – will not include the value + text.
It handles up to a 24 hour time difference not dependent on start/end time. If time consumed > 24 hours will only report time over 24 hour intervals.

Below is the example:

static void SGX_timeConsumed(Args _args)
{
    FromTime startTime = timeNow();
    int i;
    str dummyStr;
    ;
 
    for (i = 1 ; i <= 500000; i++)
    {
        dummyStr += int2str(i);    
    }
     
    info(strFmt("Total time consumed is  %1", timeConsumed(startTime, timeNow())));
}


static void Milliseconds(Args _args)
{
    TimeInMS        startTime,endTime;
    int i;
    str dummyStr;
    ;
    startTime = WinAPI::getTickCount();

    for (i = 1 ; i <= 500000; i++)
    {
    dummyStr += int2str(i);
    }
    endTime = WinAPI::getTickCount();
    info(strfmt("%1 Milliseconds",endTime-startTime));
}

Tuesday 17 June 2014

Date range filter in the grid in ax 2012

follow the below process,

Step-1:
Go to classdeclaration and declare a queryBuildRange object

public class FormRun extends ObjectRun
{
    QueryBuildRange qbr1,qbr2;
}

Step-2:

Override the init() method od DATASOURCE - Please note after super() ur range should be defined as your datasource will get initialized after super()

public void init()

{

    super();

    qbr1 = this.query().dataSourceNo(1).addRange(fieldnum(tablename, fieldname1));

    qbr2 = this.query().dataSourceNo(1).addRange(fieldnum(tablename, fieldname2));

}

Step-3:

Override the executeQuery() method on datasource - should be before super()

public void executeQuery()

{

    ;

qbr1.value(queryValue(ConfirmedDate.dateValue())); // set control autodeclaration to yes and use control name.datevalue() here

 qbr2.value(queryValue(RequestedDate.dateValue()));  // set control autodeclaration to yes and use control name.datevalue() here

 super(); // will retrive all the records from the table and shows it on the grid

}

Step-4:

Finally on the control event

Go to date controls >> OverRide the modified method and add the following code after super()

public boolean modified()

{

    boolean ret;

    ret = super();

    datasourcename_ds.executeQuery();

    return ret;

}

Get different number seq base on asset group in ax 2012 R2

Get different number seq base on asset group :-

NumberSeq                   assetIdNumberSeq;
NumberSequenceTable         numberSequenceTable;
NumberSequenceReference     numberSequenceReference
;
 if (assetIdNumberSeq)
        assetIdNumberSeq.abort();
assetIdNumberSeq = assetTable.initAssetNumberSeq(FleetAsset::find(FleetTable.FleetGroup).AssetGroup);
if (assetIdNumberSeq)
{
    info(strfmt('%1',assetIdNumberSeq.num());
}

public server NumberSeq initAssetNumberSeq(AssetGroupId _assetGroupId = '')
{
    AssetParameters assetParameters = AssetParameters::find();
    AssetGroup      assetGroup = AssetGroup::find(_assetGroupId ? _assetGroupId : this.AssetGroup);
    NumberSeq       assetNumberSeq;
    ;

    if (assetGroup.AutoNumber && assetGroup.AutoNumberSequenceTable)
    {
        assetNumberSeq = NumberSeq::newGetNumFromId(assetGroup.AutoNumberSequenceTable, true);
    }

    if (!assetNumberSeq && assetParameters.AutoNumber)
    {
        assetNumberSeq = NumberSeq::newGetNum(AssetParameters::numRefAssetId(),true);
    }

    return assetNumberSeq;
}

http://allaboutax.blogspot.in/2012/03/multiple-auto-manual-number-sequences.html

http://allaboutax.blogspot.in/2012/03/add-new-number-sequence-to-existing-ax.html

Sunday 15 June 2014

Error in SSRS in ax 2012 :For more information about this error navigate to the report server on the local server machine, or enable remote errors

Please restart the "Ax services" and "SSRS reporting" services it can be resolve your problem 

How to avoid Startup "The model store has been modified" in ax 2012

Hello, had this behaviour recently after upgrading model files. In my case the field MinorUpgrade in table ReleaseUpdateConfiguration was set to 1, so the checklist always opened.

I fixed this using a job containing this line:

SysCheckList_Update::finalizeMinorUpgrade();

Hint: AX uses info.startup() to check, if checklist must be opened.

AX 2012 R2 Delete All ax transactions

Hi,
     How to delete all transactions from AX 2012. Previously we were using SysDatabaseTransDelete class to do the same but as of now we need to modify that class to work properly with AX 2012 due to DB changes :

We need to modify the SysDatabaseTransDelete.handletable method with the below code :

void handleTable(SysDictTable sysDictTable)

{

    TableGroup      tableGroup;

  if (tableSet.in(sysDictTable.id()))

        return;

    tableSet.add(sysDictTable.id());



    if (sysDictTable && !sysDictTable.isTmp() && !sysDictTable.isMap())

    {

        tableGroup = sysDictTable.tableGroup();



        // Handle company specific tables to be deleted

        if (sysDictTable.dataPrCompany())

        {

            switch(tableGroup)

            {

                case TableGroup::Transaction:

                case TableGroup::WorksheetHeader:

                case TableGroup::WorksheetLine:

                //FIX - Support new AX2012 transaction table types

                case TableGroup::TransactionHeader:

                case TableGroup::TransactionLine:

                    this.handleTransTable(sysDictTable);

                    break;

                default:

                    this.handleNonTransTable(sysDictTable);

                    break;

            }

        }

        else

        {

            // Handle global tables to be deleted

            switch(tableGroup)

            {

                case TableGroup::Transaction:

                case TableGroup::WorksheetHeader:

                case TableGroup::WorksheetLine:

                //FIX - Support new AX2012 transaction table types

                case TableGroup::TransactionHeader:

                case TableGroup::TransactionLine:

                    this.handleGlobalTransTable(sysDictTable);

                    break;

                default:

                    break;

            }

        }

    }

}

Thursday 12 June 2014

Fix some errors from: CIL generation, Database Synchronize in AX 2012

1.) "A parameter could not be serialized":

For a quick resolve: uncheck option "Excute business operations in CIL"  under Tools-> Options -> Development tab.












The reason is that you haven't been able to do a successful FULL CIL compile.
Run again and try to fix the error in CIL.

2.)"CIL generation: source array was not long enough...":

1. Stop the AOS.
2. Delete all of the source in the C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\XppIL directory.
3. Start the AOS.
4. Perform a full CIL generation.
5.(Only do if errors are still there and you have no error when compile X++, just comment the code notice in Compiler output with /*..*/, recompile CIL and delete comment tag)

3.) "CIL generation error : The given key was not present in the dictionary":

1. Check the CIL log file, generally located at "C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\XppIL\Dynamics.Ax.Application.dll.log"
2. You will find the AOT object for which the CIL generator found the error.
3. Compile that object, fix the error, or delete (if needed) and then regenerate the IL.
4. (Only do if errors are still there : Stop AOS > Delete the .auc file from users\\Appdata  folder > Restart AOS)

4.) DB synchronize error: "Field mismatch in union query. Field ... is not compatible with field ..."

Check your EDT concern to that field ( in query, table, view). They have different size.
So you just change the size to be the same.
Or check someone changed size of standard EDT. It's the reason cause this error

5.) "Duplicate type with name 'Dynamics.Ax.application.' in assembly 'Dynamics.Ax.application "

1. Stop the ax service.

2. Truncate the SysXPPAssembly in db model
3. Delete all the files in below directory in server where AOS hosted:

C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\XppIL

4. Start the service

5. Compile full CIL