Thursday 18 February 2016

List of items that have been sold on a sales order id Using Code in Ax 2012

class SalesListItems
{
    QueryRun queryRun;
}

Methods
static void main(Args _args)
{
    SalesListItems salesListItems = new SalesListItems();
    salesListItems.run();

}

private void run()
{
    this.buildQuery();
    if (queryRun.prompt())
    this.listItems();
}

private void listItems()
{
    SalesLine salesLine;
    while (queryRun.next())
    {
        salesLine = queryRun.get(tableNum(SalesLine));
        info(strFmt("%1 %2",salesLine.ItemId,salesLine.itemName()));
    }
}

private void buildQuery()
{
    Query query;
    QueryBuildDataSource dataSource;
    query = new query();

    dataSource = query.addDataSource(tableNum(SalesLine));
    query.addQueryFilter(dataSource, fieldStr(SalesLine,SalesId));
    queryRun = new QueryRun(query);
}




Wednesday 17 February 2016

X++ Code for Sales order Invoiced which are Created through Sales Quotation Confirmed

static void Raj_SQTConfirmSTInvoiced(Args _args)
{
    SalesQuotationTable sqt;
    SalesQuotationLine  sql;
    SalesTable          st;
    ;
   while select QuotationId,salesidref,quotationstatus from sqt  join sql
        where sqt.QuotationId == sql.QuotationId
         && sqt.QuotationStatus == SalesQuotationStatus::Confirmed
         join st where sqt.SalesIdRef == st.SalesId
          && st.SalesStatus == SalesStatus::Invoiced
    {
        info(strFmt("%1 is quotationid confirmed,%2 is salesid invoiced",sqt.QuotationId, st.SalesId));
    }
}

Friday 12 February 2016

Dynamic Query with Prompt in Ax 2012

static void Job23(Args _args)
{
    QueryBuildDataSource queryBuildDataSource;
    QueryBuildRange queryBuildRange;
    QueryRun queryRun;
    Query    query;
    Qty total;
    InventTrans inventTrans;
    inventDim inventDim;
    query = new Query();
   
    queryBuildDataSource = query.addDataSource(tableNum(InventTrans));
    queryBuildDataSource.addSelectionField(fieldNum(InventTrans,Qty),SelectionField::Sum);
    queryBuildRange      = queryBuildDataSource.addRange(fieldNum(InventTrans,ItemId));
    queryBuildDataSource = queryBuildDataSource.addDataSource(tableNum(InventDim));
    queryBuildDataSource.addGroupByField(fieldNum(InventDim,InventBatchId));
    queryBuildDataSource.relations(true);
    queryRun = new QueryRun(query);
   
    if (queryRun.prompt())
    {
        while (queryRun.next())
        {
            inventTrans = queryRun.get(tableNum(InventTrans));
            inventDim   = queryRun.get(tableNum(inventDim));
            info(strFmt("Batch %1, qty %2",inventDim.inventBatchId, inventTrans.qty));
        }
    }
}

Monday 8 February 2016

How to Calculate total sales order or sales quotation amount / discounts / tax etc., through code in Ax 2012

static void Raj_TotalSalesCalculate(Args _args)
{
    SalesTotals   salesTotals;

    SalesTable   salesTable;
    container   displayFields;
    str    totalTax, amountWithoutTax, amountInclTax,exchrate;

    salesTable = salesTable::find('001271');
    salesTotals  =  SalesTotals::construct(salesTable, salesUpdate::All);
    salesTotals.calc();
    displayFields =  salesTotals.displayFieldsCurrency(salesTotals.currencyCode());

    exchrate         = conPeek(displayFields,TradeTotals::posExchRate());
    amountWithoutTax  = conpeek(displayFields, TradeTotals::posBalance());
    amountInclTax   = conpeek(displayFields, TradeTotals::posTotalAmount());
    totalTax    = conpeek(displayFields,TradeTotals::posTaxTotal());
 
    info(strFmt("%1--%2--%3",amountWithoutTax,amountInclTax,totalTax));

}

Withholding tax for purchase order

display real withholdTax()
{
    PurchTable      purchTable;
    PurchTotals     _purchTotals;
   
   
    purchTable  = PurchTable::findRecId(callingTable.RecId);
    _purchTotals = PurchTotals::newPurchTable(purchTable);
    _purchTotals.calc();
    return  _purchTotals.taxWithhold_IN().taxAmountCurTotal();
 

}

ODBC Connection using Inbound and outbound in Ax 2012

First we have to Establish ODBC Connection

  • Open Search > Administrative Tools in Ur PC
  • Select ODBC 64 or ODBC 32
  • A Prompt Will Appear as

  • Click on Add



  • Create New Data Base 
  • Check Newly Created  Data Base are added to ODBC or not

                              Inbound
static void ODBCCONNECTION_Inbound(Args _args)
{
    LoginProperty                       loginproperty;
    OdbcConnection                      odbcconnection;
    Statement                           statement;
    ResultSet                           resultset;
    str                                 sql,criteria;
    SqlStatementExecutePermission       perm;
    Custtable                           custtable;
    ODBCTABLE                           odbctable;

    ;
    loginproperty = new loginproperty();
    loginproperty.setDSN("ODBCconnection");
    loginproperty.setDatabase("DataBaseName");

    odbcconnection = new odbcconnection(loginproperty);

    if(odbcconnection)
    {
        sql = "select * from [DataBaseName].[dbo].[ODBCCUSTTABLE]";// where custgroup<=20";
        perm= new SqlStatementExecutePermission(sql);
        perm.assert();

        statement = odbcconnection.createStatement();
        resultset = statement.executeQuery(sql);

        while(resultset.next())
        {
            odbctable.AccountNum= resultset.getstring(1);
            odbctable.CustGroup= resultset.getString(2);
            odbctable.Amount   = resultset.getstring(3);
            odbctable.insert();
           
        }
        resultset.close();
        statement.close();

       info("Data Imported");
    }
    else
    {
        error("Failed to logon to the Database through ODBC");
    }
}

                                                 Outbound
static void ODBCCONNECTION_Outbound(Args _args)
{

    LoginProperty                       loginproperty;
    OdbcConnection                      odbcconnection;
    Statement                           statement;
    ResultSet                           resultset;
    Notes                               sql,values;
    SqlStatementExecutePermission       perm;
    ODBCTABLE                           odbctable;
    ;

 
    //Set the information on the ODBC.
    loginProperty = new LoginProperty();
    loginProperty.setServer("ServerName");
    loginProperty.setDatabase("DataBaseName");

     try
     {
            odbcConnection = new OdbcConnection(loginProperty);
            if(odbcConnection)
            {
                       select ODBCTABLE;
                  sql = "USE ODBCConnection";
                  sql = "INSERT INTO ODBCCUSTTABLE";
                  sql +="\n"+"  (AccountNum,CustGroup,Amount)";
                 // sql +="\nVALUES("+odbctable.accountNum+','+odbctable.CustGroup+','+odbctable.Amount+");";
                //sql+= "select (AccountNum,CustGroup,Amount) from odbctable")";
                sql += "\n"+"select AccountNum,CustGroup,Amount from ODBCTABLE;" ;
               
                    perm = new SqlStatementExecutePermission(sql);
                   perm.assert();
                    statement = odbcConnection.createStatement();
                    statement.executeUpdate(sql);
                    statement.close();
                    //update_recordset odbctable setting
                    //CustGroup = enum2str(NoYes::No)
                    //where odbctable.CustGroup ==enum2str(NoYes::Yes);
                    info("RecordS Inserted successfully.");
             }

     }
     Catch(Exception::Error)
      {
         ttsabort;
         error("Error Occured while Payment Schedule Processing");
      }

}

Friday 5 February 2016

Create Alert using X++ code

static void CreateAlertUsingCode(Args _args) 
{ 
EventInbox          inbox; 
; 
inbox.initValue(); 
inbox.ShowPopup     = NoYes::Yes; 
inbox.Subject       = "This is the Alert subject"; 
inbox.Message       = "This is the Alert message"; 
inbox.AlertedFor    = "This alert is just information no links are available"; 
inbox.SendEmail     = false; 
inbox.UserId        = curuserid(); 
inbox.TypeId        = classnum(EventType); 
inbox.AlertTableId  = tablenum(Address); 
inbox.AlertFieldId  = fieldnum(Address, Name); 
inbox.TypeTrigger   = EventTypeTrigger::FieldChanged; 
inbox.CompanyId     = curext(); 
inbox.InboxId       = EventInbox::nextEventId();; 
inbox.AlertCreatedDateTime = DateTimeUtil::getSystemDateTime(); 
inbox.insert(); 
} 


static void Event_sendAlertByCode(Args _args)
{

    EventNotificationSource _source;
    EventNotification       event = EventNotification::construct(EventNotificationSource::Sync);
    InventTable             inventTable;
    ;

    inventTable = InventTable::find('B-R14');  // sample record for which alert is shown

    event.parmRecord(inventTable);
    event.parmUserId(curuserid());      // user for which this alert to be shown
    event.parmDataSourceName('InventTable');  //form datasource
    event.parmMenuFunction(new MenuFunction('InventTable', MenuItemtype::Display));
    event.parmSubject('Test');
    event.parmMessage('Test Event alert');
    event.create();

}

Role Based Security Key in Ax 2012

Role Based Security Key

                            The Microsoft Dynamics AX security system implements a role-based security model. The primary security specifications are privileges for table fields, and policies for table records. From the perspective of the developer using the AOT, a role is an aggregation of security specifications. The security specifications are designed to support a group of job activities performed by users with a known set of job responsibilities.
                         The Microsoft Dynamics AX system administrator assigns roles to the users. The users through those role assignments acquire the permissions to perform specific system operations. You should choose role names that describe the job activities performed by users of the system.
  • Users can be assigned to one or more security roles and through those role assignments acquire the permissions to perform particular system functions.















Security role
  • Security roles represent a behavior pattern that a person in the organization can play.
  • A security role includes a defined set of application access privileges.
  • Users are assigned to one or more security roles. Each user must be assigned to at least one security role to have access to Microsoft Dynamics AX.

Duties
         A duty is a set of application access privileges that are required for a user to carry out their responsibilities.
  • A duty is a responsibility to perform one or more tasks or services for a job. Duties correspond to parts of a business process.
  • A duty can be assigned to more than one role.
  •  For example, the Maintain bank transactions duty contains the Generate deposit slips and Cancel payments privileges.
  • Although both duties and privileges can be assigned to security roles, we recommend that you use duties to grant access to Microsoft Dynamics AX.

Process Cycle
              A process cycle is a collection of duties that represent a higher level business process.
  • Process cycles organize duties and access privileges according to high level processes. For example, revenue cycle.
  • A process cycle can be defined as a group of duties for a job function.
  • For example, in the accounting process cycle, you may find the Maintain ledgersand Maintain bank transactions duties.
    Process cycles are used for organization only. The process cycles themselves cannot be assigned to roles.
Privilege
  • A privilege specifies the access that is required to accomplish a job, problem, or assignment.
  • A privilege contains permissions to individual application objects, such as user interface elements and tables.
  • Privileges group together related securable objects. For example, menu items and controls.
  • Privileges can be assigned directly to roles. However, for easier maintenance, we recommend only assigning duties to roles.
  • For example, the Cancel payments privilege contains permissions to the menu items, fields, and tables that are required to cancel payments.
    By default, privileges are provided for all features in Microsoft Dynamics AX. The administrator can modify the permissions that are associated with a privilege, or create new privileges.

Securities in Ax 2012

Configuration Key
                          Configuration keys allow administrators to enable or disable features in the application for all users. Disabling an unneeded feature helps to minimize the attack surface against potential attacks.

  • Many types of AOT elements are controlled by a configuration key. These elements have a property that is named  Configuration Key. If the property value is empty, the element is not controlled by a configuration key.
    To apply a configuration key, set the Configuration Key property of the element to the name of a configuration key.
Create a Configuration Key
  1. Expand the Data Dictionary node in the AOT.
  2. Right-click the Configuration Keys node, and then select New Configuration Key.
  3. Right-click the configuration key object, and then click Properties.
  4. Rename the configuration key by modifying the Name property.
  5. Right-click the object, and then click Create on the shortcut menu.
  6. Right-click the object, and then click Save on the shortcut menu.
  7. Right-click the object again, and then click Check In.
  • A field or table can be disabled by manipulation of a configuration key. When a configuration key is turned off, a set of tables becomes disabled. However, the data remains in the disabled tables. Later, if the configuration key is turned back on, the tables become re enabled and their data becomes available again.
AOS Authorization 
                             The AOS Authorization table property enables you to specify which data access operations must undergo user permission checking

  • None
  • CreateDelete
  • UpdateDelete
  • CreateUpdateDelete
  • CreateReadUpdateDelete
                                      Suppose AOSAuthorization is set to CreateDelete on a given table. In this case, create and delete operations would be allowed to execute only if the Application Object Server (AOS) can confirm that the user has the appropriate permissions. Update and read operations would execute without checking user permissions, because they are not mentioned in the chosen AOSAuthorizationvalue.

Table Methods
                                   The permission checking is performed by the AOS. The AOS is called to perform this checking by the following table methods:
  • aosValidateDelete
  • aosValidateInsert
  • aosValidateRead
  • aosValidateUpdate
Security Key(2009)

                                   Security keys allow administrators to set security on a user group level. Minimizing access on a user group level helps to reduce the attack surface against potential attacks.

The main reasons to apply user-level security are to:
  • Allow users to do only their designated tasks.
  • Protect sensitive data in the database.
  • Prevent users from inadvertently breaking an application by changing code or objects on which the application depends.
You need to apply a security key to:
  • Tables
  • Views
  • Menus
  • Menu items
  • Form controls
  • Report controls
Security keys are set up from  >  >  >  on the  tab.
Within a security profile, you can assign permissions that define access to Menu items, Form controls, Tables and Fields.
There are five available access levels:
  •  - Completely restricts access to that item and any sub-items it controls. The Open command is disabled. Also, the node is not displayed in the Application Object Tree (AOT).
  •  access - Members of the user group are allowed to view the item, but not use it. The SaveCompileLock and Unlockcommands are disabled.
  •  access - Members of the user group are allowed to view and use the item. The NewDuplicate and Rename commands are disabled.
  •  access - Members of the user group are allowed to view and use, as well as add new items. The Delete command is disabled.
  •  - Members of the user group have full access and consequently no commands are disabled. Additionally, members can provide additional rights in special cases.




Thursday 4 February 2016

How to create Customer through code in Ax 2012

static void Raj_CustomerCreate(Args _args)
{
    CustTable       custTable;
    NumberSeq       numseq;
    Name            name ="SouthSide Street LTDA";
   
    DirParty        dirParty;
    DirPartyPostalAddressView   dirPartyPostalAddressView;
    dirpartypostaladdressview
 
    DirPartyContactInfoView     dirPartyContactInfo;
   
    ttsBegin;
    custTable.initValue();
    numseq  = NumberSeq::newGetNum(CustParameters::numRefCustAccount());
    custTable.AccountNum = 'HYD-100';
    custTable.CustGroup  = '20';
    custTable.Currency   = 'INR';
    custTable.PaymTermId = 'Net-120';
    custTable.PaymMode   = 'Cheque';
    custTable.insert(DirPartyType::Organization , name);
   
    dirParty = DirParty::constructFromCommon(custTable);
    dirPartyPostalAddressView.LocationName      ='HeadQuarters ';
    dirPartyPostalAddressView.City              ='São Paulo';
    dirPartyPostalAddressView.Street            ='4th Avenue';
    dirPartyPostalAddressView.StreetNumber      ='18';
    dirPartyPostalAddressView.CountryRegionId   ='BRA';
    dirPartyPostalAddressView.State             ='SP';
    dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);

    dirPartyContactInfo.LocationName    ='SouthStreet Contact Phone';
    dirPartyContactInfo.Locator         ='551291165341';
    dirPartyContactInfo.Type            = LogisticsElectronicAddressMethodType::Phone;
    dirPartyContactInfo.IsPrimary       = NoYes::Yes;

        // Fill Contacts
    dirParty.createOrUpdateContactInfo(dirPartyContactInfo);

   
    ttsCommit;
   

}

Wednesday 3 February 2016

How to Invoice Purchase order through code in Ax 2012

static void Raj_POInvoice(Args _args)
{
    PurchFormLetter     purchFormLetter;
    PurchTable          purchTable;

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);
    purchTable = purchTable::find("Yours Purch id");
    purchFormLetter.update(purchTable, 'Yours Purch id',today());
    info(strFmt("purchase order %1 invoiced",purchTable.PurchId));

}

How to Create Purchase order with Multiple Lines through Code in Ax 2012

static void Raj_Po(Args _args)
{
    NumberSeq numberSeq;
    Purchtable Purchtable;
    PurchLine PurchLine;
    PurchFormLetter purchFormLetter;
    
    ;
    ttsbegin;
    numberSeq =NumberSeq::newGetNum(purchparameters::numRefPurchId(),true);

    // Initialize Purchase order values
    Purchtable.initValue();
    Purchtable.PurchId = numberSeq.num();
    Purchtable.OrderAccount = 'US-101';
    Purchtable.CurrencyCode = 'USD';
    Purchtable.initFromVendTable();
    if (!Purchtable.validateWrite())
    {
        throw Exception::Error;
    }
    Purchtable.insert();

    // Initialize Purchase Line items
    PurchLine.PurchId = Purchtable.PurchId;
    PurchLine.ItemId = 'C0001';
    PurchLine.PurchQty = 2;
    PurchLine.createLine(true, true, true, true, true, false);
    PurchLine.clear();


    PurchLine.PurchId = Purchtable.PurchId;
    PurchLine.ItemId = 'C0002';
    PurchLine.PurchQty = 1;
    PurchLine.createLine(true, true, true, true, true, false);
    ttscommit;

        //PO confirmation
    ttsBegin;
    purchTable = PurchTable::find(purchTable.PurchId);
    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PurchaseOrder);
    purchFormLetter.update(purchTable, strFmt("Inv_%1", purchTable.PurchId));
    ttsCommit;

        //PO Product Receipt
    ttsBegin;
    purchFormLetter = purchFormLetter::construct(DocumentStatus::PackingSlip);
    purchFormLetter.update(purchtable, // Purchase record Buffer
    "PO_"+purchTable.PurchId, // Invoice Number
    systemdateget()); // Transaction date
    ttsCommit;
    

    //PO Invoice
    ttsBegin;
    purchFormLetter = purchFormLetter::construct(DocumentStatus::Invoice);
    //purchFormLetter.update(purchtable,"Inv_123",systemdateget()); // Transaction date
    //purchFormLetter.update(purchTable, strFmt("PO_%1", purchTable.PurchId));
    purchFormLetter.update(purchtable, // Purchase record Buffer
    "INV-"+purchTable.PurchId, // Invoice Number
    systemdateget()); // Transaction date
    
    ttscommit;
    if (PurchTable::find(purchTable.PurchId).DocumentStatus == DocumentStatus::Invoice)
    {
        info(strfmt("Posted invoiced journal for purchase order %1",purchTable.PurchId));
    }
}

Update purchase order lines

static void updatePO(Args _args)
{
    SysExcelApplication     application;
    SysExcelWorkbooks       workbooks;
    SysExcelWorkbook        workbook;
    SysExcelWorksheets      worksheets;
    SysExcelWorksheet       worksheet;
    SysExcelCells           cells;
    COMVariantType          type;
    Name                    name;
    FileName                filename;
    Purchtable              purchtable;
    PurchLine               purchLine;
    InventDim               inventDim;
    inventDimId             inventDimId;
    int row;

    boolean first = true;
    ;

    application = SysExcelApplication::construct();
    workbooks = application.workbooks();

    filename = @"C:\Users\rajendra.c\Desktop\test.xlsx";
    try
    {
        workbooks.open(filename);
    }
    catch (Exception::Error)
    {
        throw error("File cannot be opened.");
    }

    workbook = workbooks.item(1);
    worksheets = workbook.worksheets();
    worksheet = worksheets.itemFromNum(1);
    cells = worksheet.cells();
    row =1;
    do
    {
        row++;
        select  purchtable where purchtable.PurchId == cells.item(row, 6).value().bStr()
            join purchLine where purchLine.PurchId == purchtable.PurchId;
        if(purchLine)
        {
            purchLine.clear();
            purchLine.PurchId   = cells.item(row, 6).value().bStr();
            purchLine.ItemId    = cells.item(row, 1).value().bStr();
            purchLine.PurchQty  = 1;
            //purchLine.initFromPurchTable(purchtable);
           
            //InventDim
            inventDim.clear();
            inventDim.InventSizeId   = cells.item(row, 4).value().bStr();
            //inventDim.InventSiteId   ="2";
            inventDim.wMSLocationId  = cells.item(row, 3).value().bStr();
            inventDim.inventSerialId = cells.item(row, 5).value().bStr();

            inventDimId              = InventDim::findOrCreate(inventDim).InventDimId;
            purchLine.InventDimId    = inventDimId;
            purchLine.createLine(true, true, true, true, true, false);

        }

        type = cells.item(row+1, 1).value().variantType();

    }
    while (type != COMVariantType::VT_EMPTY);
    application.quit();
    workbooks.close();

    info("Updated successfully");

}

Monday 1 February 2016

How to Get Path Value in ax 2012

static void Job39(Args _args)
{
    Dialog dialog;
    Filename filename;
    DialogField dialogFilename;
    str myCsvFile;
    ;
    dialog = new dialog();
    dialog.caption("Choose a file");
    dialogFilename = dialog.addField(extendedTypeStr(FilenameOpen));
    dialog.run();

    if(dialog.closedOk())
    {
    filename = dialogFileName.value();
    #define.file("@'"+filename+"'")
    myCsvFile = #file;
    info(myCsvFile);
    }
}