error : DNS Lookup Failed when open EP pages from another computer

Problem :

Capture

I tried to ping with Sharepoint Server IP and got response, but i cant ping with computer name. The EP itself is working fine if i open it on another computer that already joined domain.

temporary solution :
just go to drive “C:\Windows\System32\drivers\etc”
on file “Hosts” , add
example xxx.xxx.xxx.xx COMPUTERNAME
Capture

or you can set use IP on sharepoint at alternate access mapping menu :
Capture20

Filter DataSets Field Lookup Enterprise Portal example code

on AOT datasets fields method, add this code below :

void dataSetLookup(SysDataSetLookup sysDataSetLookup)
{
    List list = new List(Types::String);
    Query query = new Query();

    // Add the table to the query.
    query.addDataSource(tableNum(HcmLeaveType));

    //filter query
    query.dataSourceTable(tableNum(HcmLeaveType)).addRange(fieldNum(HcmLeaveType,ValidToCredit)).value(SysQuery::value(NoYes::Yes));

    /* uncomment if the relation is not based on reference recid
    // Specify the fields to use for the lookup.
    list.addEnd(fieldStr(HcmLeaveType,LeaveTypeId));
    list.addEnd(fieldStr(HcmLeaveType,Description));

    // Supply the set of lookup fields.
    sysDataSetLookup.parmLookupFields(list);

    // Specify the field that is returned from the lookup.
    sysDataSetLookup.parmSelectField(fieldStr(HcmLeaveType,LeaveTypeId));
    sysDataSetLookup.parmHideSelectField(true);
    */ 

    // Pass the query to the SysDataSetLookup so that the query is used.
    sysDataSetLookup.parmQuery(query);
}

preview after lookup filtered by code :
Capture

reference on MSDN :
https://msdn.microsoft.com/en-us/library/hh830903.aspx

Step by step deploying AX ListPage form to Enterprise portal

Listpage type form on ax can be deploy directly to enterprise portal.

And steps below show you how to do it :
1. Do incremental CIL first before deploy
2. On menu item display, right click on it and select deploy to EP and select module.
Capture

3. After deploy, AX will create two web object on AOT, WebUrls (Web -> Web Menu Items -> Web URLs) and Web Page Definition (Web -> Web Files -> Web Page Definition)
Capture

4. On Web Page Definitions properties “Module”, add submodule if you want to add this listpage on subModule on Enterprise portal , then right click on it select Deploy element.
Capture

5. On Web URLs properties URL , add submodule same as page definition (optional), then right click on it and select import page
Capture

6. Restart IIS
https://hellodax.com/2015/05/22/restart-iis-command-prompt/

7. Clear AOT cache
Capture

8. To check the newly added custom webcontrol, just copy paste your Default Enterprise portal URLS (System Administration -> Setup -> Enterprise portal -> Websites) and webcontrol urls (from Web Urls Properties) to web browser.

default enterprise portal urls :
Capture

full urls on web browser :
Capture

another guide to add to quick launch sidebar :
https://hellodax.com/2015/05/22/add-new-custom-webparts-data-grid-to-enterprise-portal-quick-launch-sidebar-tutorial/

Step by step to deploy newly added WebControl to Enterprise Portal AX 2012

Deploying newly added webcontrol is much complicated than deploying SSRS.
I hope microsoft will simplify it on the next version of AX.

note :
this guide below is only for newly addded webcontrols.
if you already done the steps below, and want to update your webpage by using webcontrol, just right click on web controls AOT, and select deploy. It will replace the old web page with the new web page.

here is the steps for deploying webcontrols :

1. deploy the webcontrol on aot (Web -> Web Files -> Web Controls) , right click and choose “Deploy”
Capture

2. then deploy Web Content Managed on aot (Web -> Web Content -> Managed) , and choose the module
Capture

3. after you deploy web content managed , you will get two new object on AOT,
Web Urls (Web -> Web Menu Items -> URLs), and Web Page Definition (Web -> Web Files -> Page Definitions) , Right click on web page definitions , select “Deploy Elements”, right clicks on web urls, and select “Import Pages”

Web page definitions
Capture

Web Ulrs
Capture

4. Restart di IIS with IISRESET on your sharepoint server , see the reference post below
https://hellodax.com/2015/05/22/restart-iis-command-prompt/

5. Clear cache for making sure the enterprise portal is displaying the newly added webparts. (on some cases you must generate Incremental CIL too)
Capture

6. To check the newly added custom webcontrol, just copy paste your Default Enterprise portal URLS (System Administration -> Setup -> Enterprise portal -> Websites) and webcontrol urls (from Web Urls Properties) to web browser.

default enterprise portal urls :
Capture

web control urls :
Capture

full urls on web browser :
Capture

another guide to add to quick launch sidebar :
https://hellodax.com/2015/05/22/add-new-custom-webparts-data-grid-to-enterprise-portal-quick-launch-sidebar-tutorial/

Visualize with ax data to ASP calendar COLOR highlight example code on Enterprise Portal C#

i’ll explain the code below on another day .
when we remove the highlights on calender with clicks, it will remove the data on ax
and do the same when we add highlights on calendar.

Preview :
Capture

on design

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="HRSUploadTimeSheet.ascx.cs" Inherits="HRSUploadTimeSheet" %>
<dynamics:AxDataSource ID="hrsScheduleRequestWorkerTmpDS" runat="server" 
    DataSetName="HRSScheduleRequestWorkerTmpDS" 
    ProviderView="HRSScheduleRequestWorkerTmp">
</dynamics:AxDataSource>
<dynamics:AxDataSource ID="HRSJmgProfileDayDS" runat="server" 
    DataSetName="HRSJmgProfileDayDS" 
    ProviderView="JmgProfileDay">
</dynamics:AxDataSource>

<dynamics:AxForm ID="AxForm1" runat="server">
    <dynamics:AxMultiColumn ID="AxMultiColumn1" runat="server">
        <dynamics:AxColumn ID="AxColumn1" runat="server">
            <dynamics:AxGridView ID="AxGridView1" runat="server" BodyHeight="" 
                DataKeyNames="ProfileId" DataMember="HRSScheduleRequestWorkerTmp" 
                DataSetCachingKey="09d6aa10-4163-4e45-9074-8449211996ae" 
                DataSourceID="hrsScheduleRequestWorkerTmpDS" EnableModelValidation="True" 
                AllowPaging="False" 
                onselectedindexchanged="AxGridView1_SelectedIndexChanged" 
                ShowFilter="False">
                <Columns>
                    <asp:TemplateField ConvertEmptyStringToNull="False" 
                        HeaderText="<%$ AxLabel:@SYS303656 %>" SortExpression="PersonnelNumber">
                        <ItemTemplate>
                            <asp:Label ID="PersonnelNumber" runat="server" Text='<%# Bind("PersonnelNumber") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <dynamics:AxBoundField DataField="Name" DataSet="HRSScheduleRequestWorkerTmpDS" 
                        DataSetView="HRSScheduleRequestWorkerTmp" SortExpression="Name">
                    </dynamics:AxBoundField>
                    <asp:TemplateField ConvertEmptyStringToNull="False" 
                        HeaderText="<%$ AxLabel:@SYS7607 %>" SortExpression="ProfileId">
                        <ItemTemplate>
                            <asp:Label ID="ProfileId" runat="server" Text='<%# Bind("ProfileId") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </dynamics:AxGridView>
        </dynamics:AxColumn>

         <dynamics:AxColumn ID="AxColumn2" runat="server">
            <asp:Calendar ID="Calendar1" runat="server" 
                                    OnPreRender="Calendar1_PreRender" 
                                    OnSelectionChanged="Calendar1_SelectionChanged" 
                                    ondayrender="Calendar1_DayRender" Height="226px" 
                    Width="427px">
            </asp:Calendar>
            <dynamics:AxGridView ID="AxGridView2" runat="server" BodyHeight="" 
                DataKeyNames="RecId" DataMember="JmgProfileDay" 
                DataSetCachingKey="a1fd011a-2d33-4680-a45d-c70b2dcaf863" 
                DataSourceID="HRSJmgProfileDayDS" EnableModelValidation="True"
                ondatabound="AxGridView2_databound" ShowFilter="False" AllowPaging="False"
                >
                <Columns>
                    <asp:TemplateField ConvertEmptyStringToNull="False" 
                        HeaderText="<%$ AxLabel:@SYS67221 %>" SortExpression="Color">
                        <ItemTemplate>
                            <asp:Label ID="Color" runat="server" Text='<%# Bind("Color") %>' Visible="false"></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField ConvertEmptyStringToNull="False" 
                        HeaderText="<%$ AxLabel:@SYS7607 %>" SortExpression="Profile">
                        <ItemTemplate>
                            <asp:Label ID="Profile" runat="server" Text='<%# Bind("Profile") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField ConvertEmptyStringToNull="False" HeaderText="Profile Key" 
                        SortExpression="HRSProfleKey">
                        <ItemTemplate>
                            <asp:Label ID="ProfileKey" runat="server" Text='<%# Bind("HRSProfleKey") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <dynamics:AxBoundField DataField="StartWorkTime" DataSet="HRSJmgProfileDayDS" 
                        DataSetView="JmgProfileDay" SortExpression="StartWorkTime">
                    </dynamics:AxBoundField>
                    <dynamics:AxBoundField DataField="EndWorkTime" DataSet="HRSJmgProfileDayDS" 
                        DataSetView="JmgProfileDay" SortExpression="EndWorkTime">
                    </dynamics:AxBoundField>
                </Columns>
            </dynamics:AxGridView>

        </dynamics:AxColumn>
    </dynamics:AxMultiColumn>
</dynamics:AxForm>

.cs file

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.DataVisualization.Charting;
using System.Web.UI.WebControls;
using Microsoft.Dynamics.Framework.Portal.UI.WebControls;
using Microsoft.Dynamics.Framework.Portal.UI.WebControls.WebParts;
using System.IO;
using System.Data.OleDb;
using System.Data;
using Proxy = Microsoft.Dynamics.Framework.BusinessConnector.Proxy;
using Microsoft.Dynamics.Framework.BusinessConnector.Session;
using System.Drawing;
using Microsoft.Dynamics.AX.Framework.Portal.Data;
using Microsoft.Dynamics.Framework.BusinessConnector.Adapter;


public partial class HRSUploadTimeSheet : System.Web.UI.UserControl
{
    private string profileId { get; set; }
    private string scheduleRequestId { get; set; }
    private string personnelNumber { get; set; }
    private Boolean canEdit { get; set; }

    Dictionary<DateTime, int> dict = new Dictionary<DateTime, int>();

    public Dictionary<DateTime, int> SelectedDates
    {
        get
        {
            if (ViewState["Dates"] == null)
            {
                dict.Add(DateTime.MaxValue.AddDays(-2), 0);
                ViewState["Dates"] = dict;
            }

            return (Dictionary<DateTime, int>)ViewState["Dates"];
        }
        set
        {
            ViewState["Dates"] = value;
        }
    }

    private ISession AxSession
    {
        get
        {
            AxBaseWebPart webPart = AxBaseWebPart.GetWebpart(this);
            return webPart == null ? null : webPart.Session;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        IAxaptaRecordAdapter currentRecord = AxBaseWebPart.GetWebpart(this).ExternalRecord;
        if (currentRecord != null)
        {
            string status = currentRecord.GetField("HRSRequestStatus").ToString();
            if (status != "0")
            {
                canEdit = false;
            }
            else
            {
                canEdit = true;
            }
            scheduleRequestId = currentRecord.GetField("ScheduleReqestId").ToString();
        }
        if (!IsPostBack)
        {
            getProfileIdAndPersonnelNumber(true);
            getCalendarDataFromAX();
        }
      
    }

    #region grid
    protected void AxGridView2_databound(object sender, EventArgs e)
    {
        for (int i = 0; i <= AxGridView2.Rows.Count - 1; i++)
        {
            Label colorTxt = (Label)AxGridView2.Rows[i].FindControl("Color");
            Color myColor = Color.FromArgb(Convert.ToInt32(colorTxt.Text));
            AxGridView2.Rows[i].Cells[0].BackColor = myColor;
        }

        getProfileIdAndPersonnelNumber(true);
        getCalendarDataFromAX();
        FilterRows();
   
    }

    protected void AxGridView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        getProfileIdAndPersonnelNumber();
        getCalendarDataFromAX();
        FilterRows();

    }

    protected void getProfileIdAndPersonnelNumber(Boolean isInit = false)
    {
        Label profileIdLbl;
        Label PersonnelNumberLbl;

        if (isInit)
        {
            profileIdLbl = (Label)AxGridView1.Rows[0].FindControl("ProfileId");
            PersonnelNumberLbl = (Label)AxGridView1.Rows[0].FindControl("PersonnelNumber");
        }
        else
        {
            profileIdLbl = (Label)AxGridView1.Rows[AxGridView1.SelectedIndex].FindControl("ProfileId");
            PersonnelNumberLbl = (Label)AxGridView1.Rows[AxGridView1.SelectedIndex].FindControl("PersonnelNumber");
        }
        profileId = profileIdLbl.Text;
        personnelNumber = PersonnelNumberLbl.Text;
    }

    protected void getCalendarDataFromAX()
    {
        SelectedDates.Clear();
        SelectedDates.Add(DateTime.MaxValue.AddDays(-2), 0);

        DateTime keyDate = System.DateTime.Now;
        int valueInt = 0;
        Microsoft.Dynamics.AX.ManagedInterop.Container axContainer;

        axContainer = (Microsoft.Dynamics.AX.ManagedInterop.Container)this.AxSession.AxaptaAdapter.CallStaticRecordMethod("HRSScheduleRequestWorkerTmp", "getDataScheduleByWorker", personnelNumber, scheduleRequestId);

        for (int i = 1; i <= axContainer.Count; i++)
        {
            if (i % 2 != 0)
            {
                keyDate = Convert.ToDateTime(axContainer.get_Item(i));
            }
            else
            {
                valueInt = Convert.ToInt32(axContainer.get_Item(i));
                if (SelectedDates.ContainsKey(keyDate))
                {
                    SelectedDates.Remove(keyDate);
                }

                SelectedDates.Add(keyDate, valueInt);

            }
        }

        ViewState["Dates"] = SelectedDates;
    }

    protected void ShowRows()
    {
        // Display all the rows
        foreach (GridViewRow row in AxGridView2.Rows)
        {
            row.Visible = true;
        }
    }

    protected void FilterRows()
    {
        ShowRows();
        string colProfileId;
        // Loop through the rows and apply the filter
        int i = 0;
        foreach (GridViewRow row1 in AxGridView2.Rows)
        {
            Label lblProfile = (Label)AxGridView2.Rows[i].FindControl("Profile");
            // Get the filter column values
            colProfileId = lblProfile.Text;

            // If the name, visit and discharge fields are not equal to "All" and not equal to the filter value then the row is hidden.
            if (colProfileId != profileId)
            {
                row1.Visible = false;
            }
            i++;
        }

    }

    #endregion

    #region calendar
    protected void Calendar1_PreRender(object sender, EventArgs e)
    {
        // Reset Selected Dates 
        Calendar1.SelectedDates.Clear();
        // Select previously Selected Dates 

        foreach (var dt in SelectedDates)
        {
            Calendar1.SelectedDates.Add(dt.Key);
            Color myColor = Color.FromArgb(Convert.ToInt32(dt.Value));
            Calendar1.SelectedDayStyle.BackColor = myColor;
        }

    }

    protected void Calendar1_SelectionChanged(object sender, EventArgs e)
    {
        if (canEdit)
        {
            getProfileIdAndPersonnelNumber();
            //Check if selected Date is in the saved list 
            // Remove the Selected Date from the saved list 
            if (SelectedDates.ContainsKey(Calendar1.SelectedDate))
            {
                SelectedDates.Remove(Calendar1.SelectedDate);
                //delete record in ax , call custom table static method
                this.AxSession.AxaptaAdapter.CallStaticRecordMethod("HRSScheduleRequestWorkerTmp", "deleteScheduleRequestWorker", personnelNumber, scheduleRequestId, Calendar1.SelectedDate.Date);
            }

            else
            {
                Label colorTxt = (Label)AxGridView2.Rows[AxGridView2.SelectedIndex].FindControl("Color");
                Label profileKey = (Label)AxGridView2.Rows[AxGridView2.SelectedIndex].FindControl("ProfileKey");
                SelectedDates.Add(Calendar1.SelectedDate, Convert.ToInt32(colorTxt.Text));
                //insert to ax , call custom table static method
                this.AxSession.AxaptaAdapter.CallStaticRecordMethod("HRSScheduleRequestWorkerTmp", "insertScheduleRequestWorker", personnelNumber, scheduleRequestId, Calendar1.SelectedDate.Date, profileId, profileKey.Text);
            }

            ViewState["Dates"] = SelectedDates;
        }
    }

    protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
    {
        if (e.Day.IsSelected == true)
        {
            int color = SelectedDates[e.Day.Date];
            Color myColor = Color.FromArgb(color);
            e.Cell.BackColor = myColor;
        }
    }

    #endregion
}

get return container from AX and iterate(loop) items example code EP (Enterprise Portal) C#

protected void getCalendarDataFromAX()
    {
        SelectedDates.Clear();

        DateTime keyDate = System.DateTime.Now;
        int     valueInt = 0;
        Microsoft.Dynamics.AX.ManagedInterop.Container axContainer;

        axContainer = (Microsoft.Dynamics.AX.ManagedInterop.Container)this.AxSession.AxaptaAdapter.CallStaticRecordMethod("HRSScheduleRequestWorkerTmp", "getDataScheduleByWorker", personnelNumber, "SCH-000001");

        for (int i = 1; i <= axContainer.Count; i++)
        {
            if (i % 2 != 0)
            {
                keyDate = Convert.ToDateTime(axContainer.get_Item(i));
            }
            else
            {
                valueInt = Convert.ToInt32(axContainer.get_Item(i));
                if (SelectedDates.ContainsKey(keyDate))
                {
                    SelectedDates.Remove(keyDate);
                }
            
                SelectedDates.Add(keyDate, valueInt);
              
            }
        }

        ViewState["Dates"] = SelectedDates;
    }

how to add custom DLL reference to resolve error “missing an assembly reference” on enterprise portal AX 2012

if you add custom DLL to your VS project. When you open up web page you will receive error “are you missing an assembly reference?”.

to resolve this issue.. just copy paste the custom dll to folder (Sharepoint Server) C:\inetpub\wwwroot\wss\VirtualDirectories\PORT_NUMBER\_app_bin .

do incremental CIL and reset IIS

Reset the IIS :
https://hellodax.com/2015/05/22/restart-iis-command-prompt/

Capture

example custom code submitManager class for both Rich Client and EP (Enterprise Portal) x++

differentiate the rich client and ep using the menu items name.
always remember to do INCREMENTAL CIL every time you modify any of workflow classses

public void submit(Args _args)
{
    WorkflowComment         note = "";
    WorkflowSubmitDialog    workflowSubmitDialog;
    WorkflowCorrelationId   workflowCorrelationId;
    recId                   recId;
    workflowTypeName        workflowTypeName = workflowtypestr("TIDEmploymentLeave");
    WorkflowComment         initialNote = "";
    HcmEmploymentLeave      HcmEmploymentLeave;
    FormDataSource          HcmEmploymentLeave_ds;
    EPWorkflowControlContext workflowControlContext;
    str                     menuItemName = _args.menuItemName();


    //from rich client
    if(menuItemName == menuitemactionstr(TIDEmploymentLeaveSubmitMenuItem) || menuItemName == menuitemActionStr(HRSLeaveCreditSubmitMenuItem))
    {
        // Workflow is starting from the Windows client. This can be determined
        // because the menu item for submitting the workflow on the Windows
        // client was chosen by the user.

        // Opens the submit to workflow dialog.
        workflowSubmitDialog = WorkflowSubmitDialog::construct(_args.caller().getActiveWorkflowConfiguration());
        workflowSubmitDialog.run();

        if (workflowSubmitDialog.parmIsClosedOK())
        {
            // Find what record from the Work Orders table is being submitted to workflow.
            recId = _args.record().RecId;

            // Get comments from the submit to workflow dialog.
            initialNote = workflowSubmitDialog.parmWorkflowComment();

            try
            {
                // Update the record in the FCMWorkOrders table that is being submitted to workflow.
                // The record is moved to the 'submitted' state.
                ttsBegin;
                HcmEmploymentLeave = _args.record();
                HcmEmploymentLeave.selectForUpdate(true);
                HcmEmploymentLeave.Status = HRSLeaveStatus::Submitted;
                HcmEmploymentLeave.update();
                // Activate the workflow.
                workflowCorrelationId = Workflow::activateFromWorkflowType(workflowTypeName, recId, initialNote, NoYes::No);

                 ttsCommit;

                // Updates the workflow button to diplay Actions instead of Submit.
                _args.caller().updateWorkflowControls();
            }

            catch(exception::Error)
            {
                info("Error on workflow activation.");
            }
        }
    }
    //from EP
    else
    {
         // Workflow is starting from Enterprise Portal.

         // Retrieve the workflow controller context from the arguments passed in.
         workflowControlContext = _args.caller();

         // Find what record from the Work Orders table is being submitted to workflow.
         recId = _args.record().RecId;

         // Get comments from the submit to workflow dialog.
         initialNote = workflowControlContext.getWorkflowComment();

        try
        {
            ttsBegin;
            workflowCorrelationId = Workflow::activateFromWorkflowType(workflowTypeName, recId, initialNote, NoYes::Yes);
            HcmEmploymentLeave = _args.record();
            HcmEmploymentLeave.selectForUpdate(true);
            HcmEmploymentLeave.Status = HRSLeaveStatus::Submitted;
            HcmEmploymentLeave.update();
            ttsCommit;
        }
        catch(exception::Error)
        {
            info("Error on workflow activation.");
        }
    }
}

error : Paging is not supported for queries that do not have an ordering property.

example error :
Capture

if you are using list page for EP,
at your list page interaction class on AX.

do override method initializeQuery and add sortbyfield like example below

public void initializeQuery(Query _query)
{

_query.dataSourceTable(tableNum(HRSBenefitEntitlement)).addOrderByField(fieldNum(HRSBenefitEntitlement,Employment));
    super(_query);

}

do Incremental CIL after you modify the code.

error : The type or namespace name ‘Portal’ does not exist in the namespace ‘Microsoft.Dynamics’ (are you missing an assembly reference?)

i found this error when tried to edit and build solution for standard web control on visual studio.

Capture

how to resolve :
Right Click on your project and select add EP Proxy Project.
Capture

source :
https://msdn.microsoft.com/en-us/library/gg846077.aspx

error : Data or calculated fields with type ‘Record’ are not supported. EP AX 2012

found error : Data or calculated fields with type ‘Record’ are not supported when open custom page on Enterprise Portal.

the reason behind is because the DISPLAY method on table datasource or related table on AX is returning record.

example the error cause :
Capture

Add new custom webparts (Data Grid) to Enterprise Portal Quick Launch sidebar tutorial

This is step by step to create custom webparts and added it to Enterprise Portal (EP)
1. at Visual Studio, add new EP VS Project
Capture

2. Right click at the solution project, and click add new item, select Microsoft Dynamics Ax -> EP User Control with form and grid.
Capture

3. Go to AOT, add new data set , then add datasource, link it to your table , do compile and do INCREMENTAL CIL.
Capture

4. Go back to VS, refresh schema for the datasource, and select your newly created datasource
Capture

5. Make sure your column etc are inside axForm, fill the properties DataKeyNames,DataMember and DataSourcesID
Capture

6. at gridview, select datasource, and edit colomn, select field you want to show on the grid
Capture

7. right click on VS solution project, and choose “Add your_webParts to AOT”
Capture

8. go back to AOT, on Web -> Web Content -> Managed , find your webcontrol, right click on it, and Deploy to EP, then choose which module this webcontrol belongs to. After you deploy it , AX will create an URL Menu Item automatically at (Web -> Web Menu Items -> URLs) and Page Definition (Web -> Web Files -> Page Definition
Capture

9. If your menu is on submenu of the module, example Home\EmployeeServices\ManageTime , just change it on properties “Web Module” at Page Definition. and change the url on on web url properties
Capture
Capture

10. The next step is we want to add newly web parts to EP Quick Launch. Find the page you want to customize on “Web Modules” on AOT, on the properties, look at value of properties “Quick Launch”
Capture

10. Go to Web -> Web Menus , find the Quick Launch, and drag and drop the newly add url menu item to Quick Launch Menu, then deploy the EP from System Admin -> Setup -> Enterprise Portal -> Deployment
Capture

11. go to Web -> Web Modules . just right click and deploy on the module you customize.
Capture

12. Last, restart IIS for refreshing the EP with newest customize, with command prompt see post :
https://hellodax.com/2015/05/22/restart-iis-command-prompt/
Capture

13. Preview
Capture

Restart IIS command prompt

To restart IIS using the IISReset command-line utility
1.From the Start menu, click Run.
2.In the Open box, type cmd, and click OK.
3.At the command prompt, type iisreset /noforce computername, and press ENTER.
4.IIS attempts to stop all services before restarting. The IISReset command-line utility waits up to one minute for all services to stop. If the services cannot be stopped within one minute, all IIS services are terminated, and IIS restarts.

example :
Capture

source :
https://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/003ed2fe-6339-4919-b577-6aa965994a9b.mspx?mfr=true

Init field value from datasource , show on Enterprise Portal AXBoundField

on AOT dataset method init() :
Capture

X++ code on init method example:

public void init()
{
    super();
    DNLLeaveRequest.DNLEmplRecId  = DNLEmployeeTable::findByUserId().RecId;
    DNLLeaveRequest.LeaveDateFrom = today();
    DNLLeaveRequest.LeaveDateTo   = today();
}

or you can code it on Tables\initvalue()

XML code on visual studio for EP pages :

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TIDDNLLeaveRequestEP.ascx.cs" Inherits="TIDDNLLeaveRequestEP" %>
<dynamics:AxDataSource ID="AxDataSource1" runat="server" 
    DataSetName="TIDLeaveRequestDS" ProviderView="DNLLeaveRequest" 
    oninitializeddatasetrun="AxDataSource1_InitializedDataSetRun">
</dynamics:AxDataSource>
<dynamics:AxForm ID="AxForm1" runat="server" DataSourceID="AxDataSource1" 
    DataKeyNames="RecId,Added,AdvanceUsed,BlankLeave,carryused,ContactPhone,createdBy,createdDateTime,dataAreaId,DNLEmplRecId,DNLLeaveTypeRecId,IdApproval,IdPersonSubstitute,LeaveDateFrom,LeaveDateTo,modifiedBy,modifiedDateTime,Remarks,RequestDate,State,StatusFlag,SubmittedBy,SubmittedDateTime,TableId,TotalLeaveDays,TravellingLocation,getEmplName**,GetEntitlement**,getExpiration**,getLeaveDesc**,mostRecentComment**,requiredActionDueDate**,titleFields**" 
    DataMember="DNLLeaveRequest_Current" AutoGenerateInsertButton="True" 
    DefaultMode="Insert" UpdateOnPostBack="true" oninit="AxForm1_Init"  >
    <dynamics:AxMultiColumn ID="AxMultiColumn1" runat="server">
    
 
    
 
        <dynamics:AxColumn ID="AxColumn2" runat="server">
            <dynamics:AxGroup ID="groupLeaveRequest" runat="server" FormID="AxForm1" 
                Caption="Leave Request" CaptionAlign="Top" HorizontalAlign="Left" 
                Width="300px">
                <Fields>
                    <dynamics:AxReferenceBoundField DataField="DNLEmplRecId" 
                        DataSet="TIDLeaveRequestDS" DataSetView="DNLLeaveRequest" 
                        SortExpression="DNLEmplRecId" Mandatory="True">
                    </dynamics:AxReferenceBoundField>
                    <dynamics:AxReferenceBoundField AutoPostBack="True" 
                        DataField="DNLLeaveTypeRecId" DataSet="TIDLeaveRequestDS" 
                        DataSetView="DNLLeaveRequest" SortExpression="DNLLeaveTypeRecId" 
                        Mandatory="True">
                    </dynamics:AxReferenceBoundField>
                    <dynamics:AxBoundField AutoPostBack="True" DataField="LeaveDateFrom" 
                        DataSet="TIDLeaveRequestDS" 
                        DataSetView="DNLLeaveRequest" SortExpression="LeaveDateFrom">
                    </dynamics:AxBoundField>
                    <dynamics:AxBoundField AutoPostBack="True" DataField="LeaveDateTo" 
                        DataSet="TIDLeaveRequestDS" 
                        DataSetView="DNLLeaveRequest" SortExpression="LeaveDateTo" 
                        Mandatory="True" >
                    </dynamics:AxBoundField>
                    <dynamics:AxBoundField AutoPostBack="True" DataField="Remarks" 
                        DataSet="TIDLeaveRequestDS" DataSetView="DNLLeaveRequest" 
                        SortExpression="Remarks">
                    </dynamics:AxBoundField>
                    <dynamics:AxBoundField AutoPostBack="True" DataField="TotalLeaveDays" 
                        DataSet="TIDLeaveRequestDS" DataSetView="DNLLeaveRequest" 
                        SortExpression="TotalLeaveDays">
                    </dynamics:AxBoundField>
                    <dynamics:AxBoundField DataField="GetEntitlement**" DataSet="TIDLeaveRequestDS" 
                        DataSetView="DNLLeaveRequest" ReadOnly="True">
                    </dynamics:AxBoundField>
                </Fields>
            </dynamics:AxGroup>
        </dynamics:AxColumn>
    </dynamics:AxMultiColumn>
</dynamics:AxForm>

C# code on visual studio for EP pages

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.DataVisualization.Charting;
using System.Web.UI.WebControls;
using Microsoft.Dynamics.Framework.Portal.UI.WebControls;
using Microsoft.Dynamics.Framework.Portal.UI.WebControls.WebParts;
using Microsoft.Dynamics.AX.Framework.Portal.Data;
using Microsoft.Dynamics.AX.Framework.Services.Client;
using Microsoft.Dynamics.Framework.BusinessConnector.Session;
using Microsoft.Dynamics.Framework.BusinessConnector.Adapter;
using Microsoft.Dynamics.Framework.Portal;
using Microsoft.Dynamics.Framework.BusinessConnector.Proxy;

public partial class TIDDNLLeaveRequestEP : System.Web.UI.UserControl
{
    DateTime dateFrom;
    DateTime dateTo;
    Int64 recIdLeaveType;
   
    

    #region customMethod
    private ISession AxSession
    {
        get 
        {
            AxBaseWebPart webPart = AxBaseWebPart.GetWebpart(this);
            return webPart == null ? null : webPart.Session;
        }
    }
    static AxBoundField GetField(DataControlFieldCollection fields, string name)
    {
        foreach (DataControlField field in fields)
        {
            // Is this the field being searched for?
            AxBoundField boundField = field as AxBoundField;
            if (boundField != null && String.Compare(boundField.DataField, name, true) == 0)
            {
                return boundField;
            }

        }
        // Nothing found, so return null.
        return null;
    }

    private DataSetViewRow CurrentRow
    {
        get
        {
            try
            {
                DataSetView dataSetView;
                dataSetView = this.AxDataSource1.GetDataSet().DataSetViews["DNLLeaveRequest"];
                return (dataSetView == null) ? null : dataSetView.GetCurrent();
            }
            catch (System.Exception)
            {
                return null;
            }
        }
    }

    #endregion customMethod

    protected void AxForm1_Init(object sender, EventArgs e)
    {
        //this.loadFirst();
        this.AxForm1.DefaultMode = DetailsViewMode.Insert;
        this.AxForm1.AutoGenerateInsertButton = true;

        AxBoundField axbfNoNPK;
        axbfNoNPK = GetField(groupLeaveRequest.Fields, "DNLEmplRecId");
        axbfNoNPK.ReadOnly = true; 
    }


    protected void Page_Load(object sender, EventArgs e)
    {

    }
 
   
    protected void AxDataSource1_InitializedDataSetRun(object sender, AxDataSourceDataSetEventArgs e)
    {
        e.DataSet.Init();
    }
}

preview :
Capture