Page 5330 CRM Connection Setup

App
Base Application
Namespace
Microsoft.Integration.D365Sales
Versions
17-28
Source table
5330

Versions171819202122232425262728

Source29

Source in 29

src/Layers/W1/BaseApp/Integration/D365Sales/CRMConnectionSetup.Page.al825 lines, Copyright (c) Microsoft Corporation. MIT

// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Integration.D365Sales;

using Microsoft.Integration.Dataverse;
using Microsoft.Integration.SyncEngine;
using System.Environment;
using System.Environment.Configuration;
using System.Security.Encryption;
using System.Telemetry;
using System.Threading;
using System.Utilities;

page 5330 "CRM Connection Setup"
{
    AccessByPermission = TableData "CRM Connection Setup" = IM;
    ApplicationArea = Suite;
    Caption = 'Dynamics 365 Sales Integration Setup';
    DeleteAllowed = false;
    InsertAllowed = false;
    LinksAllowed = false;
    ShowFilter = false;
    SourceTable = "CRM Connection Setup";
    UsageCategory = Administration;
    AdditionalSearchTerms = 'Dynamics 365 Sales Connection Setup, CRM Connection Setup';

    layout
    {
        area(content)
        {
            group(NAVToCRM)
            {
                Caption = 'Connection from Dynamics 365 Business Central to Dynamics 365 Sales';
                field("Server Address"; Rec."Server Address")
                {
                    ApplicationArea = Suite;
                    Editable = IsEditable;

                    trigger OnValidate()
                    begin
                        ConnectionString := Rec.GetConnectionString();
                    end;
                }
                field("User Name"; Rec."User Name")
                {
                    ApplicationArea = Suite;
                    Editable = IsEditable;
                    Visible = IsUserNamePasswordVisible;

                    trigger OnValidate()
                    begin
                        ConnectionString := Rec.GetConnectionString();
                    end;
                }
                field(Password; CRMPassword)
                {
                    ApplicationArea = Suite;
                    Enabled = IsEditable;
                    ExtendedDatatype = Masked;
                    Visible = IsUserNamePasswordVisible;
                    ToolTip = 'Specifies the password of a Dynamics 365 Sales user account.';

                    trigger OnValidate()
                    begin
                        if (CRMPassword <> '') and (not EncryptionEnabled()) then
                            if Confirm(EncryptionIsNotActivatedQst) then
                                PAGE.RunModal(PAGE::"Data Encryption Management");
                        Rec.SetPassword(CRMPassword);
                    end;
                }
                field("Is Enabled"; Rec."Is Enabled")
                {
                    ApplicationArea = Suite;
                    Caption = 'Enabled', Comment = 'Name of tickbox which shows whether the connection is enabled or disabled';

                    trigger OnValidate()
                    var
                        AuditLog: Codeunit "Audit Log";
                        FeatureTelemetry: Codeunit "Feature Telemetry";
                        CDSIntegrationImpl: Codeunit "CDS Integration Impl.";
                        Dynamics365SalesEnabledLbl: Label 'Integration to Dynamics 365 Sales has been enabled by UserSecurityId %1.', Locked = true;
                    begin
                        CurrPage.Update(true);
                        if Rec."Is Enabled" then begin
                            FeatureTelemetry.LogUptake('0000H7A', 'Dynamics 365 Sales', Enum::"Feature Uptake Status"::"Set up");
                            Session.LogMessage('0000CM7', CRMConnEnabledOnPageTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
                            AuditLog.LogAuditMessage(StrSubstNo(Dynamics365SalesEnabledLbl, UserSecurityId()), SecurityOperationResult::Success, AuditCategory::ApplicationManagement, 4, 0);

                            if (Rec."Server Address" <> '') and (Rec."Server Address" <> TestServerAddressTok) then
                                if CDSIntegrationImpl.MultipleCompaniesConnected() then
                                    CDSIntegrationImpl.SendMultipleCompaniesNotification();
                        end;
                    end;
                }
                field(ScheduledSynchJobsActive; ScheduledSynchJobsRunning)
                {
                    ApplicationArea = Suite;
                    Caption = 'Active scheduled synchronization jobs';
                    Editable = false;
                    StyleExpr = ScheduledSynchJobsRunningStyleExpr;
                    ToolTip = 'Specifies how many of the default integration synchronization job queue entries ready to automatically synchronize data between Dynamics 365 and Dynamics 365 Sales.';

                    trigger OnDrillDown()
                    var
                        ScheduledSynchJobsRunningMsg: Text;
                    begin
                        if TotalJobs = 0 then
                            ScheduledSynchJobsRunningMsg := JobQueueIsNotRunningMsg
                        else
                            if ActiveJobs = TotalJobs then
                                ScheduledSynchJobsRunningMsg := AllScheduledJobsAreRunningMsg
                            else
                                ScheduledSynchJobsRunningMsg := StrSubstNo(PartialScheduledJobsAreRunningMsg, ActiveJobs, TotalJobs);
                        Message(ScheduledSynchJobsRunningMsg);
                    end;
                }
                field(SDKVersion; Rec."Proxy Version")
                {
                    ApplicationArea = Suite;
                    AssistEdit = true;
                    Caption = 'Dynamics 365 SDK Version';
                    Editable = false;
                    Enabled = IsProxyVersionEnabled;

                    trigger OnAssistEdit()
                    var
                        TempStack: Record TempStack temporary;
                    begin
                        if PAGE.RunModal(PAGE::"SDK Version List", TempStack) = ACTION::LookupOK then begin
                            Rec.Validate("Proxy Version", TempStack.StackOrder);
                            ConnectionString := Rec.GetConnectionString();
                            CurrPage.Update(true);
                        end;
                    end;
                }
            }
            group(CRMToNAV)
            {
                Caption = 'Connection from Dynamics 365 Sales to Dynamics 365 Business Central';
                Visible = Rec."Is Enabled";
                field(NAVURL; Rec."Dynamics NAV URL")
                {
                    ApplicationArea = Suite;
                    Caption = 'Dynamics 365 Business Central Web Client URL';
                    Enabled = Rec."Is CRM Solution Installed";
                }
            }
            group(CRMSettings)
            {
                Caption = 'Dynamics 365 Sales Settings';
                Visible = Rec."Is Enabled";
                field("CRM Version Status"; CRMVersionStatus)
                {
                    ApplicationArea = Suite;
                    Caption = 'Dynamics 365 Sales Version checked';
                    Editable = false;
                    StyleExpr = CRMVersionStyleExpr;
                    ToolTip = 'Specifies whether the version of Dynamics 365 Sales that you are connected to is valid.';

                    trigger OnDrillDown()
                    begin
                        if Rec.IsVersionValid() then
                            Message(FavorableCRMVersionMsg, CRMProductName.SHORT())
                        else
                            Message(UnfavorableCRMVersionMsg, PRODUCTNAME.Short(), CRMProductName.SHORT());
                    end;
                }
                field("Is CRM Solution Installed"; Rec."Is CRM Solution Installed")
                {
                    ApplicationArea = Suite;
                    Caption = 'Dynamics 365 Business Central Integration Solution Imported';
                    Editable = false;
                    StyleExpr = CRMSolutionInstalledStyleExpr;

                    trigger OnDrillDown()
                    begin
                        if Rec."Is CRM Solution Installed" then
                            Message(FavorableCRMSolutionInstalledMsg, PRODUCTNAME.Short(), CRMProductName.SHORT())
                        else
                            Message(UnfavorableCRMSolutionInstalledMsg, PRODUCTNAME.Short());
                    end;
                }
                field("Is S.Order Integration Enabled"; Rec."Is S.Order Integration Enabled")
                {
                    ApplicationArea = Suite;
                    Caption = 'Legacy Sales Order Integration Enabled';
                    Enabled = not IsBidirectionalSalesOrderIntegrationEnabled;

                    trigger OnValidate()
                    begin
                        SetAutoCreateSalesOrdersEditable();
                    end;
                }
                field("Auto Create Sales Orders"; Rec."Auto Create Sales Orders")
                {
                    ApplicationArea = Suite;
                    Caption = 'Automatically Create Sales Orders';
                    Editable = IsAutoCreateSalesOrdersEditable;
                }
                field("Auto Process Sales Quotes"; Rec."Auto Process Sales Quotes")
                {
                    ApplicationArea = Suite;
                    Caption = 'Automatically Process Sales Quotes';
                }
                field("Bidirectional Sales Order Int."; Rec."Bidirectional Sales Order Int.")
                {
                    ApplicationArea = Suite;
                    Caption = 'Bidirectional Sales Order Int.';
                    Editable = not IsAutoCreateSalesOrdersEditable;

                    trigger OnValidate()
                    var
                        CRMIntegrationManagement: Codeunit "CRM Integration Management";
                    begin
                        if Rec."Bidirectional Sales Order Int." then
                            if CRMIntegrationManagement.CheckSolutionVersionOutdated() then
                                if Confirm(InstallLatestSolutionConfirmLbl) then
                                    Rec.DeployCRMSolution(true)
                                else
                                    Error('');

                        CurrPage.Update();
                    end;
                }
            }
            group(AdvancedSettings)
            {
                Caption = 'Advanced Settings';
                field("Use Newest UI"; Rec."Use Newest UI")
                {
                    ApplicationArea = Suite;
                    Editable = Rec."Is Enabled";
                    Caption = 'Open Coupled Entities in Dynamics 365 Sales Hub';
                }
                field("Item Availability Enabled"; Rec."Item Availability Enabled")
                {
                    ApplicationArea = Suite;
                    Editable = Rec."Is Enabled";
                    Caption = 'Automatically Synchronize Item Availability';
                }
                field("Unit Group Mapping Enabled"; Rec."Unit Group Mapping Enabled")
                {
                    ApplicationArea = Suite;
                    Caption = 'Unit Group Mapping';
                    Editable = not Rec."Is Enabled";
                }
                label(Control30)
                {
                    ApplicationArea = Suite;
                    ShowCaption = false;
                    Caption = '';
                }
            }
            group(AuthTypeDetails)
            {
                Caption = 'Authentication Type Details';
                Visible = not SoftwareAsAService;
                field("Authentication Type"; Rec."Authentication Type")
                {
                    ApplicationArea = Advanced;
                    Editable = IsEditable;

                    trigger OnValidate()
                    begin
                        ConnectionString := Rec.GetConnectionString();
                    end;
                }
                field(Domain; Rec.Domain)
                {
                    ApplicationArea = Advanced;
                }
                field("Connection String"; ConnectionString)
                {
                    ApplicationArea = Advanced;
                    Caption = 'Connection String';
                    Editable = IsEditable;
                    ToolTip = 'Specifies the connection string that will be used to connect to Dynamics 365 Sales';

                    trigger OnValidate()
                    begin
                        Rec.SetConnectionString(ConnectionString);
                    end;
                }
            }
        }
    }

    actions
    {
        area(processing)
        {
            action("Assisted Setup")
            {
                ApplicationArea = Suite;
                Caption = 'Assisted Setup';
                Image = Setup;
                ToolTip = 'Runs Dynamics 365 Connection Setup Wizard.';

                trigger OnAction()
                var
                    GuidedExperience: Codeunit "Guided Experience";
                    CRMIntegrationMgt: Codeunit "CRM Integration Management";
                    GuidedExperienceType: Enum "Guided Experience Type";
                begin
                    CRMIntegrationMgt.RegisterAssistedSetup();
                    Commit(); // Make sure all data is committed before we run the wizard
                    GuidedExperience.Run(GuidedExperienceType::"Assisted Setup", ObjectType::Page, Page::"CRM Connection Setup Wizard");
                    CurrPage.Update(false);
                end;
            }
            action("Test Connection")
            {
                ApplicationArea = Suite;
                Caption = 'Test Connection', Comment = 'Test is a verb.';
                Image = ValidateEmailLoggingSetup;
                ToolTip = 'Tests the connection to Dynamics 365 Sales using the specified settings.';

                trigger OnAction()
                begin
                    Rec.PerformTestConnection();
                end;
            }
            action("Use Certificate Authentication")
            {
                ApplicationArea = Suite;
                Caption = 'Use Certificate Authentication';
                Image = Certificate;
                Visible = SoftwareAsAService;
                Enabled = Rec."Is Enabled";
                ToolTip = 'Upgrades the connection to Dynamics 365 Sales to use certificate-based OAuth 2.0 service-to-service authentication.';

                trigger OnAction()
                var
                    TempCDSConnectionSetup: Record "CDS Connection Setup" temporary;
                    CDSConnectionSetup: Record "CDS Connection Setup";
                    CDSIntegrationImpl: Codeunit "CDS Integration Impl.";
                    EmptySecretText: SecretText;
                begin
                    TempCDSConnectionSetup."Server Address" := Rec."Server Address";
                    TempCDSConnectionSetup."User Name" := Rec."User Name";
                    TempCDSConnectionSetup."Proxy Version" := CDSIntegrationImpl.GetLastProxyVersionItem();
                    TempCDSConnectionSetup."Authentication Type" := TempCDSConnectionSetup."Authentication Type"::Office365;
                    TempCDSConnectionSetup.Insert();
                    Commit();

                    CDSIntegrationImpl.SetupCertificateAuthentication(TempCDSConnectionSetup);

                    if (TempCDSConnectionSetup."Connection String".IndexOf('{CERTIFICATE}') > 0) and (TempCDSConnectionSetup."User Name" <> Rec."User Name") then begin
                        if CDSConnectionSetup.Get() then
                            if CDSConnectionSetup."Is Enabled" then begin
                                CDSConnectionSetup."User Name" := TempCDSConnectionSetup."User Name";
                                CDSConnectionSetup.SetPassword(EmptySecretText);
                                CDSConnectionSetup."Proxy Version" := TempCDSConnectionSetup."Proxy Version";
                                CDSConnectionSetup."Connection String" := TempCDSConnectionSetup."Connection String";
                                CDSConnectionSetup.Modify();
                            end;
                        Rec."User Name" := TempCDSConnectionSetup."User Name";
                        Rec.SetPassword(EmptySecretText);
                        Rec."Proxy Version" := TempCDSConnectionSetup."Proxy Version";
                        Rec.SetConnectionString(TempCDSConnectionSetup."Connection String");
                        CurrPage.Update(false);
                        Session.LogMessage('0000FB5', CertificateConnectionSetupTelemetryMsg, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
                        Message(StrSubstNo(CertificateConnectionSetupMsg, Rec."User Name"));
                    end;
                end;
            }
            action(IntegrationTableMappings)
            {
                ApplicationArea = Suite;
                Caption = 'Integration Table Mappings';
                Enabled = Rec."Is Enabled";
                Image = MapAccounts;
                ToolTip = 'Opens the integration table mapping list.';

                trigger OnAction()
                begin
                    Page.Run(Page::"Integration Table Mapping List");
                end;
            }
            action("Redeploy Solution")
            {
                ApplicationArea = Suite;
                Caption = 'Redeploy Integration Solution';
                Image = Setup;
                Enabled = IsCdsIntegrationEnabled and (not Rec."Is Enabled");
                ToolTip = 'Redeploy and reconfigure the Microsoft Dynamics 365 Sales integration solution.';

                trigger OnAction()
                begin
                    Commit();
                    Rec.DeployCRMSolution(true);
                end;
            }
            action(ResetConfiguration)
            {
                ApplicationArea = Suite;
                Caption = 'Use Default Synchronization Setup';
                Enabled = Rec."Is Enabled";
                Image = ResetStatus;
                ToolTip = 'Resets the integration table mappings and synchronization jobs to the default values for a connection with Dynamics 365 Sales. All current mappings are deleted.';

                trigger OnAction()
                var
                    CRMSetupDefaults: Codeunit "CRM Setup Defaults";
                begin
                    Rec.EnsureCDSConnectionIsEnabled();
                    if Confirm(ResetIntegrationTableMappingConfirmQst, false, CRMProductName.SHORT()) then begin
                        CRMSetupDefaults.ResetConfiguration(Rec);
                        Message(SetupSuccessfulMsg, CRMProductName.SHORT());
                    end;
                    Rec.RefreshDataFromCRM();
                end;
            }
            action(CoupleUsers)
            {
                ApplicationArea = Suite;
                Caption = 'Couple Salespeople';
                Image = CoupledUsers;
                ToolTip = 'Open the list of users in Dynamics 365 Sales to manually couple them to salespeople in Business Central.';

                trigger OnAction()
                var
                    CRMSystemuserList: Page "CRM Systemuser List";
                begin
                    CRMSystemuserList.Initialize(true);
                    CRMSystemuserList.Run();
                end;
            }
            action(StartInitialSynchAction)
            {
                ApplicationArea = Suite;
                Caption = 'Run Full Synchronization';
                Enabled = Rec."Is Enabled";
                Image = RefreshLines;
                ToolTip = 'Start all the default integration jobs for synchronizing Business Central record types and Dynamics 365 Sales entities, as defined on the Integration Table Mappings page.';

                trigger OnAction()
                begin
                    PAGE.Run(PAGE::"CRM Full Synch. Review");
                end;
            }
            action("Reset Web Client URL")
            {
                ApplicationArea = Suite;
                Caption = 'Reset Web Client URL';
                Enabled = IsWebCliResetEnabled;
                Image = ResetStatus;
                ToolTip = 'Undo your change and enter the default URL in the Business Central web Client URL field.';

                trigger OnAction()
                begin
                    Rec.PerformWebClientUrlReset();
                    Message(WebClientUrlResetMsg, PRODUCTNAME.Short());
                end;
            }
            action(SynchronizeNow)
            {
                ApplicationArea = Suite;
                Caption = 'Synchronize Modified Records';
                Enabled = Rec."Is Enabled";
                Image = Refresh;
                ToolTip = 'Synchronize records that have been modified since the last time they were synchronized.';

                trigger OnAction()
                var
                    IntegrationSynchJobList: Page "Integration Synch. Job List";
                begin
                    if not Confirm(SynchronizeModifiedQst) then
                        exit;

                    Rec.SynchronizeNow(false);
                    Message(SyncNowScheduledMsg, IntegrationSynchJobList.Caption)
                end;
            }
        }
        area(navigation)
        {
            action("Synch. Job Queue Entries")
            {
                ApplicationArea = Suite;
                Caption = 'Synch. Job Queue Entries';
                Image = JobListSetup;
                ToolTip = 'View the job queue entries that manage the scheduled synchronization between Dynamics 365 Sales and Business Central.';

                trigger OnAction()
                var
                    JobQueueEntry: Record "Job Queue Entry";
                begin
                    JobQueueEntry.FilterGroup := 2;
                    JobQueueEntry.SetRange("Object Type to Run", JobQueueEntry."Object Type to Run"::Codeunit);
                    JobQueueEntry.SetFilter("Object ID to Run", Rec.GetJobQueueEntriesObjectIDToRunFilter());
                    JobQueueEntry.FilterGroup := 0;

                    PAGE.Run(PAGE::"Job Queue Entries", JobQueueEntry);
                end;
            }
            action(SkippedSynchRecords)
            {
                ApplicationArea = Suite;
                Caption = 'Skipped Synch. Records';
                Enabled = Rec."Is Enabled";
                Image = NegativeLines;
                RunObject = Page "CRM Skipped Records";
                RunPageMode = View;
                ToolTip = 'View the list of records that will be skipped for synchronization.';
            }
            action(EncryptionManagement)
            {
                ApplicationArea = Advanced;
                Caption = 'Encryption Management';
                Image = EncryptionKeys;
                RunObject = Page "Data Encryption Management";
                RunPageMode = View;
                ToolTip = 'Enable or disable data encryption. Data encryption helps make sure that unauthorized users cannot read business data.';
            }
            action(RebuildCouplingTable)
            {
                ApplicationArea = Suite;
                Caption = 'Rebuild Coupling Table';
                Enabled = true;
                Image = Restore;
                ToolTip = 'Rebuilds the coupling table after Cloud Migration from Business Central 2019 Wave 1 (Business Central 14).';

                trigger OnAction()
                var
                    CDSIntegrationImpl: Codeunit "CDS Integration Impl.";
                begin
                    CDSIntegrationImpl.ScheduleRebuildingOfCouplingTable();
                end;
            }
            action(FieldServiceIntegrationApp)
            {
                ApplicationArea = Suite;
                Caption = 'Field Service Integration App';
                Image = Setup;
                Visible = SoftwareAsAService;
                ToolTip = 'Go to Microsoft AppSource to get the Field Service Integration app. The app will let you integrate Dynamics 365 Field Service with Business Central.';

                trigger OnAction()
                var
                    CRMIntegrationManagement: Codeunit "CRM Integration Management";
                begin
                    Hyperlink(CRMIntegrationManagement.GetFieldServiceIntegrationAppSourceLink());
                end;
            }
        }
        area(Promoted)
        {
            group(Category_Process)
            {
                Caption = 'Connection', Comment = 'Generated from the PromotedActionCategories property index 1.';

                actionref("Assisted Setup_Promoted"; "Assisted Setup")
                {
                }
                actionref("Test Connection_Promoted"; "Test Connection")
                {
                }
                actionref("Use Certificate Authentication_Promoted"; "Use Certificate Authentication")
                {
                }
            }
            group(Category_Report)
            {
                Caption = 'Mapping', Comment = 'Generated from the PromotedActionCategories property index 2.';

                actionref(IntegrationTableMappings_Promoted; IntegrationTableMappings)
                {
                }
                actionref("Redeploy Solution_Promoted"; "Redeploy Solution")
                {
                }
                actionref(CoupleUsers_Promoted; CoupleUsers)
                {
                }
            }
            group(Category_Category4)
            {
                Caption = 'Synchronization', Comment = 'Generated from the PromotedActionCategories property index 3.';

                actionref(StartInitialSynchAction_Promoted; StartInitialSynchAction)
                {
                }
                actionref(SynchronizeNow_Promoted; SynchronizeNow)
                {
                }
                actionref("Synch. Job Queue Entries_Promoted"; "Synch. Job Queue Entries")
                {
                }
                actionref(SkippedSynchRecords_Promoted; SkippedSynchRecords)
                {
                }
            }
            group(Category_Category5)
            {
                Caption = 'Encryption', Comment = 'Generated from the PromotedActionCategories property index 4.';

                actionref(EncryptionManagement_Promoted; EncryptionManagement)
                {
                }
            }
            group(Category_Category6)
            {
                Caption = 'Cloud Migration', Comment = 'Generated from the PromotedActionCategories property index 5.';

                actionref(RebuildCouplingTable_Promoted; RebuildCouplingTable)
                {
                }
            }
            group(Category_Category7)
            {
                Caption = 'Field Service';
                Visible = SoftwareAsAService;

                actionref(FieldServiceIntegrationApp_Promoted; FieldServiceIntegrationApp)
                {
                }
            }
        }
    }

    trigger OnAfterGetRecord()
    begin
        RefreshData();
    end;

    trigger OnInit()
    var
        ApplicationAreaMgmtFacade: Codeunit "Application Area Mgmt. Facade";
        CRMIntegrationManagement: Codeunit "CRM Integration Management";
        EnvironmentInfo: Codeunit "Environment Information";
    begin
        ApplicationAreaMgmtFacade.CheckAppAreaOnlyBasic();
        SoftwareAsAService := EnvironmentInfo.IsSaaSInfrastructure();
        CRMIntegrationManagement.RegisterAssistedSetup();
        SetVisibilityFlags();
    end;

    trigger OnOpenPage()
    var
        CRMIntegrationManagement: Codeunit "CRM Integration Management";
        FeatureTelemetry: Codeunit "Feature Telemetry";
        CDSIntegrationImpl: Codeunit "CDS Integration Impl.";
        MultipleCompaniesDetected: Boolean;
    begin
        FeatureTelemetry.LogUptake('0000H7B', 'Dataverse', Enum::"Feature Uptake Status"::Discovered);
        FeatureTelemetry.LogUptake('0000H7C', 'Dynamics 365 Sales', Enum::"Feature Uptake Status"::Discovered);
        Rec.EnsureCDSConnectionIsEnabled();

        if not Rec.Get() then begin
            Rec.Init();
            InitializeDefaultProxyVersion();
            Rec.Insert();
            Rec.LoadConnectionStringElementsFromCDSConnectionSetup();
        end else begin
            CRMPassword := '**********';
            if not Rec."Is Enabled" then
                Rec.LoadConnectionStringElementsFromCDSConnectionSetup();
            ConnectionString := Rec.GetConnectionString();
            Rec.UnregisterConnection();
            if (not IsValidProxyVersion()) then begin
                if not IsValidProxyVersion() then
                    InitializeDefaultProxyVersion();
                Rec.Modify();
            end;
            if Rec."Is Enabled" then begin
                // just try notifying, because the setup may be broken, and we are in OnOpenPage
                if TryDetectMultipleCompanies(MultipleCompaniesDetected) then
                    if MultipleCompaniesDetected then
                        CDSIntegrationImpl.SendMultipleCompaniesNotification()

            end else
                if Rec."Disable Reason" <> '' then
                    CRMIntegrationManagement.SendConnectionDisabledNotification(Rec."Disable Reason");
        end;
    end;

    trigger OnQueryClosePage(CloseAction: Action): Boolean
    begin
        if not Rec."Is Enabled" then
            if not Confirm(StrSubstNo(EnableServiceQst, CurrPage.Caption), true) then
                exit(false);
    end;

    [TryFunction]
    local procedure TryDetectMultipleCompanies(var MultipleCompaniesDetected: Boolean)
    var
        CDSIntegrationImpl: Codeunit "CDS Integration Impl.";
    begin
        Rec.RegisterConnection();
        if (Rec."Server Address" <> '') and (Rec."Server Address" <> TestServerAddressTok) then
            MultipleCompaniesDetected := CDSIntegrationImpl.MultipleCompaniesConnected();
    end;

    var
        CRMProductName: Codeunit "CRM Product Name";
        [NonDebuggable]
        CRMPassword: Text;
        ResetIntegrationTableMappingConfirmQst: Label 'This will restore the default integration table mappings and synchronization jobs for %1. All custom mappings and jobs will be deleted. The default mappings and jobs will be used the next time data is synchronized. Do you want to continue?', Comment = '%1 = CRM product name';
        EncryptionIsNotActivatedQst: Label 'Data encryption is currently not enabled. We recommend that you encrypt data. \Do you want to open the Data Encryption Management window?';
        WebClientUrlResetMsg: Label 'The %1 Web Client URL has been reset to the default value.', Comment = '%1 - product name';
        SyncNowScheduledMsg: Label 'Synchronization of modified records is scheduled.\You can view details on the %1 page.', Comment = '%1 = The localized caption of page Integration Synch. Job List';
        UnfavorableCRMVersionMsg: Label 'This version of %2 might not work correctly with %1. We recommend you upgrade to a supported version.', Comment = '%1 - product name, %2 = CRM product name';
        FavorableCRMVersionMsg: Label 'The version of %1 is valid.', Comment = '%1 = CRM product name';
        UnfavorableCRMSolutionInstalledMsg: Label 'The %1 Integration Solution was not detected.', Comment = '%1 - product name';
        FavorableCRMSolutionInstalledMsg: Label 'The %1 Integration Solution is installed in %2.', Comment = '%1 - product name, %2 = CRM product name';
        SynchronizeModifiedQst: Label 'This will synchronize all modified records in all integration table mappings.\The synchronization will run in the background so you can continue with other tasks.\\Do you want to continue?';
        ReadyScheduledSynchJobsTok: Label '%1 of %2', Comment = '%1 = Count of scheduled job queue entries in ready or in process state, %2 count of all scheduled jobs';
        ScheduledSynchJobsRunning: Text;
        EnableServiceQst: Label 'The %1 is not enabled. Are you sure you want to exit?', Comment = '%1 = This Page Caption (Microsoft Dynamics 365 Connection Setup)';
        PartialScheduledJobsAreRunningMsg: Label 'An active job queue is available but only %1 of the %2 scheduled synchronization jobs are ready or in process.', Comment = '%1 = Count of scheduled job queue entries in ready or in process state, %2 count of all scheduled jobs';
        JobQueueIsNotRunningMsg: Label 'There is no job queue started. Scheduled synchronization jobs require an active job queue to process jobs.\\Contact your administrator to get a job queue configured and started.';
        AllScheduledJobsAreRunningMsg: Label 'An job queue is started and all scheduled synchronization jobs are ready or already processing.';
        SetupSuccessfulMsg: Label 'The default setup for %1 synchronization has completed successfully.', Comment = '%1 = CRM product name';
        CertificateConnectionSetupTelemetryMsg: Label 'User has successfully set up the certificate connection to Dataverse.', Locked = true;
        CertificateConnectionSetupMsg: Label 'You have successfully upgraded the connection to Dynamics 365 Sales to use certificate-based OAuth 2.0 service-to-service authentication. Business Central has auto-generated a new integration user with user name %1 in your Dynamics 365 sales environment. This user does not require a license.', Comment = '%1 - user name';
        Office365AuthTxt: Label 'AuthType=Office365', Locked = true;
        CategoryTok: Label 'AL Dataverse Integration', Locked = true;
        CRMConnEnabledOnPageTxt: Label 'CRM Connection has been enabled from CRMConnectionSetupPage', Locked = true;
        InstallLatestSolutionConfirmLbl: Label 'Bidirectional Sales Order Integration requires the latest integration solution. Do you want to redeploy latest integration solution?';
        TestServerAddressTok: Label '@@test@@', Locked = true;
        ScheduledSynchJobsRunningStyleExpr: Text;
        CRMSolutionInstalledStyleExpr: Text;
        CRMVersionStyleExpr: Text;
        ConnectionString: Text;
        ActiveJobs: Integer;
        TotalJobs: Integer;
        IsEditable: Boolean;
        IsProxyVersionEnabled: Boolean;
        IsCdsIntegrationEnabled: Boolean;
        IsUserNamePasswordVisible: Boolean;
        IsWebCliResetEnabled: Boolean;
        SoftwareAsAService: Boolean;
        IsAutoCreateSalesOrdersEditable: Boolean;
        IsBidirectionalSalesOrderIntegrationEnabled: Boolean;
        CRMVersionStatus: Boolean;

    local procedure RefreshData()
    begin
        Rec.RefreshDataFromCRM(false);
        SetAutoCreateSalesOrdersEditable();
        RefreshSynchJobsData();
        UpdateEnableFlags();
        CRMVersionStatus := Rec.IsVersionValid();
        SetStyleExpr();
        IsBidirectionalSalesOrderIntegrationEnabled := Rec."Bidirectional Sales Order Int.";
    end;

    local procedure RefreshSynchJobsData()
    begin
        Rec.CountCRMJobQueueEntries(ActiveJobs, TotalJobs);
        ScheduledSynchJobsRunning := StrSubstNo(ReadyScheduledSynchJobsTok, ActiveJobs, TotalJobs);
        ScheduledSynchJobsRunningStyleExpr := GetRunningJobsStyleExpr();
    end;

    local procedure SetStyleExpr()
    begin
        CRMSolutionInstalledStyleExpr := GetStyleExpr(Rec."Is CRM Solution Installed");
        CRMVersionStyleExpr := GetStyleExpr(CRMVersionStatus);
    end;

    local procedure SetAutoCreateSalesOrdersEditable()
    begin
        IsAutoCreateSalesOrdersEditable := Rec."Is S.Order Integration Enabled";
    end;

    local procedure GetRunningJobsStyleExpr() StyleExpr: Text
    begin
        if ActiveJobs < TotalJobs then
            StyleExpr := 'Ambiguous'
        else
            StyleExpr := GetStyleExpr((ActiveJobs = TotalJobs) and (TotalJobs <> 0))
    end;

    local procedure GetStyleExpr(Favorable: Boolean) StyleExpr: Text
    begin
        if Favorable then
            StyleExpr := 'Favorable'
        else
            StyleExpr := 'Unfavorable'
    end;

    local procedure UpdateEnableFlags()
    var
        CDSConnectionSetup: Record "CDS Connection Setup";
        CDSIntegrationImpl: Codeunit "CDS Integration Impl.";
    begin
        IsEditable := not Rec."Is Enabled" and not CDSIntegrationImpl.IsIntegrationEnabled();
        IsProxyVersionEnabled := true;
        if CDSConnectionSetup.Get() then
            if CDSConnectionSetup."Is Enabled" then
                IsProxyVersionEnabled := false;

        IsWebCliResetEnabled := Rec."Is CRM Solution Installed" and Rec."Is Enabled";
    end;

    local procedure SetVisibilityFlags()
    var
        CDSConnectionSetup: Record "CDS Connection Setup";
    begin
        IsUserNamePasswordVisible := true;

        if CDSConnectionSetup.Get() then begin
            IsCdsIntegrationEnabled := CDSConnectionSetup."Is Enabled";
            if CDSConnectionSetup."Authentication Type" = CDSConnectionSetup."Authentication Type"::Office365 then
                if not CDSConnectionSetup."Connection String".Contains(Office365AuthTxt) then
                    IsUserNamePasswordVisible := false;
        end;
    end;

    local procedure IsValidProxyVersion(): Boolean
    begin
        exit(Rec."Proxy Version" <> 0);
    end;

    local procedure InitializeDefaultProxyVersion()
    var
        CRMIntegrationManagement: Codeunit "CRM Integration Management";
    begin
        Rec.Validate("Proxy Version", CRMIntegrationManagement.GetLastProxyVersionItem());
    end;
}