Quantcast
Channel: Microsoft Dynamics 365 Community
Viewing all 10657 articles
Browse latest View live

A Brief History of Dynamics AX (v7) on the Azure Marketplace

$
0
0

New Dynamics AX technology is creating challenges and opportunities for ISVs and partners. Solution providers are now asked to bake their experience and expertise into the product by adding process guides, methodology, sample data, and help in addition to AX customizations. The goal of this thorough product offering is to reduce the time to deploy Dynamics AX.

Productizing Industry Features on Dynamics AX

Many times companies have to make tradeoffs between having a system with a breadth of features and having a system that is well suited to their industry. Developing an ERP with a huge feature set requires an investment that only a few large players can make. However, understanding the nuances of each industry requires real-world implementation experience and feedback from end users.

The new Dynamics AX has technical capabilities that can bridge these two models. Customers can have the breadth of features they want in a single system, while also adding solutions that provide the must-have features to successfully run their business. Microsoft has provided new capabilities via Lifecycle Services (LCS) that allow implementers to fulfill this vision through a variety of tools discussed below.

The Azure Marketplace serves two purposes. It is a lead generator where prospects can see what solutions are available on Dynamics AX and contact the vendor. Perhaps more importantly, the marketplace is proof that solution creators bring a comprehensive package to the table.

LCS

LCS is the delivery mechanism for the Dynamics AX Azure Marketplace products; it contains all the assets needed to deploy the solution. Assets currently include:

  • Methodology – The steps a customer will go through to get the solution live.
  • Business Process Library – Prerecorded task guides that allow new users to quickly learn the functionality and best practices.
  • Models and Software package – Customizations that create a more robust experience in Dynamics AX.
  • Data Packages – Base configurations and data migrations to get users hands on with their data.
  • Demo Data – Demo environment to research the capabilities of the solution.
  • Environments – Deploy complex Dynamics AX environments in one day.

In the past delivering a product was focused primarily on customizing Dynamics AX. Now the capability exists to deliver more than just customizations; LCS can jump-start the implementation process as well.

Dynamics AX (v7)

New technical capabilities come with the new Dynamics AX, and it is important to leverage these capabilities when building a solution.

Extensibility

There is now a significant amount of development that can be done “off to the side” in Dynamics AX through extension technology. This approach to development becomes critically important when considering code upgrades or hotfixes. When done right, updating AX and updating the industry solution have less dependencies on each other; reducing on-going maintenance costs of Dynamics AX.

Data Management

Whether working on data migrations, integrations, or configurations, the new data management framework centralizes these tasks under an umbrella call Data Entities. Having the right entities built into the solution accelerates getting information into Dynamics AX.

Workspaces

Workspaces surface information about key tasks so users can jump into their activities in Dynamics AX. Workspaces are front and center in Dynamics AX, and it is important to combine industry knowledge into dashboards that surface the pertinent details.

Business Intelligence

Business intelligence is a first class citizen in Dynamics AX. Data can be aggregated and consumed nearly real-time, giving users more confidence in the results. Aggregated data can also be consumed directly within Dynamics AX or via PowerBI reporting dashboards.

Behind the Scenes

The approval bar is intentionally set high for the Azure Marketplace, and therefore there are some behind the scenes requirements that need to happen.

Testing

Testing is obvious when creating customizations, but it gets more complex when creating a solution. In addition to unit testing the development, there’s also a need for automated testing and performance testing of high volume and high use features.

There are also a lot more deployment tests than before. Deploying environments with default data, demo data, and compiled code are all areas that need to be validated.

Marketing

There are specific assets required to publish to the Azure Marketplace, including metadata, marketing text, and logos.

Coordination

Not only do all these assets need to be delivered, they need to be completed simultaneously for them to be approved and published on the Azure Marketplace. This adds an extra level of coordination in the Product management lifecycle.

Approval

Solutions now need to be approved by Microsoft. The approval has a number of components including best practices checks (CAR report), a video walkthrough, and publishing all the updated assets.

More information

Looking for more information? I am presenting more on these topics on a webinar on March 30, 2016.



error : Object ‘FormRun’ could not be created. when submit workflow from EP Dynamics Ax 2012

$
0
0

I got error  “‘FormRun’ could not be created “on EP. When I test the submit for approval in EP.

I have to reimplement all methods with respect to following link

 

https://msdn.microsoft.com/EN-US/library/ee677503.aspx

 

AX 2012 - sysOperation Framework implementation [Example]

$
0
0
This post demonstrates how to create batch classes using Business Operation Framework (or sysOperation). We used to use RunBaseBatch framework to implement batch functionality before this new concept of AX services was taken in place.
Compensations of BOF (or sysOperation) framework over RunBaseBatch are very well explained here http://daxmusings.codecrib.com/2011/08/from-runbase-to-sysoperation-business.html

Key points RunBase/RunBaseBatch Vs sysOperation Frameworks
  1. The sysOperation framework is an implementation of the MVC pattern (Model-View-Controller)
  2. Model - parameters [contract class]
  3. View - Dialog [contract class]
  4. Controller - Process (the code that runs in the essence of pattern)
  5. The framework influence the Services framework, whereas a service in AX has a data contract with some special attributes
  6. DataMember attributes in contract class take the entered values in parameters (dialog fields) to the process (aka "operations")
Let’s jump into example now, we are going to create a batch looks like this;


Create a new Contract Class

General concept of contract class: Contract class in basically an AX class with special attributes as you can see mentioned at the top of this class declaration. This class acts as a model of MVC (model-view-controller) pattern. 
In runbase/runbasebatch framework this model has member variables and pack/unpack (aka serialization). 
These member variables are defined in runbase/runbasebatch class declaration with pack/unpack variables handle under currentVersion and localVersion macros.

Specific to this this example: This class has two attributes; DataContractAttribute which is making it special class to leverage with AX services and the other attribute is referring to UIBuilder class. More on UIBuilder class explains well in this post follows.
[
    DataContractAttribute,
    SysOperationContractProcessingAttribute(classstr(FF_ExampleUIBuilder))
]
class FF_ExampleContract implements SysOperationValidatable
{
    FromDate                fromDate;
    ToDate                  toDate;
    NoYesId                 todaysDate;
    MainAccountNum          mainAccount;
}





[DataMemberAttribute]


public MainAccountNum parmMainAccount(MainAccountNum _mainAccount = mainAccount)


{


    mainAccount = _mainAccount;





    return mainAccount;

}









[DataMemberAttribute]


public FromDate parmFromDate(ExchangeRateImportFromDate _fromDate = fromDate)


{


    fromDate = _fromDate;





    return fromDate;

}









[DataMemberAttribute]


public ToDate parmToDate(ExchangeRateImportToDate _toDate = toDate)


{


    toDate = _toDate;





    return toDate;

}









[DataMemberAttribute]


public NoYesId parmTodaysDate(NoYesId _todaysDate = todaysDate)


{


    todaysDate = _todaysDate;





    return todaysDate;

}









public boolean validate()


{


    boolean ok = true;





    if (mainAccount == "")


    {


        ok = checkFailed("Main account cannot be blank");


    }





    if (todaysDate == NoYes::No)


    {


        if (fromDate == dateNull())


        {


            ok = checkFailed("From date cannot be blank");


        }





        if (toDate == dateNull())


        {


            ok = checkFailed("To date cannot be blank");


        }


    }





    return ok;

}





Create a new UIBuider class;
This class is only required when you want to play with added parameter (data member attributes) in contract class. Like in this example I will be enabling/disabling parameters based on other parameter values, this class can also be used to build custom lookups and perform some custom logic only to play with parameters and their values.






class FF_ExampleUIBuilder extends
SysOperationAutomaticUIBuilder


{


   
#define.MainAccount('mainAccount')


   
#define.TodaysDate('todaysDate')


   
#define.FromDate('fromDate')


   
#define.ToDate('toDate')





   
FormComboBoxControl                
mainAccountControl;


   
FormCheckBoxControl                
todaysDateControl;


   
FormDateControl                    
fromDateControl;


   
FormDateControl                    
toDateControl;

}









publicvoid
build()


{


   
DialogGroup                            
fromToDateRangeGroup;


   
DialogField                            
dialogField;


   
SAB_RetailConsolidateContract          
dataContract;





    dialog
= this.dialog();


   
dataContract = this.dataContractObject();





   
dialogField = dialog.addField(extendedtypestr(MainAccountNum));


   
mainAccountControl = dialogField.control();


   
mainAccountControl.text(dataContract.parmMainAccount());


   
mainAccountControl.name(#MainAccount);





   
dialogField = dialog.addField(extendedtypestr(NoYesId));


   
todaysDateControl = dialogField.fieldControl();


   
todaysDateControl.value(NoYes::No);


   
todaysDateControl.name(#TodaysDate);


   
todaysDateControl.label("Today");





   
fromToDateRangeGroup = dialog.addGroup("Date
range"
);


   
fromToDateRangeGroup.columns(2);


   
fromToDateRangeGroup.widthMode(FormWidth::ColumnWidth);


   
fromToDateRangeGroup.caption('');





   
dialogField = dialog.addField(extendedtypestr(FromDate));


   
fromDateControl = dialogField.control();


   
fromDateControl.name(#FromDate);


   
fromDateControl.allowEdit(true);


   
fromDateControl.dateValue(systemDateGet());


   
fromToDateRangeGroup.addFieldname(#ToDate);





   
dialogField = dialog.addField(extendedtypestr(ToDate));


   
toDateControl = dialogField.control();


   
toDateControl.name(#ToDate);


   
toDateControl.allowEdit(true);


   
toDateControl.dateValue(systemDateGet());


   
fromToDateRangeGroup.addFieldname(#ToDate);




}









/// <summary>


/// Provides form logic related to
the date type selected.


/// </summary>


/// <param
name="_importDateTypeControl">


/// The <c>FormComboBoxControl</c>
control for the date type.


/// </param>


publicboolean
dateControlSelectionChg(FormCheckBoxControl _importDateTypeControl)


{


   
FormDateControl fromDateControlLocal;


   
FormDateControl toDateControlLocal;


    boolean ret;





   
fromDateControlLocal = this.dialog().dialogForm().runControl(#FromDate);


   
toDateControlLocal = 
this.dialog().dialogForm().runControl(#ToDate);





    ret =
_importDateTypeControl.modified();





    if (_importDateTypeControl.checked() ==
NoYes::Yes)


    {


       
fromDateControlLocal.dateValue(dateNull());


       
toDateControlLocal.dateValue(dateNull());


       
fromDateControlLocal.allowEdit(false);


       
toDateControlLocal.allowEdit(false);


    }


    else


    {


       
fromDateControlLocal.dateValue(systemDateGet());


       
toDateControlLocal.dateValue(systemDateGet());


       
fromDateControlLocal.allowEdit(true);


       
toDateControlLocal.allowEdit(true);


    }


    return 
ret;




}









/// <summary>


/// Called after the user interface
has been built to allow for method overrides.


/// </summary>


publicvoid
postRun()


{


    super();





   
dialog.dialogForm().formRun().controlMethodOverload(false);


   
todaysDateControl.registerOverrideMethod(methodstr(FormCheckBoxControl,
modified), methodstr(FF_ExampleUIBuilder,
dateControlSelectionChg), this);

}








Create a new Controller class;
This class as a controller class of the MVC pattern and runs the business logic. In this example it is setting dialog title, retrieving dialog values from contract class and from Main method it is calling service class with provided method name and execution mode.






class FF_ExampleController extends SysOperationServiceController


{


   
#define.MainAccount('mainAccount')


   
#define.TodaysDate('todaysDate')


   
#define.ToDate('toDate')


   
#define.FromDate('fromDate')

}









public ClassDescription caption()


{


   
ClassDescription ret;





    // This is used to identify the batch job within batch
processing


    ret = "Example sysOperation Framework";





    return ret;

}









publicvoid
getFromDialog()


{


   
FormComboBoxControl                
mainAccountControl;


   
FormCheckBoxControl                
todaysDateControl;


   
FormDateControl                    
fromDateControl;


   
FormDateControl                    
toDateControl;





   
DialogForm                          theDialogForm;


   
FF_ExampleContract                 
FF_ExampleContract;





   
theDialogForm = this.dialog().dialogForm();





    super();





   
mainAccountControl = theDialogForm.runControl(#MainAccount);


   
todaysDateControl = theDialogForm.runControl(#TodaysDate);


   
fromDateControl = theDialogForm.runControl(#toDate);


   
toDateControl = theDialogForm.runControl(#fromDate);





   
FF_ExampleContract = this.getDataContractObject(classStr(FF_ExampleContract));





    if (FF_ExampleContract)


    {


        // Set the values in data contract


       
FF_ExampleContract.parmMainAccount(mainAccountControl.text());


       
FF_ExampleContract.parmTodaysDate(todaysDateControl.value());


       
FF_ExampleContract.parmToDate(fromDateControl.dateValue());


       
FF_ExampleContract.parmFromDate(toDateControl.dateValue());


    }

}









public LabelType parmDialogCaption(LabelType
_dialogCaption = "")


{


   
LabelType caption;





    // This appears as the window name


   
caption = "Example for SysOperation
Framework"
;





    return caption;

}









publicstatic
FF_ExampleController construct()


{


    returnnew
FF_ExampleController();


}










publicstatic
void main(Args args)


{


   
FF_ExampleController                        controller;


   
identifierName                     
        className;


   
identifierName                              methodName;


   
SysOperationExecutionMode                   executionMode;





   
[className, methodName, executionMode] =
SysOperationServiceController::parseServiceInfo(args);


   
controller = new
FF_ExampleController(className, methodName, executionMode);





    if (controller.prompt())


    {


       
controller.run();


    }

}





Create a new Service class;
This class is an AX service class with [SysEntryPointAttribute] attribute at the top of the method which will be called from action menu item.





class FF_ExampleService


{


    



}









[SysEntryPointAttribute]


public void transactionConsolidation(FF_ExampleContract FF_ExampleContract)


{


    FromDate                            fromDate       = FF_ExampleContract.parmFromDate();


    ToDate                              toDate         = FF_ExampleContract.parmToDate();


    NoYesId                             todaysDate     = FF_ExampleContract.parmTodaysDate();


    MainAccountNum                      mainAccountNum = FF_ExampleContract.parmMainAccount();





    MainAccount                         mainAccount = mainAccount::findByMainAccountId(mainAccountNum);





    if (todaysDate == NoYes::Yes)


    {


        fromDate    = systemDateGet();


        toDate      = systemDateGet();


    }





    /*


    ttsBegin;





    ... call any logic here





    ttsCommit;





    */ 

}





Create a new action menu item; 

Create new action menu item with following properties set as shown;

This menu item is calling controller class with parameters ServiceClass.MethodName with execution mode. If you see the Main method of controller class it is getting these passed parameters in this piece of code and eventually calling transactionConsolidation method of Service class.

[className, methodName, executionMode] = SysOperationServiceController::parseServiceInfo(args);
    controller = new FF_ExampleController(className, methodName, executionMode);

Since BOF services run X++ in the CLR, it is very important to generate incremental CIL after implementing new service in AX.

Another important point; the parameter name in FF_ExampleService.transactionConsolidation method MUST BE same as it is in getFromDialog() method of controller class. Otherwise you will get error object not initialised in getFromDialog method.

FF_ExampleService.transactionConsolidation

[SysEntryPointAttribute]
public void transactionConsolidation(FF_ExampleContract FF_ExampleContract)
{
    
}

FF_ExampleControler

public void getFromDialog()
{
    FormComboBoxControl                 mainAccountControl;
    FormCheckBoxControl                 todaysDateControl;
    FormDateControl                     fromDateControl;
    FormDateControl                     toDateControl;

    DialogForm                          theDialogForm;
    FF_ExampleContract                  FF_ExampleContract;

    theDialogForm = this.dialog().dialogForm();

    super();

    mainAccountControl = theDialogForm.runControl(#MainAccount);
    todaysDateControl = theDialogForm.runControl(#TodaysDate);
    fromDateControl = theDialogForm.runControl(#toDate);
    toDateControl = theDialogForm.runControl(#fromDate);

    FF_ExampleContract = this.getDataContractObject(classStr(FF_ExampleContract));

    if (FF_ExampleContract)
    {
        // Set the values in data contract
        FF_ExampleContract.parmMainAccount(mainAccountControl.text());
        FF_ExampleContract.parmTodaysDate(todaysDateControl.value());
        FF_ExampleContract.parmToDate(fromDateControl.dateValue());
        FF_ExampleContract.parmFromDate(toDateControl.dateValue());
    }
}

AX7 T&A: Teams and assistant

$
0
0
In a dynamic factory setting where human resources go back and forth between different jobs, roles and machines it is important to track each resource to get a good overview of the costing. Some times...(read more)

AX 2012 - sysOperation Framework - Use controller class to open dialog from AX form

$
0
0
In my previous post on sysOperation framework Example I described how the sysOperation framework can be used for the batch functionality in contrast to RunBaseBatch framework. In this post I will explain how you can use sysOperation Framework classes to open a dialog from a AX form using contract and controller classes and then run logic in Service class.

In this example I added a new menu item "Example" on projProjectsListPage form which will call controller class. This example is create project transactions using service calls at the end.









First we need to create a contract class which holds parameters (dialog fields value or user input). To keep it simple I only added two parameters ProjId (Project Id) and ProjContractId (Project Contract Id). That's the model part of MVC pattern and view part is automatically created by using these data member attributes.







[DataContractAttribute]


class FF_ExampleContract


{


   
ProjId              projId;


   
ProjInvoiceProjId  
projContractId;

}











[DataMemberAttribute,


SysOperationLabelAttribute(literalStr("Selected
Project Id"
)),


SysOperationHelpTextAttribute(literalStr("Selected
Project Id from projects"
)),


SysOperationDisplayOrderAttribute('1')


]


public ProjId parmProjId(ProjId _projId
= projId)


{


    projId =
_projId;


    return projId;

}











[DataMemberAttribute,


SysOperationLabelAttribute(literalStr("Selected
Project contract Id"
)),


SysOperationHelpTextAttribute(literalStr("Selected
Project Contract Id from projects"
)),


SysOperationDisplayOrderAttribute('2')


]


public ProjInvoiceProjId
parmProjContractId(ProjInvoiceProjId _projContractId = projContractId)


{


   
projContractId = _projContractId;


    return projContractId;

}






Let's move to controller part of sysOperation framework and create a new controller class.

For this example I don't need to have batch tab on dialog, so I set return value to FALSE in canGoBatch() method.







class FF_ExampleController extends SysOperationServiceController


{


    Common
callerRecord;







}












publicstatic
void main(
Args
_args
)


{


   
FF_ExampleController controller;





   
controller = FF_ExampleController::newFromArgs(_args);





   
controller.parmShowDialog(true);


   
controller.initFromCaller();


   
controller.startOperation();


   
controller.refreshCallerRecord();



























}












publicstatic
FF_ExampleController newFromArgs(Args _args)


{


   
FF_ExampleController       
controller;





   
IdentifierName             
className;


   
IdentifierName             
methodName;


    SysOperationExecutionMode   executionMode;





   
[className, methodName, executionMode] =
SysOperationServiceController::parseServiceInfo(_args);


    if (_args.record())


    {


       
executionMode = SysOperationExecutionMode::Synchronous;


    }


    controller
= new
FF_ExampleController(className, methodName, executionMode);


   
controller.parmArgs(_args);


   
controller.parmCallerRecord(_args.record());





    return controller;





































}












public LabelType
parmDialogCaption(LabelType _dialogCaption = "")


{


    LabelType
caption;


    // This appears as the window name


    caption =
"Create project transaction";


    return caption;













}












protectedvoid
new(


    IdentifierName
_className = classStr(FF_ExampleService),


   
IdentifierName _methodName = methodStr(FF_ExampleService,
example),


   
SysOperationExecutionMode _executionMode =
SysOperationExecutionMode::ReliableAsynchronous


    )


{


    super(_className, _methodName,
_executionMode);















}












privatevoid
initFromCaller()


{


   
#define.dataContractKey('_contract')





   
FF_ExampleContract contract;





    ProjTable       projTable;





    contract
= this.getDataContractObject(#dataContractKey) as
FF_ExampleContract;





    switch (this.parmCallerRecord().TableId)


    {


        casetableNum(ProjTable)
:


           
projTable = this.parmCallerRecord() as
ProjTable;


           
contract.parmProjId(projTable.ProjId);


           
contract.parmProjContractId(projTable.ProjInvoiceProjId);


            break;


    }





































}












publicboolean
canGoBatch()


{


    returnfalse;









}












public Common parmCallerRecord(


    Common
_callerRecord = callerRecord


    )


{


   
callerRecord = _callerRecord;


    return callerRecord;













}












/// <summary>


///    Refreshes the calling form data source.


/// </summary>


protectedvoid
refreshCallerRecord()


{


   
FormDataSource callerDataSource;





    if (this.parmCallerRecord() &&
this.parmCallerRecord().dataSource())


    {


       
callerDataSource = this.parmCallerRecord().dataSource();


       
callerDataSource.research(true);


    }

























}







In the new method of controller class it is eventually calling service class method. We could create a method in controller class itself and refer that method into the new method of controller class to process business logic. This seems to be a lot for controller class, first to handle all parameters and then process business logic, recommended way is to separate the business logic in service class and another advantage of having service class is, these operations can also be used in web services (AIF) operations. That's the separate topic and we will talk about it later...

Let's create new service class and add entry point method to process business logic.







class FF_ExampleService


{


   
FF_ExampleContract contract;







}












[SysEntryPointAttribute]


publicvoid
createProjectTransaction(FF_ExampleContract _contract)


{


   
ProjId                  projId;


   
ProjInvoiceProjId      
projContractId;





   
contract            = _contract;





   
projId          =
contract.parmProjId();


   
projContractId  =
contract.parmProjContractId();





    /*


   


    .... create project transactions


   


    */

































}







Have we achieved what we aimed at start?

We are almost there, just need to add a new action menu item and assign controller & service class to it.













That's it!!! run the menu item and see how it works...














Click on Example menu item from Project list page, it opened a dialog with correct title 'Create project transactions' and with correct Project Id passed from calling form (ProProjectsListPage). 

Happy Dax!ng...


AX 2012 : Generate customer account statement as PDF through X++

$
0
0
Customer account statement in AX 2012 R3 can be generated from Accounts Receivable > Reports > External > Customer account statement. However, if we need to generate this report through code - how can we achieve this?

I created a new query in AOT with only dataSource 'CustTable', as I want to loop on selected customers only. I created a class extending from RunBase (did not want to touch existing report and class for customer account statement) being considering it a custom process of generating customer account statement using X++ code opposed to what exists in system.

New query looks like this with three ranges, these ranges will show on dialog form
















Created a new class with following methods which are common for every dialog class;


  • main
  • construct
  • new
  • pack
  • unpack
  • dialog
  • getFromDialog
  • run
  • showQueryValues
  • queryRun

I will explain important methods from the class which I think need discussion.

QueryRun method - this method will be called from Pack() method from this line of code return [#CurrentVersion,#CurrentList,this.queryRun().pack()];








public QueryRun queryRun()


{


    QueryRun                ret;


    QueryBuildDataSource    qbds;


    CustTable               custTable =
CustTable::findRecId(selectedRec);





    if
(!queryRun)


    {


        query  
=   new
query(queryStr(FF_CustAccountStatement));


        qbds = query.dataSourceTable(tableNum(custTable));


        if(selectedRec)


        {


            SysQuery::findOrCreateRange(qbds, fieldNum(custTable, AccountNum)).value(custTable.AccountNum);


            SysQuery::findOrCreateRange(qbds, fieldNum(custTable,
CustGroup)).value(custTable.CustGroup);


            SysQuery::findOrCreateRange(qbds, fieldNum(custTable,
AccountStatement)).value(SysQuery::value(custTable.AccountStatement));


        }


        else


        {


            SysQuery::findOrCreateRange(qbds, fieldNum(custTable,
AccountNum)).value(SysQuery::valueUnlimited());


            SysQuery::findOrCreateRange(qbds, fieldNum(custTable,
CustGroup)).value(SysQuery::valueUnlimited());


            SysQuery::findOrCreateRange(qbds, fieldNum(custTable,
AccountStatement)).value(SysQuery::valueUnlimited());


        }


        queryRun    =   new QueryRun(query);


    }





    ret = queryRun;





    return
ret;

}







This method generates customer account statement for each provided customer in query. This method is called from run() method;

while (queryRun.next())
    {
        custTable    =   queryRun.get(tableNum(custTable));
        //this.setParameters(custTable);

        filename    =   WinAPI::getTempPath()+"Customer "+ custTable.AccountNum+ " Customer Account Statement.pdf";

        this.createCustAccountStatement(custTable, filename);

    }

public void createCustAccountStatement(CustTable _custTable,FileName _filename)
{
    CustAccountStatementExtController      controller = new CustAccountStatementExtController();
    SRSPrintDestinationSettings            printSettings;
    CustAccountStatementExtContract        Contract;

    controller.parmReportName(PrintMgmtDocType::construct(PrintMgmtDocumentType::CustAccountStatement).getDefaultReportFormat());
    controller.parmLoadFromSysLastValue(true);
    controller.parmShowDialog(false);

    printSettings = controller.parmReportContract().parmPrintSettings();

    printSettings.printMediumType(SRSPrintMediumType::File);
    printSettings.fileFormat(SRSReportFileFormat::PDF);
    printSettings.overwriteFile(true);
    printSettings.fileName(_filename);

    Contract = controller.parmReportContract().parmRdpContract() as CustAccountStatementExtContract;

    enumerator = controller.parmReportContract().parmQueryContracts().getEnumerator();
    enumerator.moveNext();
    query = enumerator.currentValue();
    query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable, AccountNum)).value(queryValue(_custTable.AccountNum));

    Contract.parmAgingBucket(agingBucket);
    Contract.parmAgingBucketPrintDescription(AgingBucketPrintDescription);
    Contract.parmAgingPeriod(agingPeriod);
    Contract.parmDayMonth(dayMonth);
    Contract.parmFromDate(fromDate);
    Contract.parmIncludeReversed(includeReversed);
    Contract.parmManualSetup(manualSetup);
    Contract.parmOnlyOpen(onlyOpen);
    Contract.parmPrintAging(printAging);
    Contract.parmPrintAmountGiro(printAmountGiro);
    Contract.parmPrintCreditLimit(printCreditLimit);
    Contract.parmPrintGiro(printGiro);
    Contract.parmPrintingDirection(printingDirection);
    Contract.parmPrintNonZero(printNonZero);
    Contract.parmPrintPaymentSchedule(printPaymentSchedule);
    Contract.parmPrintType(printType);
    Contract.parmSpecifyDueToDate(specifyDueToDate);
    Contract.parmToDate(toDate);
     
    controller.startOperation();
}

It generates report in user's temp folder for each selected customer on below screen [this is custom screen created by a class which I referred above]



AX7 T&A: Document groups

$
0
0
When working on the Job card terminal or Job card device you are able to access attachments to the orders you’re working on. This is done by clicking the attachment button/menu item. Job card terminal...(read more)

Dynamics AX Vendor Portal (AX7)

$
0
0
General notes The vendor portal in Dynamics AX 2012 was based on the enterprise portal and used the SharePoint platform as an underlying architecture. If you’ve ever tried to do an amendments to...(read more)

Are You Prepared for a Mobile Device Data Breach?

$
0
0

Analysts from Gartner have predicted that by 2017, the focus of endpoint breaches will be predominately mobile devices such as smartphones and tablets. Their prediction makes sense – after all, the firm estimated that 2.2 billion smartphones and tablets were sold in 2014.

The growing number of mobile devices makes the threat of data breaches ever more likely. Many of these data breaches won’t be the result of hackers, say Gartner analysts. They believe that 75% of breaches will be due to the misconfiguration of mobile apps.

With these sobering statistics in mind, businesses can no longer say, “Data breaches can’t happen here.” Not only are data breaches possible, they are probable. Organizations must implement a plan to prevent data breaches, although they must also have a strategy in place for when a data breach takes place.

What to Do after a Data Breach Takes Place

Once you have determined that a data breach affecting mobile devices has taken place, there are several critical steps you must take to mitigate the damage.

The first step is to determine how the breach took place. Was it the result of a lost or stolen device? Did a hacker launch an attack on your company?

Secondly, the corporation’s security team must figure out the extent of the breach. They should be able to assess what information was on the device, the sensitivity of the data, whether the data was encrypted or not, if the device and information can be recovered, and whether or not further data will be exposed.

Similarly to a network data breach, the third step is to fix the problem. When it comes to mobile devices, a two-pronged approach might be necessary. Implementing an enterprise mobility management system is part of the solution. This software protects confidential corporate information, determines which apps are safe, and allows users to access shared content without putting the company at risk. However, it is equally important to educate users about device and data loss prevention. A knowledgeable workforce is the first line of defense against threats.

Notification about Data Breaches

Many jurisdictions have enacted legislations requiring organizations to notify people affected by a data breach. Companies that have suffered a data breach might have a legal responsibility to carry out these notifications. And if the organization operates in more than one jurisdiction, it might be subject to different notification requirements.

How do you know what your legal obligation for notification is? Consult your legal counsel in each relevant jurisdiction. Your legal team will be familiar with the legislation regarding data breach notification (which continues to evolve on an annual basis in order to keep up with technology).

Even if you’ve fixed the problem that led to the data breach, you cannot sweep it under the rug and pretend it didn’t happen. There are harsh penalties for failing to comply with notification regulations. While your corporate reputation will suffer because of the breach, not following the law will worsen the situation.

The post Are You Prepared for a Mobile Device Data Breach? appeared first on Merit Solutions.

Lançar lista de separação e iniciar roteiro de separação para ordem de transferência

$
0
0

Olá Pessoal,
Tudo bem?

Pessoal estou compartilhando com vocês o processo para realizar o lançamento de lista de separação, inicar roteiro de lista de separação e atualizar todas as linhas do roteiro por código X++ para o Microsoft Dynamics AX 2012 caso precisem.

publicboolean init(){boolean ret =true;
 
    ret = this.validate();
 
    if(ret){//Post PickingList
        this.pickingList();
        //Start Router from Picking list
        wmsPickingRouteID = this.wmsPickingRouteStart();
        //Update all from Router
        this.pickAllLines(wmsPickingRouteID);
    } 
    return ret;
}
/// <summary>/// Realiza o lançamento da lista de separação/// </summary>publicvoid pickingList(){
    InventTransferParmTable     localInventTransferParmTable;
    InventTransferMultiPick     localInventTransferMultiPick = InventTransferMultiPick::construct();
    ;
 
    localInventTransferParmTable.TransferId=   inventTransferId; //Provide transferId
    localInventTransferParmTable.EditLines=   NoYes::Yes;
    localInventTransferParmTable.AutoReceiveQty=   NoYes::Yes;
    localInventTransferParmTable.TransDate=systemDateGet();
    localInventTransferParmTable.UpdateType=   InventTransferUpdateType::PickingList;
    localInventTransferParmTable.PickUpdateQty=   InventTransferPickUpdateQty::All ;
    localInventTransferMultiPick.runUpdate(localInventTransferParmTable);
}
/// <summary>/// Iniciar roteiro de separação/// </summary>/// <returns>/// Retorna o nr. do roteiro/// </returns>public WMSPickingRouteID wmsPickingRouteStart(){
    WMSPickingRoute         localWMSPickingRoute;
    WMSPickingRouteStart    localWMSPickingRouteStart;
 
    //Buscar roteiro vinculado ao registro da lista de separaçãoselectfirstOnly PickingRouteID, expeditionStatus
        from localWMSPickingRoute
        where localWMSPickingRoute.transType== InventTransType::TransferOrderShip&& localWMSPickingRoute.transRefId==  inventTransferId;
 
    if(localWMSPickingRoute.PickingRouteID){//Verificar se esta com o status ativadoif(localWMSPickingRoute.expeditionStatus== WMSExpeditionStatus::Activated){
            localWMSPickingRouteStart =new  WMSPickingRouteStart();
            localWMSPickingRouteStart.parmWMSPickingRouteId(localWMSPickingRoute.PickingRouteID);
            localWMSPickingRouteStart.parmWorker(DirPersonUser::findUserWorkerReference());
            localWMSPickingRouteStart.run();
        }} 
    return localWMSPickingRoute.PickingRouteID;
}
/// <summary>/// Atualizar todas as linhas do roteiro da lista de separação/// </summary>/// <param name="_pickingRouteID">/// Nº do roteiro a ser atualizado/// </param>publicvoid pickAllLines(WMSPickingRouteID _pickingRouteID){
    List            list =new List(Types::String);
    WMSPickingRoute localWMSPickingRoute;
 
    //verificar se o roteiro foi informadoif(!_pickingRouteID){//Buscar pelo nº da ordem de transferênciaselectfirstOnly PickingRouteID, expeditionStatus
            from localWMSPickingRoute
                where localWMSPickingRoute.transType== InventTransType::TransferOrderShip&& localWMSPickingRoute.transRefId==  inventTransferId;
    }else{//Buscar pelo nº do roteiroselectfirstOnly PickingRouteID, expeditionStatus
            from localWMSPickingRoute
                where localWMSPickingRoute.PickingRouteID== _pickingRouteID;
    } 
    //Verificar se o roteiro esta com o status iniciadoif(localWMSPickingRoute && localWMSPickingRoute.expeditionStatus== WMSExpeditionStatus::Started){
        list.addEnd(localWMSPickingRoute.PickingRouteID);
        WMSPickingRoute::finishMulti(list.pack()); 
        wmsDeliverPickedItems::checkDeliverPickedItems(localWMSPickingRoute.PickingRouteID,list.pack());
    }}

Abraços,
Juliano Bachesque

Catching and auditing duplicate receipts with Gorilla Expense

$
0
0

gorilla post auditing duplicate receiptsFor companies that have travelers on the road, one of the main challenges when it comes to the expense reporting reconciliation is catching and potentially auditing duplicate receipts. It is important to note that in many cases, these expenses might be legitimate; because they are repeat expenses – for example an employee might be at a conference for a week and purchase the same Starbucks coffee for $4.5 every morning. While these expenses may appear to be duplicates to the casual observer, they are really not. The main problem is when a traveler uses the same receipt twice. And this is where Gorilla Expense comes to the rescue! So how do we do it?

 

The first step is during the manager review/approval process. The manager receives the submitted expense report, and the application clearly highlights the fact that there may be potential duplicates in the expense report. Below is an example expense report with the highlights:

gorilla post 2auditing duplicate receipts

Once the manager clicks on the Yellow triangle at the bottom of the expense report page, the application will open a ‘Potential Duplicate’ report, where the manager can compare the details of the current expense transaction of $7.1 allocated to MEALS with a previous transaction with the same details. Here is a screenshot of what that looks like:

gorilla post 3 auditing duplicate receipts

It is clear to see that the employee had submitted the same transaction as part of expense report # GE1576, which is noted by the application to be the ‘Original’ transaction. The potential duplicate which is for the current expense report that the manager is reviewing is shown below that Original expense.

By clicking on the blue ‘Receipt’ link, the manager can also compare the receipts of both of these expenses and see if they are indeed different receipts or if the same receipt was used twice. Pretty cool right?

Gorilla Expense makes the next steps very easy too. If the receipt is indeed different, then the manager can approve the expense report and move it forward to the next approver or accounting for reimbursement. However if the same receipt has been used twice, the manager can remove just that one expense line and approve the rest of the expense report. During that time, the manager can also provide comments or remarks to the employee on why this particular expense line was being removed.

It would then be up to the company to advise the employee about their T&E policies and take appropriate action, if it is indeed a case of fraud with an established intent to submit a duplicate receipt. As they say, the best way to tackle fraud is to let employees know that their expenses are being monitored carefully by utilizing an automated T&E application. And this is how Gorilla Expense tackles this potential duplicate receipts pain point in a very intelligent and elegant manner.

Want to learn more? Would you like to see a live demo of this feature in action? Feel free to contact us at sales@gorillaexpense.com


About Gorilla Expense

Gorilla Expense is a leading global provider of T&E Expense Management Software for Microsoft Dynamics ERP. Our Expense Reporting, Mobile Apps, Integration Services & Analytics solutions give customers the edge they need to compete in the global marketplace. With our powerful solution, we are constantly proving that – Expense management doesn’t have to be so difficult! Learn more at www.gorillaexpense.com

The post Catching and auditing duplicate receipts with Gorilla Expense appeared first on goERPcloud.

Basic constraint based configuration product and model setup.

$
0
0
If you are starting to explore setting up constraint based configured products then it helps to start simple till you understand how the models works and then add to it. The first thing you need to do...(read more)

Microsoft Dynamics AX 2012: Viewing Project Control Transactions in Microsoft Excel

$
0
0
Measurement is fundamental to high performance, improvement, and success. The export to Microsoft Excel function in project control allows you to create a multidimensional pivot table reports. A simple...(read more)

Reuse configurations on constraint based product model

$
0
0
If you are using the constraint based product configurator then you might want to consider the overall lifecycle of the data in your system. There is an option to enable reuse of configurations which will...(read more)

Gartner: Microsoft One of Just Two Market Leaders in Application Platform as a Service (aPaaS)

$
0
0
The air is pretty thin when it comes to Enterprise Application Platform as a Service (aPaaS) providers, finds Gartner. Only Microsoft and Salesforce rated Leader status in Gartner's aPaaS Magic Quadrant, released last week. The two companies were ...read more

AX7 T&A: Electronic Timecards

$
0
0
The concept of Electronic timecards are used to manually enter time or change your existing time journals based on your terminal registrations. The form is rather detailed and does require some end-user...(read more)

Creating extension of elements in Microsoft Dynamics AX7

$
0
0
In Microsoft Dynamics AX7, we can create an extension of elements to customize an existing object. Creating extension in AX7 does not overlay the baseline model elements as in Microsoft Dynamics AX 2012...(read more)

Certified EDI Provider Data Masons Software Joins Envision 2016

$
0
0

Data Masons Software, a leading provider of Integrated EDI and XML solutions for Microsoft Dynamics customers, announces its sponsorship of Microsoft Envision 2016, April 4-7, 2016 in New Orleans, LA. Microsoft designed Envision to provide business leaders with the opportunity to discover business insights, gain technology expertise and learn successful strategies to help their businesses achieve more.

Export to Excel vs Open in Excel in the new Dynamics AX.

$
0
0
If you are starting to work with the new Dynamics AX there are some nice updates to the Excel integration. You still have the basic export to excel download which is just a basic export of the data but...(read more)

Real-time Supply Chain

$
0
0

With technology and the right processes, the flow of information and transactions in a supply chain reach further and further upstream and downstream. If they don’t know it already, customers, vendors and suppliers will soon be demanding more because they can see the benefits of working with an organization that can quickly respond to their particular needs. They are demanding a real-time supply chain.

Achieving a real-time supply chain starts with speed. The information available from trading partners must be simultaneously processed by efficient workstreams to meet the needs of customers. An integrated infrastructure and real-time data drive the technology needed to deliver on-time or sooner. For example, using big data to predict when raw materials are needed before the customer asks allows a company to produce now, without waiting for an update on a supplier’s availability.

When it comes to customers, two benefits of a real-time supply chain go hand-in-hand: customer satisfaction and personalized products. Now, more than ever, the customer is King. Forget about high-end customers being limited to what a business is producing at that time. The information about customer needs is available upstream at the manufacturer’s fingertips even before production begins, allowing a business to customize its deliverables in real-time. There’s nothing like a personalized product designed to fit unique specifications to boost customer satisfaction. With a real-time supply chain, a business can listen to a demand for an entirely unique product, say “no problem”, and deliver ahead of schedule.

Relationships with customers is not the only benefit of a real-time supply chain. The right combination of a robust ERP system and integrated processes lead to stable yet innovative business networks that can morph to meet the needs of both trading partners. Business is about building relationships that are mutually beneficial and reliable. Leveraging technology to stay abreast of a supplier’s pipeline or a vendor’s output is powerful and leads to more predictable B2B relationships. The real-time supply chain keeps them happy and puts the company in great position to be a preferred partner, which results in higher quality products and higher customer satisfaction.

A manufacturer’s ERP system cannot simply bring together an organization’s departments to be successful. Rather, a dynamic ERP solution integrated with powerful workstreams must be optimized to connect with customers, vendors, and suppliers in new and innovative ways. Processing information in real-time and have a lean, agile organization ready to respond to that information leads to a real-time supply chain that boosts customer satisfaction and the bottom line.

The post Real-time Supply Chain appeared first on Merit Solutions.

Viewing all 10657 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>