Truncate AxDB database log


Recently on one of the environments with the below error

After investigation, found an issue with the MSSQL_Logs drive got full

So I figure the issue by truncating or shrinking of database log by following the below steps.

Truncate the transaction log

  1. Right-click the AxDB database and select Properties -> Options.
  2. Set the recovery model to Simple and exit the menu.
  3. Right-click the database again and select Tasks -> Shrink -> Files.
  4. Change the type to Log .
  5. Under Shrink action, select Reorganize pages before releasing unused space and click OK.

Read File’s from SFTP Server and Write data in AX365 (PART 1)


In Part 1, will create a project with basic SFTP functionality which we will use in AX in Part 2

Basic Step is to add the Parameters to set the SFTP details.

Tips:

If we are using Port 22 then no need to use a prefix of SFTP in your Host because 21 is for FTP and 22 is for SFTP

Your File path should start from the directory root folder not from the SFTP server name.

To connect to the SFTP Server. I used SSH.NET Dll.

Create a New C# Library project, Right Click on your project, click on Manage NuGet Packages and Install ssh.net In your project. It will add a reference of DLL into your project.

Add a reference of this dll in your class

using Renci.SshNet;

Now we need to write a method to make a connection,

1
2
3
4
5
6
7
8
9
10
11
12
13
public SftpClient OpenSFTPConnection(string host, int port, string username, string password)
{
    if (this.sftpClient == null)
    {
        this.sftpClient = new Renci.SshNet.SftpClient(host, port,      username, password);
    }
   if (!this.sftpClient.IsConnected)
    {
        this.sftpClient.Connect();
    }
    return this.sftpClient;
}

This method will return all the files present in the directory

1
2
3
4
public List<string> GetDirectories(SftpClient _SftpClient, string path)
{
        return _SftpClient.ListDirectory(path)/*.Where(n => n.IsDirectory).ToList();
}

This method will return the stream which we can use to read the content of the files.

public Stream DownloadFile(SftpClient _SftpClient, string sourcePath)
 {
        var memoryStream = new MemoryStream();
        _SftpClient.DownloadFile(sourcePath, memoryStream);
        memoryStream.Position = 0;
        return memoryStream;
}

I also got a requirement to move files to a different folder after writing data in AX. Below method will do that magic.

1
2
3
4
public void MoveFile(SftpClient _SftpClient, string sourcePath, string destinationPath, bool isPosix)
{
        _SftpClient.RenameFile(sourcePath, destinationPath, isPosix);
}

Final Code for our library project will look like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using Renci.SshNet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MySshNet
{
    public class sftpConnection
    {
        public SftpClient sftpClient;
        public SftpClient OpenSFTPConnection(string host, int port, string username, string password)
        {
            if (this.sftpClient == null)
            {
                this.sftpClient = new Renci.SshNet.SftpClient(host, port, username, password);
            }
            if (!this.sftpClient.IsConnected)
            {
                this.sftpClient.Connect();
            }
            return this.sftpClient;
        }
        public List<string> GetDirectories(SftpClient _SftpClient, string path)
        {
            return _SftpClient.ListDirectory(path)/*.Where(n => n.IsDirectory)*/.Select(n => n.Name).ToList();
        }
        public void MoveFile(SftpClient _SftpClient, string sourcePath, string destinationPath, bool isPosix)
        {
            _SftpClient.RenameFile(sourcePath, destinationPath, isPosix);
        }
        public Stream DownloadFile(SftpClient _SftpClient, string sourcePath)
        {
            var memoryStream = new MemoryStream();
            _SftpClient.DownloadFile(sourcePath, memoryStream);
            memoryStream.Position = 0;
            return memoryStream;
        }
    }
}

Now Just build your project then go to your projects bin\Debug folder and copy both Dll’s. paste the DLL’s to your AX extension Bin Folder so we can use it in our AX project.

Tips:

We need to add our Dll’s in our extension Bin folder so It can go through with check in to the next environments.

Reference: https://dynamicsax4u.wordpress.com/2020/08/18/read-files-from-sftp-server-and-write-data-in-ax365-part-1/?blogsub=confirming&blogsub=confirming#subscribe-blog

Security Authorization and Access Control in D365


How to authorize users security roles that are assigned to them including process cycles, duties, privileges, and permissions.

Security Roles
All users must be assigned to at least one security role in order to have access to D365. The security roles that are assigned to a user determine the duties that the user can perform and the parts of the user interface that the user can view. Administrators can apply data security policies to limit the data for the access of user roles.



For example a user in a role may have access to data only from a single organization. The administrator can also specify the level of access that the users in a role have to current, past, and future records and also users in a role can be assigned privileges that allow them to view records for all periods, but that allow them to modify records only for the current period.

By managing access through security roles, administrators save time because they do not have to manage access separately for each users. Security roles are defined one time for all organizations. In addition, users can be automatically assigned to roles based on business data.

For example the administrator can set up a rule that associates a Human resources position with a security role. Any time that users are assigned to that position, those users are automatically added to the appropriate security roles. Users can also be automatically added to or removed from roles based on the Active Directory groups that they belong to.

Security roles can be organized into a hierarchy. A role hierarchy enables roles to be defined as combinations of other roles.

For example the sales manager role can be defined as a combination of the manager role and the salesperson role. In the security model of D364, duties and privileges are used to grant access to the program also it can be assigned to maintain revenue policies and review sales orders duties.

By default, sample security roles are provided. All functionality in Microsoft Dynamics 365 for Finance and Operations is associated with at least one of the sample security roles. The administrator can assign users to the sample security roles, modify the sample security roles to fit the needs of the business, or create new security roles. By default, the sample roles are not arranged in a hierarchy.

Process Cycles
A business process is a coordinated set of activities in which one or more participants consume, produce, and use economic resources to achieve organizational goals.
To help the administrator locate the duties that must be assigned to roles, duties are organized by the business processes that they are part of. In the context of the security model, business processes are referred to as process cycles.



For example 
in the accounting process cycle, you may find the Maintain ledgers and Maintain bank transactions duties. Process cycles are used for organization only. The process cycles themselves cannot be assigned to roles.

Duties
Duties correspond to parts of a business process. The administrator assigns duties to security roles. A duty can be assigned to more than one role. In the security model for Microsoft Dynamics 365 for Finance and Operations, duties contain privileges.

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, it is recommended that you use duties to grant access to Microsoft Dynamics 365 for Finance and Operations.

You can assign related duties to separate roles. These duties are said to be segregated. By segregating duties, you can better comply with regulatory requirements, such as those from Sarbanes-Oxley (SOX), International Financial Reporting Standards (IFRS), and the United States Food and Drug Administration (FDA). In addition, segregation of duties helps reduce the risk of fraud, and helps you detect errors or irregularities. Default duties can provide administrator to modify the privileges that are associated with a duty, or create new duties.

Privileges
In the security model for Microsoft Dynamics 365 for Finance and Operations, a privilege specifies the level of access that is required to perform a job, solve a problem, or complete an assignment. Privileges can be assigned directly to roles. However, for easier maintenance, we recommend that you assign only duties to roles. A privilege contains permissions to individual application objects, such as user interface elements and tables.

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 365 for Finance and Operations. The administrator can modify the permissions that are associated with a privilege, or create new privileges.

Permissions
In the security model for Microsoft Dynamics 365 for Finance and Operations, a permission grants access to logical units of data and functionality, such as tables, fields, forms, and server side methods. Only developers can create or modify permissions. The screen shot on top shows the Security configuration form where system administrators can create and edit roles and view the duties, privileges, and so on that are related.

Security Structure in D365


In D365 the security model is hierarchical, and each element in the hierarchy represents a different level of detail.
Permissions represent access to individual secure objects, such as menu items and tables.
Privileges are composed of permissions and represent access to tasks, such as canceling payments and processing deposits.
Duties are composed of privileges and represent parts of a business process, such as maintaining bank transactions.
Both duties and privileges can be assigned to roles to grant access to Microsoft Dynamics 365 for Finance and Operations.

  • Application Security Aligned with your Business

In earlier versions, administrators created their own user groups and manually assigned users to those groups. In Microsoft Dynamics 365 for Finance and Operations, security is role-based, and many security roles and duties are provided to help base security definitions. Using role-based security, users are assigned to roles, based on their responsibilities in the organization and their participation in business processes. Instead of identifying and granting access to application elements, the administrator assigns duties which users in the role perform. Because rules can be set up for automatic role assignment, the administrator does not have to be involved every time a user’s responsibilities change. After security roles and rules are set up, role assignments are updated based on changes in business data.

  • Reusable Permissions

In Microsoft Dynamics 365 for Finance and Operations, a single set of roles applies across all companies and organizations. The administrator no longer has to create and maintain separate user groups for each company, as was the case in earlier versions. Even though roles themselves are not specific to a company or organization, the administrator can still specify a company or organization context for a particular user in a role.

Change maintenance mode for license configuration in D365


How to change maintenance mode for license configuration in Dynamics365. When we need to enable / disable configuration key we can do it by going at navigation System administration > Setup > License configuration  by this setup we can enable / disable configuration key. By-default in D365 License configuration setup is disable due to maintenance mode is set to False

In order to enable or disable configuration we need to change the maintenance mode to True. There are two ways to achieve it: (1) By Sql Query(2) By Command

By Sql Query:
–System variable table having system settings and configurations.
update SQLSYSTEMVARIABLES
–Set value to 1 (True).
set SQLSYSTEMVARIABLES.VALUE = 1
–Where clause of configuration mode.
where PARM = ‘CONFIGURATIONMODE’


By Command:
C:\AosService\PackagesLocalDirectory\Bin\Microsoft.Dynamics.AX.Deployment.Setup.exe –metadatadir C:\AosService\PackagesLocalDirectory –bindir C:\AosService\PackagesLocalDirectory\Bin –sqlserver . –sqldatabase axdb –sqluser <SQL admin user id> –sqlpwd <SQL users password> –setupmode maintenancemode –isinmaintenancemode true

Note: Change drive command in my case I have “C Drive” and change SQL user and password accordingly.

After using one of the method to change the maintenance mode, restart IISServer.

Ref: http://axtechsolutions.blogspot.com/

Tips & Tricks for Debugging in Visual Studio for D365


In this blog, I have covered some tips and tricks supported for D365 in Visual studio.

Tip # 1 – Pin data tips
While debugging code we have frequently hover over data tips in order to see the values contains in variables. In VS we can pin the data tip for the variable to give our-self quick access. To pin the data tip, click the pin icon while hovering over it. You can pin multiple variables.

First way to pin is to select your variable and right-click it as shown in image.

Second way to pin is to hover your variable click pin icon.

Tip # 2 – Conditional Break points
If it is difficult or time-consuming to recreate a particular state in your app, consider whether the use of a conditional breakpoints can help. Right-click a break-point icon (the red ball) and choose Conditions. In the Break-point Settings window, type an expression.


Tip # 3 – Track an out-of-scope object
We can view variables values using debugger window. However, when a variable goes out of scope in the Watch window, you may notice that it is grayed out. In VS we can track those variable by creating an Object ID for it in the Watch window.

To Create an object Id:
– Set a break-point near a variable that you want to track.
– Stop your break-point at your variable.
– Find variable in the Locals window (Debug > Windows > Locals), right-click the variable, and select Make Object ID.
– Right-click the object ID variable and choose Add Watch.



Tip # 4 – View return values for functions
In order to view return values for your functions, look at the functions that appear in the Autos window to see the return value for a function, make sure that the function you are interested in has already executed.



Tip # 5 – Format your string in a visualizer
When working with strings, it can be helpful to view the entire formatted string. To view a plain text, XML, HTML, or JSON string, click the magnifying glass icon Visualizer Icon while hovering over a variable containing a string value.

Tip # 6 – Manage breakpoints
In VS when we set-up some breakpoints and now we need to switch one-off for as it’s getting hit too much but we will need it again for debugging. If we remove the break-point we’ll have to come back and find it again. So instead of removing the break-point we can use Break-point window. This window will show all breakpoints you have set but crucially lets you disable them without un-setting them by simply removing the check-mark. Check it again to re-enable it.

Tip # 7 – Break into code on handled exceptions
The debugger breaks into your code on unhandled exceptions. However, handled exceptions can also be a source of bugs and you may want to investigate when they occur. We can configure the debugger to break into code for handled exceptions as well by configuring options in the Exception Settings dialog box. Open this dialog box by choosing Debug > Windows > Exception Settings. Also in the dialog box window you can search your relevant exception in which you want to break the code when exception occur.







Reference Link: 
1- Tips & Trick to debug in visual studio
2- Visual Studio Debugging Tips That Will Lighten Your Load

Get Last Selected Value on Form Control


Problem: Store last selection in the form by user

There was a requirement to store user’s last selection on the form – i.e. the site selected last time should be populated automatically when the user opens the same form again. So if the user selected siteInventory details inquiry Dynamics AX “E” the form should remember it the next time.

Solution: We can solve this problem by implementing standard Ax syslastvalue/Pack-Unpack methods. Here we store the value in variable for current user session and based on user, current extension etc. To develop this functionality add the following code on the form.

Code: Add these methods on the form and it will start working:

//class declaration

public class FormRun extends ObjectRun

{

InventSiteId                    site;

#define.CurrentVersion(1)

#localmacro.CurrentList

site

#endmacro

}

//pack

public container pack()

{

return [#CurrentVersion,#CurrentList];

}

// Unpack

public boolean unpack(container packedClass)

{

int version;

;

version = RunBase::getVersion(packedClass);

if(version)

{

[version,#CurrentList] = packedClass;

return true;

}

return false;

}

//Site sysLastValue: This method is use to initialize default value

Public void initParmDefault()

{

;

site = “SiteA”;

}

//Site sysLastValue: This method is use to store dataAreaId for current user

public dataAreaId lastValueDataAreaId()

{

return curext();

}

//Site sysLastValue: This method returns the name of caller

public identifiername lastValueDesignName()

{

return element.args().menuItemName();

}

//Site sysLastValue: This method returns the name of form/object

public identifiername lastValueElementName()

{

return this.name();

}

//Site sysLastValue: This method returns the type of caller

public UtilElementType lastValueType()

{

return UtilElementType::Form;

}

//Site sysLastValue: This method returns the name of current user

public userId lastValueUserId()

{

return curuserid();

}

//Site sysLastValue: on form close save site value

public void close()

{

site = StringEditSiteId.valueStr();

xSysLastValue::saveLast(this);

super();

}

//Site sysLastValue: on run assign value to form control

public void run()

{

super();

//get the last value stored in cache

//here unpack method used

xSysLastValue::getLast(this);

//set the last user selection on the field- this is form control for siteId

StringEditSiteId.text(site);

}