Monday, January 27, 2020

Alert notification pop up and In user message center for custom/standard table in D365FO



///  class delivers the alerts notifications to user for custom tables
class BRUEventNotification_Test extends EventNotification
{
    SysIMailerNonInteractive mailer;
    Email        senderEmailAddress;

    public EventInboxId create()
    {
        SysUserInfo     userInfo;

        super();

        // send mail as well if enabled.
        userInfo = SysUserInfo::find(inbox.UserId);
        if (userInfo && userInfo.EventWorkflowTasksInEmail)
        {
            if (SysEmailDistributor::validateEmail(userInfo.emailDisplay()))
            {
                inbox.SendEmail = true;
                inbox.EmailRecipient = userInfo.emailDisplay();
                this.sendMail();
            }
        }

        inbox.AlertCreatedDateTime = DateTimeUtil::newDateTime(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()),DateTimeUtil::getTimeNow(DateTimeUtil::getUserPreferredTimeZone()),DateTimeUtil::getUserPreferredTimeZone());
        inbox.update();
        this.addPopupNotification(inbox, SysUserInfo::find(inbox.userId).EventPollFrequency, 30,this.ParmMenuFunction().name(),MenuItemType::Display,this.ParmRecord().RecId);//To get alert in to message center
        return inbox.InboxId;
    }

    private void addPopupNotification(EventInbox _inbox, int _reminderInterval, int _addDays, MenuItemName _menuItemName, MenuItemType _menuItemType, Int64 _recId)
    {
        SystemNotificationDataContract ndc = new SystemNotificationDataContract();
        Array actions = new Array (Types::Class);
        Array userList = new Array(Types::String);

        // create the message to be displayed in the message center
        userList.value(1, _inbox.UserId);

        ndc.Message(_inbox.Message);
        ndc.Title(_inbox.Subject);
        ndc.RuleId(_inbox.RuleId);
        ndc.Type(SystemNotificationType::Alert);
        ndc.State(SystemNotificationState::Active);
        ndc.Severity(SystemNotificationSeverity::Informational);
        ndc.Users(userList);
        ndc.ReminderInterval(_reminderInterval);
        ndc.ExpirationDateTime(DateTimeUtil::addDays(DateTimeUtil::utcNow(), _addDays));

        if (_menuItemName)
        {
            // create the hyperlink to the form
            SystemNotificationActionDataContract adc = new SystemNotificationActionDataContract();
            userList.value(1, _inbox.UserId);
            adc.Message(_inbox.AlertedFor);
            if (_menuItemType == MenuItemType::Action)
            {
                adc.Type(SystemNotificationActionType::AxActionMenuFunction);
            }
            else
            {
                // if it isn't an action menu item, assume display
                adc.Type(SystemNotificationActionType::AxDisplayMenuFunction);
            }

            SystemNotificationMenuFunctionDataContract notificationActionData = new SystemNotificationMenuFunctionDataContract();
            notificationActionData.MenuItemName(_menuItemName);
            notificationActionData.Data(int642Str(_recId));
            adc.Data(FormJsonSerializer::serializeClass(notificationActionData));
            actions.value(1,adc);
            ndc.Actions(actions);
        }

        // add to the Message center
        SystemNotificationsManager::AddNotification(ndc);
    }

    protected void new()
    {
        super();
        inbox.NotificationSource = EventNotificationSource::Alerts;
    }

    protected Email senderEmailAddress()
    {
        SysUserInfo     sysUserInfo;

        if (! senderEmailAddress)
        {
            // get the sender email address
            sysUserInfo = SysUserInfo::find(curuserid());
            senderEmailAddress = sysUserInfo.emailDisplay();

            // set senderEmail = toEmail
            if (! senderEmailAddress)
            {
                sysUserInfo         = SysUserInfo::find(inbox.UserId);
                senderEmailAddress  = sysUserInfo.emailDisplay();
            }
        }

        return senderEmailAddress;
    }

    protected void sendMail()
    {
        #define.mailPriority(1)

        super();

        if (mailer == null)
        {
            mailer = SysMailerFactory::getNonInteractiveMailer();
        }

        if (mailer != null
            && SysEmailDistributor::validateEmail(this.senderEmailAddress()))
        {
            try
            {
                var messageBuilder = new SysMailerMessageBuilder();
                messageBuilder.setFrom(this.senderEmailAddress(), "@SYS115063")
                              .setSubject(inbox.Subject)
                              .addTo(inbox.EmailRecipient)
                              .setPriority(#mailPriority)
                              .setBody(strReplace(inbox.Message, '\r\n', '<br>'));
                mailer.sendNonInteractive(messageBuilder.getMessage());
            }
            catch
            {
                warning(strfmt("@SYS324464",inbox.EmailRecipient));
                mailer = null;
            }
        }
    }

    protected static BRUEventNotification_Test construct()
    {
        return new BRUEventNotification_Test();
    }

    public static BRUEventNotification_Test newStandard(
        userId                  _userId,
        EventSubject            _subject,
        EventMessage            _message,
        EventNotificationType   _eventNotificationType,
        Common                  _record)
    {
        BRUEventNotification_Test  notification = BRUEventNotification_Test::construct();
        MenuFunction    getmenuFunction;
        getmenuFunction = new MenuFunction(menuitemdisplaystr(TestTableDetails),MenuItemType::Display);
        notification.parmUserId(_userId);
        notification.parmSubject(_subject);
        notification.parmMessage(_message);
        notification.parmNotificationType(_eventNotificationType);
        notification.parmRecord(_record);
        notification.parmDataSourceName(tableId2Name(tableNum(TestTable)));
        notification.parmMenuFunction(getmenuFunction);

        return notification;
    }

}

Monday, October 28, 2019

Restore .bacpac file to DEV VM D365 FO


Restore .bacpac file to Development VM

Steps:

1.       Take Backup of AxDB database from Development VM

2.       Open Command Prompt (Run as Administrator)



Go To Path (Version Folder might be differ, SQL)

cd "C:\Program Files (x86)\Microsoft SQL Server\140\DAC\bin"



C:\Program Files (x86)\Microsoft SQL Server\140\DAC\bin>

3.       Command to Execute



SqlPackage.exe /a:import /sf:C:\TEMP\VWD365FUT3backup.bacpac /tsn:localhost /tdn:AxDB_ENV_DDMMYYYY /p:CommandTimeout=1200



Note: Process will take some more time



4.       Open SQL, Run this below script

CREATE USER axdeployuser FROM LOGIN axdeployuser EXEC sp_addrolemember 'db_owner', 'axdeployuser' CREATE USER axdbadmin FROM LOGIN axdbadmin EXEC sp_addrolemember 'db_owner', 'axdbadmin' CREATE USER axmrruntimeuser FROM LOGIN axmrruntimeuser EXEC sp_addrolemember 'db_datareader', 'axmrruntimeuser' EXEC sp_addrolemember 'db_datawriter', 'axmrruntimeuser' CREATE USER axretaildatasyncuser FROM LOGIN axretaildatasyncuser EXEC sp_addrolemember 'DataSyncUsersRole', 'axretaildatasyncuser' CREATE USER axretailruntimeuser FROM LOGIN axretailruntimeuser EXEC sp_addrolemember 'UsersRole', 'axretailruntimeuser' EXEC sp_addrolemember 'ReportUsersRole', 'axretailruntimeuser' CREATE USER axdeployextuser FROM LOGIN axdeployextuser EXEC sp_addrolemember 'DeployExtensibilityRole', 'axdeployextuser' CREATE USER [NT AUTHORITY\NETWORK SERVICE] FROM LOGIN [NT AUTHORITY\NETWORK SERVICE] EXEC sp_addrolemember 'db_owner', 'NT AUTHORITY\NETWORK SERVICE' UPDATE T1 SET T1.storageproviderid = 0 , T1.accessinformation = '' , T1.modifiedby = 'Admin' , T1.modifieddatetime = getdate() FROM docuvalue T1 WHERE T1.storageproviderid = 1 --Azure storage DROP PROCEDURE IF EXISTS SP_ConfigureTablesForChangeTracking DROP PROCEDURE IF EXISTS SP_ConfigureTablesForChangeTracking_V2 GO -- Begin Refresh Retail FullText Catalogs DECLARE @RFTXNAME NVARCHAR(MAX); DECLARE @RFTXSQL NVARCHAR(MAX); DECLARE retail_ftx CURSOR FOR SELECT OBJECT_SCHEMA_NAME(object_id) + '.' + OBJECT_NAME(object_id) fullname FROM SYS.FULLTEXT_INDEXES WHERE FULLTEXT_CATALOG_ID = (SELECT TOP 1 FULLTEXT_CATALOG_ID FROM SYS.FULLTEXT_CATALOGS WHERE NAME = 'COMMERCEFULLTEXTCATALOG'); OPEN retail_ftx; FETCH NEXT FROM retail_ftx INTO @RFTXNAME; BEGIN TRY WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Refreshing Full Text Index ' + @RFTXNAME; EXEC SP_FULLTEXT_TABLE @RFTXNAME, 'activate'; SET @RFTXSQL = 'ALTER FULLTEXT INDEX ON ' + @RFTXNAME + ' START FULL POPULATION'; EXEC SP_EXECUTESQL @RFTXSQL; FETCH NEXT FROM retail_ftx INTO @RFTXNAME; END END TRY BEGIN CATCH PRINT error_message() END CATCH CLOSE retail_ftx; DEALLOCATE retail_ftx; -- End Refresh Retail FullText Catalogs

ALTER DATABASE [<your AX database name>] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 6 DAYS, AUTO_CLEANUP = ON) GO

5.       Stop following services

a.       Management Reporter 2012 process Service

b.      Microsoft Dynamics 365 Unified Operations: Batch Management Service

c.       World Wide Web Publishing Service

6.       Rename DB

a.       AxDB to AxDB_Orig

b.      AxDB_DDMMYYYY (New Restored DB) to AxDB

Use Script

USE master; 
GO 
ALTER DATABASE AxDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE AxDB MODIFY NAME = AxDB_orig ;
GO 
ALTER DATABASE AxDB_orig SET MULTI_USER
GO


USE master; 
GO 
ALTER DATABASE <Restore DB name> SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE <Restore DB name> MODIFY NAME = AxDB ;
GO 
ALTER DATABASE AxDB SET MULTI_USER
GO
THis is one

7.       Start following services

a.       Management Reporter 2012 process Service

b.      Microsoft Dynamics 365 Unified Operations: Batch Management Service

c.       World Wide Web Publishing Service

d.      Start IIS website from IIS manager


Build Model and Sync DB


Open DEV URL and check once



Ref: https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/database/dbmovement-scenario-exportuat

Export label custom content

 GRID => Properties "Export Label" => "SalesReportMexico" To get download file with custom naming.