Tuesday, July 1, 2025

"Your connection isn't private" error, specifically with the code net::ERR_CERT_DATE_INVALID, on the D365FO environment


 







To fix the issue:

  1. 1. Access LCS:
    Log in to your Lifecycle Services (LCS) project and locate the cloud-hosted environment.
  2. 2. Navigate to Maintain:
    Under the "Maintain" tab, find and select the "Rotate secrets" option.


  3. 3. Rotate SSL Certificate:
    Choose "Rotate SSL certificate" and confirm the action. This process will restart your environment.










  4. 4. Monitor Progress:
    The operation will be displayed in LCS and may take some time to complete. You can monitor its progress in the environment details.



  5. 5. Verify Access:
    Once the operation is complete and the environment is back online, try accessing the D365FO instance again. 
Important Note: Rotating SSL certificates will restart your environment, so ensure you save any unsaved work before initiating this process. 

Thursday, July 18, 2024

Label D365FO cloud environments using extensions

In D365FO Developers, Testers, key users, functional consultants will work on multiple environments. It is very important to them to differentiate and which environments they are working on.

Using below Extensions, you can enter the URL of specific cloud environments, for example to separate PROD environments from TEST environments like in the attached image.

Chrome: https://chromewebstore.google.com/detail/environment-marker/ahjhdebcnlgmojdmjnhikhakkghcchkk

Edge: https://microsoftedge.microsoft.com/addons/detail/environment-marker/iggchogopggbmjgplniemfaghmdkhlip






Wednesday, July 3, 2024

Copy args value to variable

CopyArgs() method will copy args value from one args to another variable 


 private void run(Args _args)

{

    Args salesArgs  = Args::copyArgs(_args, new Args());

    Args projArgs   = Args::copyArgs(salesArgs, new Args());

    Map  dataSourceValidRecs = new Map(extendedTypeId2Type(extendedTypeNum(RecId)), Types::Record);

    

    if (FormDataUtil::getFormDataSource(salesArgs.record()))

    {

        FormDataSource formDataSource_ds = FormDataUtil::getFormDataSource(salesArgs.record());


        for (Common common = formDataSource_ds.getFirst(true) ? formDataSource_ds.getFirst(true) : formDataSource_ds.cursor();

            common;

            common = formDataSource_ds.getNext())

        {

            WHSPostPackingSlipAction postPackingSlipAction = this.constructPostPackingSlipAction(common, salesArgs);


            if (postPackingSlipAction.validateCanPackingSlipBePosted())

            {

                this.determinePackingSlipTypes(postPackingSlipAction.whsPackingSlipType());


                dataSourceValidRecs.insert(common.RecId, common);

            }

        }

    }

}

Monday, June 24, 2024

Check Security Privilege is assigned or not for that User iusing X++

 

Below method will help to check security Privileges assigned for that user.

public static boolean hasUserSecurityPrivilege(SecurityPrivilegeName _securityPrivilege, UserId _userId = curUserId())

{

  SecurityRolePrivilegeExplodedGraph securityRolePrivilegeExplodedGraph;

  SecurityUserRole securityUserRole;

  SecurityPrivilege securityPrivilege;

  select firstonly securityPrivilege

    where securityPrivilege.Identifier == _securityPrivilege

  exists join securityRolePrivilegeExplodedGraph

    where securityRolePrivilegeExplodedGraph.SecurityPrivilege == securityPrivilege.RecId

  exists join securityUserRole

    where securityUserRole.SecurityRole == securityRolePrivilegeExplodedGraph.SecurityRole

       && securityUserRole.User == _userId

       && securityUserRole.AssignmentStatus == RoleAssignmentStatus::Enabled

       && (securityUserRole.ValidFrom < DateTimeUtil::utcNow() || securityUserRole.ValidFrom == utcDateTimeNull())

       && (securityUserRole.ValidTo > DateTimeUtil::utcNow() || securityUserRole.ValidTo == utcDateTimeNull());

  return securityPrivilege.RecId != 0;

}


Orelse you can use below method also with dummy control in form

Logic to implement user has specific privilege through code:

Created one dummy form control with visibility false and need permission manual and created privilege using below logic we can verify the access.

SecurityRights securityRights = SecurityRights::construct();

        maxAccess = securityRights.formControlAccessRight(formStr(SalesTable), formControlStr(SalesTable, QTQSalesStatus));

=============

verify user has specific role assigned or not.

if (xUserInfo::checkUserRole(roleStr(InventMaterialsManager))

            || xUserInfo::checkUserRole(roleStr(InventQualityControlManager)) 

            || xUserInfo::checkUserRole(roleStr(WMSWarehouseManager)) 

            || Global::isSystemAdministrator()) 


Wednesday, October 18, 2023

Shrink log D365FO log file

 Shrink log D365FO log file 

Select DB -> Right click -> Tasks -> Shrink -> Files

select file type as "Log".

Note down the value of file name.




Right click the Database -> New query -> Execute below query.

       ALTER DATABASE AXDB

        SET RECOVERY SIMPLE

        GO

      -- DBCC SHRINKFILE (filename , 1)

        DBCC SHRINKFILE ('AXDB-17Mar_log', 1)

        GO

        ALTER DATABASE AXDB

        SET RECOVERY FULL


** replace your file name

Tuesday, September 26, 2023

Restore/move D365 database

 Restore data base from same tenant (company)


1. Open as Administrator PowerShell
Install if not installed d365fo tools in power shell
- Install-Module -Name d365fo.tools
- Invoke-D365InstallSqlPackage

2. Restore database
if BACPAC file
in powershell
- Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\CLI TEST1backup.bacpac" -NewDatabaseName "AxDB_20211104" -ShowOriginalProgress

if BAK file go to Microsoft SQL Server Management Studio
Databases node / Right click / Restore Database...
General / Source / Device / click ... button
Click add button select BAK file and click OK and then again OK
Destination / Database change to AxDB_20211104 (date)
Files page (at right)
make sure that Restore As columnt has different files from Original File Name, change from AXDB_FromProdRep1 to AXDB_20211104_FromProdRep1, both lines
Click OK to start process

3. Stop environment
powershell
- Stop-D365Environment
Open IIS manager / Application Pools / AOSService / stop
Close all visual studio. Re open visual studio. Check tray for IISExpress. Right click in tray and Exit

4. Switch databases
In powershell
- Switch-D365ActiveDatabase -SourceDatabaseName "AxDB_20211104" -DestinationSuffix "_old"
Where _old is postfix for currently used AxDB, it will be called AxDB_old

5. Start environment
In powershell
- Start-D365Environment
Open IIS manager / Application Pools / AOSService / start
Close all visual studio. Re open visual studio.
Dynamics 365 / Synchronize database...

For tier2 environments like UAT it is possible to do it from LCS:
Open full environment details
Maintain / Move database
Export database - fill create BACPAC file and upload it to LCS
Import database - will import database from BACPAC file from LCS

To take backups in Microsoft SQL Server Management Studio
Righr click on data base Tasks / Back Up...
Back up type : Full
Destination / Back up to: Disk
Files - change the file name of back up for example AxDB_20211103.bak
Backup Options: Compression can be enabled - Set backup compression: Compress backup. LCS has limit of 14 Gb to upload. Therefore might be usefull.
Also shrink DB might be used: https://daxonline.org/1734-axdb-shrink.html

D365FO documentation:
https://github.com/d365collaborative/d365fo.tools/tree/development/docs

BAK/BACKBAK difference:
https://www.sqlservercentral.com/forums/topic/diff-between-bak-and-backpac-files

Monday, August 28, 2023

Synchornize the D365FO database using command prompt

 K:\AosService\PackagesLocalDirectory\Bin\SyncEngine.exe -syncmode=fullall -metadatabinaries=K:\AosService\PackagesLocalDirectory -connect="Data Source=localhost;Initial Catalog=AxDB;Integrated Security=True;Enlist=True;Application Name=SyncEngine" -fallbacktonative=False -verbosity=Diagnostic