Page 7201 CDS Connection Setup Wizard

App
Base Application
Namespace
Microsoft.Integration.Dataverse
Versions
17-28
Source table
7200

Versions171819202122232425262728

Source29

Source in 29

src/Layers/W1/BaseApp/Integration/Dataverse/CDSConnectionSetupWizard.Page.al1393 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.Dataverse;

using Microsoft.Integration.D365Sales;
using System;
using System.Environment;
using System.Environment.Configuration;
using System.Security.Authentication;
using System.Telemetry;
using System.Utilities;

page 7201 "CDS Connection Setup Wizard"
{
    Caption = 'Dataverse Connection Setup', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';

    PageType = NavigatePage;
    SourceTable = "CDS Connection Setup";
    SourceTableTemporary = true;
    Extensible = false;

    layout
    {
        area(content)
        {
            group(BannerStandard)
            {
                Caption = '';
                Editable = false;
                Visible = TopBannerVisible and not CredentialsStepVisible;
                field(MediaResourceStandardReference; MediaResourcesStandard."Media Reference")
                {
                    ApplicationArea = Suite;
                    Editable = false;
                    ShowCaption = false;
                }
            }
            group(BannerDone)
            {
                Caption = '';
                Editable = false;
                Visible = TopBannerVisible and CredentialsStepVisible;
                field(MediaResourceDoneReference; MediaResourcesDone."Media Reference")
                {
                    ApplicationArea = Suite;
                    Editable = false;
                    ShowCaption = false;
                }
            }
            group(Step0)
            {
                Visible = InfoStepVisible;

                Caption = '';
                group(Control2)
                {
                    InstructionalText = 'Quickly set up the connection, couple records, and even synchronize data.';
                    ShowCaption = false;

                    field(Synchronization; Synchronization)
                    {
                        ApplicationArea = Basic, Suite;
                        Caption = 'Enable data synchronization';
                        ToolTip = 'Enable Business Central to synchronize data with Dataverse.';

                        trigger OnValidate()
                        begin
                            NextActionEnabled := Synchronization or BusinessEvents;
                        end;
                    }
                }
                group(Control1)
                {
                    InstructionalText = 'Connect Business Central to Dataverse to synchronize data with other business apps.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';
                    ShowCaption = false;
                }
                group(BusinessEventsOption)
                {
                    InstructionalText = 'Quickly set up Business Central virtual tables in Dataverse and enable business events that Business Central sends to Dataverse.';
                    ShowCaption = false;

                    field("Business Events"; BusinessEvents)
                    {
                        ApplicationArea = Basic, Suite;
                        Enabled = BusinessEventsSupported;
                        Caption = 'Enable virtual tables and events';
                        ToolTip = 'Set up virtual tables and enable business events.';
                        trigger OnValidate()
                        begin
                            NextActionEnabled := Synchronization or BusinessEvents;
                        end;
                    }
                }
                group(Control3)
                {
                    InstructionalText = 'If you choose Next we will try to find your Dataverse environments so you can choose the one to connect to.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';
                    ShowCaption = false;
                }
            }
            group(StepConsent)
            {
                InstructionalText = 'Please review terms and conditions.';
                Visible = ConsentStepVisible;
                field(ConsentLbl; ConsentLbl)
                {
                    ApplicationArea = Basic, Suite;
                    ShowCaption = false;
                    Editable = false;
                    Caption = ' ';
                    MultiLine = true;
                    ToolTip = 'Agree with the customer consent.';
                }
                field(Consent; ConsentVar)
                {
                    ApplicationArea = Basic, Suite;
                    Caption = 'I accept';
                    ToolTip = 'Agree with the customer consent.';
                    trigger OnValidate()
                    begin
                        NextActionEnabled := false;
                        if ConsentVar then
                            NextActionEnabled := true;
                    end;
                }
                field(LearnMore; LearnMoreTok)
                {
                    ApplicationArea = All;
                    Editable = false;
                    ShowCaption = false;
                    Caption = ' ';
                    ToolTip = 'View information about the privacy.';

                    trigger OnDrillDown()
                    begin
                        Hyperlink(PrivacyLinkTxt);
                    end;
                }
            }
            group(StepApplication)
            {
                InstructionalText = 'Specify the ID, secret and redirect URL of the Microsoft Entra application that will be used to connect to Dataverse.', Comment = 'Dataverse and Microsoft Entra are names of Microsoft services and should not be translated.';
                ShowCaption = false;
                Visible = ApplicationStepVisible;

                field("Client Id"; Rec."Client Id")
                {
                    ApplicationArea = Suite;
                    Caption = 'Client ID';
                    ToolTip = 'Specifies the ID of the Microsoft Entra application that will be used to connect to the Dataverse environment.', Comment = 'Dataverse and Microsoft Entra are names of Microsoft services and should not be translated.';
                }
                field("Client Secret"; ClientSecret)
                {
                    ApplicationArea = Suite;
                    ExtendedDatatype = Masked;
                    Caption = 'Client Secret';
                    ToolTip = 'Specifies the secret of the Microsoft Entra application that will be used to connect to the Dataverse environment.', Comment = 'Dataverse and Microsoft Entra are names of Microsoft services and should not be translated.';

                    trigger OnValidate()
                    begin
                        ClientSecretEdited := true;
                        Rec.SetClientSecret(ClientSecret);
                    end;
                }
                field("Redirect URL"; Rec."Redirect URL")
                {
                    ApplicationArea = Suite;
                    ToolTip = 'Specifies the Redirect URL of the Microsoft Entra application that will be used to connect to the Dataverse environment.', Comment = 'Dataverse and Microsoft Entra are names of Microsoft services and should not be translated.';
                }
            }
            group(Step1)
            {
                Visible = AdminStepVisible;

                group(Control11)
                {
                    Caption = 'SET UP THE CONNECTION';
                    InstructionalText = 'Specify the URL of the Dataverse environment. Your environments appear in the list, or you can enter the URL.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';

                    field(ServerAddress; Rec."Server Address")
                    {
                        ApplicationArea = Suite;
                        AssistEdit = true;
                        Caption = 'The Dataverse environment URL.';
                        ShowCaption = false;

                        trigger OnValidate()
                        begin
                            CDSIntegrationImpl.CheckModifyConnectionURL(Rec."Server Address");
                            if Rec."Server Address" <> xRec."Server Address" then begin
                                HasAdminSignedIn := false;
                                NextActionEnabled := false;
                            end;
                            CurrPage.Update();
                        end;

                        trigger OnAssistEdit()
                        var
                            CDSEnvironment: Codeunit "CDS Environment";
                        begin
                            CDSEnvironment.SelectTenantEnvironment(Rec, CDSEnvironment.GetGlobalDiscoverabilityToken(), false);

                            if Rec."Server Address" <> xRec."Server Address" then begin
                                HasAdminSignedIn := false;
                                NextActionEnabled := false;
                            end;
                            CurrPage.Update();
                        end;
                    }
                }

                group(Control12)
                {
                    Caption = '';
                    InstructionalText = 'Sign in with an administrator user account and give consent to the application that will be used to connect to Dataverse. The account will be used one time to install and configure components that the integration requires.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';
                    ShowCaption = false;

                    group(Control13)
                    {
                        Visible = not HasAdminSignedIn;
                        ShowCaption = false;

                        field(SignInAdmin; SignInAdminTxt)
                        {
                            Caption = 'Sign in';
                            ShowCaption = false;
                            Editable = false;
                            ApplicationArea = Suite;

                            trigger OnDrillDown()
                            begin
                                if Rec."Server Address" = '' then
                                    Error(NoEnvironmentSelectedErr);

                                HasAdminSignedIn := true;
                                CDSIntegrationImpl.SignInCDSAdminUser(Rec, CrmHelper, AdminUserName, AdminPassword, AdminAccessToken, AdminADDomain, false);
                                CDSIntegrationImpl.JITProvisionFirstPartyApp(CrmHelper);
                                Sleep(5000);

                                AreAdminCredentialsCorrect := true;
                                if UserPasswordEdited then
                                    Rec.SetPassword(UserPassword)
                                else
                                    Rec.SetPassword(CurrentCDSConnectionSetupPassword());
                                NextActionEnabled := true;

                                if BusinessEvents then
                                    ShowDifferentTenantWarning := CDSEnvironment.CheckIfEnvironmentInDifferentTenant(Rec."Server Address", CDSEnvironment.GetGlobalDiscoverabilityOnBehalfTokenAsSecretText());

                                CurrPage.Update(false);
                            end;
                        }
                    }

                    group(Control14)
                    {
                        Visible = HasAdminSignedIn and AreAdminCredentialsCorrect;
                        ShowCaption = false;

                        field(SuccesfullyLoggedIn; SuccesfullyLoggedInTxt)
                        {
                            ApplicationArea = Suite;
                            ToolTip = 'Indicates whether the administrator user has logged in successfully.';
                            Caption = 'The administrator is signed in.';
                            Editable = false;
                            ShowCaption = false;
                            Style = Favorable;
                        }
                    }

                    group(Control17)
                    {
                        Visible = HasAdminSignedIn and ShowDifferentTenantWarning;
                        ShowCaption = false;

                        field(DifferentTenantWarning; DifferentTenantWarningTxt)
                        {
                            ApplicationArea = Suite;
                            Tooltip = 'Indicates that the environment URL is from a different than Business Central environment and virtual tables will not work.';
                            Caption = 'The environment URL is from a different tenant.';
                            Editable = false;
                            ShowCaption = false;
                            Style = Unfavorable;
                        }
                    }

                    group(Control15)
                    {
                        Visible = HasAdminSignedIn and (not AreAdminCredentialsCorrect);
                        ShowCaption = false;

                        field(UnsuccesfullyLoggedIn; UnsuccesfullyLoggedInTxt)
                        {
                            ApplicationArea = Suite;
                            Tooltip = 'Indicates that the administrator user has not logged in successfully';
                            Caption = 'Could not sign in the administrator.';
                            Editable = false;
                            ShowCaption = false;
                            Style = Unfavorable;
                        }
                    }
                }

                group(Control16)
                {
                    InstructionalText = 'To install and configure integration components, choose Next. This might take a few minutes.';
                    ShowCaption = false;
                }
            }
            group(Step2)
            {
                Caption = '';
                Visible = CredentialsStepVisible;
                group("Integration User")
                {
                    Caption = '';
                    InstructionalText = 'Provide credentials for the user account that the business apps will use to authenticate when they exchange data. This should be an account that is used only for integration with Dataverse.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';

                    group(Control22)
                    {
                        InstructionalText = 'This account must be a valid user in Dataverse and must not be assigned to the System Administrator role. When you finish this guide the account will become non-interactive.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';
                        ShowCaption = false;
                    }

                    field(Email; Rec."User Name")
                    {
                        ApplicationArea = Suite;
                        Caption = 'User Name';
                        ExtendedDatatype = EMail;
                        ToolTip = 'Specifies the email of the user that will be used to connect to the Dataverse environment and synchronize data. This must not be the administrator user account.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';

                        trigger OnValidate()
                        begin
                            CDSIntegrationImpl.CheckUserName(Rec);
                        end;
                    }
                    field(Password; UserPassword)
                    {
                        ApplicationArea = Suite;
                        Caption = 'Password';
                        ExtendedDatatype = Masked;
                        ToolTip = 'Specifies the password of the user that will be used to connect to the Dataverse environment and synchronize data.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';

                        trigger OnValidate()
                        begin
                            UserPasswordEdited := true;
                            Rec.SetPassword(UserPassword);
                        end;
                    }
                }

            }
            group(Step3)
            {
                Caption = '';
                Visible = OwnershipModelStepVisible;
                group("Ownership Model Selection")
                {
                    Caption = 'Choose an ownership model.';
                    InstructionalText = 'People or a team own records in Dataverse that are created from data in Business Central. We recommend the Team model.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';

                    field("Ownership Model"; TempCDSConnectionSetup."Ownership Model")
                    {
                        Caption = 'Ownership Model';
                        ShowCaption = false;
                        ApplicationArea = Suite;
                        ToolTip = 'Specifies the type of owner that will be assigned to any record that is created while synchronizing from Business Central to Dataverse.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';

                        trigger OnValidate()
                        begin
                            IsPersonOwnershipModelSelected := TempCDSConnectionSetup."Ownership Model" = TempCDSConnectionSetup."Ownership Model"::Person;
                            CurrPage.Update(false);
                        end;

                    }
                }
                group("Team Ownership Model")
                {
                    Caption = '';
                    InstructionalText = 'We will create a business unit and a team in Dataverse. Members of the team will own the synchronized data and can assign records to other users or teams in the business unit.';
                    Visible = not IsPersonOwnershipModelSelected;
                }
                group("Salesperson Ownership Model")
                {
                    Caption = '';
                    InstructionalText = 'Couple salespeople in Business Central with users in Dataverse. The salespeople will automatically own all synchronized data. Owners (people) can assign synchronized records to other users or teams in the business unit.', Comment = 'Dataverse is the name of a Microsoft Service and should not be translated.';
                    Visible = IsPersonOwnershipModelSelected;
                }

                group("Skip Synchronization")
                {
                    Caption = 'Complete setup without synchronization';
                    InstructionalText = 'Choose this option to enable the connection without synchronizing data.';
                    field(FinishWithoutSynchronizingData; FinishWithoutSynchronizingData)
                    {
                        ApplicationArea = Suite;
                        Caption = 'Complete without synchronization ';
                        ShowCaption = false;
                        ToolTip = 'Complete the Dataverse Assisted Setup without synchronizing data.';

                        trigger OnValidate()
                        begin
                            if FinishWithoutSynchronizingData then begin
                                NextActionEnabled := BusinessEvents;
                                FinishActionEnabled := not BusinessEvents;
                            end else begin
                                NextActionEnabled := true;
                                FinishActionEnabled := false;
                            end;

                            CurrPage.Update(false);
                        end;
                    }
                    group(Control31)
                    {
                        Visible = FinishWithoutSynchronizingData and BusinessEvents;
                        InstructionalText = 'When you choose Next, the Dataverse connection is enabled and you can start synchronizing data.';
                        ShowCaption = false;
                    }
                    group(Control32)
                    {
                        Visible = FinishWithoutSynchronizingData and (not BusinessEvents);
                        InstructionalText = 'When you choose Finish, the Dataverse connection is enabled and you can start synchronizing data.';
                        ShowCaption = false;
                    }
                }
            }
            group(Step4)
            {
                Visible = CoupleSalespersonsStepVisible;
                Caption = '';
                InstructionalText = 'The Person ownership model requires that you couple salespeople in Business Central with users in Dataverse before you synchronize data. Otherwise, synchronization will not be successful.';
                group(Control41)
                {
                    InstructionalText = 'The salespeople will own the synchronized data and can assign records to other users or teams in the business unit.';
                    ShowCaption = false;
                }
                field(CoupleSalesPeople; CoupleSalesPeopleTxt)
                {
                    Caption = 'Couple Salespeople';
                    ShowCaption = false;
                    Editable = false;
                    ApplicationArea = Suite;

                    trigger OnDrillDown()
                    var
                        CDSCoupleSalespersons: Page "CDS Couple Salespersons";
                    begin
                        if UserPasswordEdited then
                            Rec.SetPassword(UserPassword)
                        else
                            Rec.SetPassword(CurrentCDSConnectionSetupPassword());
                        CDSIntegrationImpl.CheckConnectionRequiredFields(Rec, false);

                        CDSCoupleSalespersons.Editable := true;
                        CDSCoupleSalespersons.Initialize(CrmHelper);
                        if CDSCoupleSalespersons.RunModal() = Action::OK then begin
                            CoupledSalesPeople := true;
                            AddCoupledUsersToDefaultOwningTeam();
                        end;

                        CurrPage.Update(false);
                    end;
                }

            }
            group(Step5)
            {
                Caption = 'Review Recommendations for first-time synchronization.';
                Visible = FullSynchReviewStepVisible;

                group(Control51)
                {
                    InstructionalText = 'First-time synchronization depends on whether there is data in both business apps and the direction.';
                    ShowCaption = false;
                }
                group(Control52)
                {
                    InstructionalText = 'If you have data in both apps and want bi-directional synchronization you must couple each record using match-based coupling or manually.';
                    ShowCaption = false;
                }
                group(Control53)
                {
                    InstructionalText = 'We can analyze both business apps and provide recommendations for your first synchronization.';
                    ShowCaption = false;
                }
                field(SynchronizationRecommendations; SynchronizationRecommendationsLbl)
                {
                    ApplicationArea = Suite;
                    Editable = false;
                    Caption = 'Show initial synchronization recommendations list.';
                    ShowCaption = false;
                    Style = StrongAccent;
                    StyleExpr = true;

                    trigger OnDrillDown()
                    var
                        CDSFullSynchReview: Page "CDS Full Synch. Review";
                    begin
                        Window.Open(GettingThingsReadyTxt);
                        if UserPasswordEdited then
                            Rec.SetPassword(UserPassword)
                        else
                            Rec.SetPassword(CurrentCDSConnectionSetupPassword());

                        CDSFullSynchReview.SetRecord(CRMFullSynchReviewLine);
                        CDSFullSynchReview.SetTableView(CRMFullSynchReviewLine);
                        CDSFullSynchReview.LookupMode := true;
                        Window.Close();
                        if CDSFullSynchReview.RunModal() = Action::LookupOK then;
                        CRMFullSynchReviewLine.FindSet();
                        repeat
                            if InitialSynchRecommendations.ContainsKey(CRMFullSynchReviewLine.Name) then
                                InitialSynchRecommendations.Set(CRMFullSynchReviewLine.Name, CRMFullSynchReviewLine."Initial Synch Recommendation")
                            else
                                InitialSynchRecommendations.Add(CRMFullSynchReviewLine.Name, CRMFullSynchReviewLine."Initial Synch Recommendation")
                        until CRMFullSynchReviewLine.Next() = 0;
                    end;
                }
                group(Control45)
                {
                    InstructionalText = 'After you choose Next, you can follow the progress of your first synchronization on the Dataverse Full Synch Review page. You might need to refresh the page to update the status.';
                    ShowCaption = false;
                    Visible = BusinessEvents;
                }
                group(Control46)
                {
                    InstructionalText = 'After you choose Finish, you can follow the progress of your first synchronization on the Dataverse Full Synch Review page. You might need to refresh the page to update the status.';
                    ShowCaption = false;
                    Visible = not BusinessEvents;
                }
            }
            group(StepBusinessEvents)
            {
                Visible = BusinessEventsStepVisible;

                group(Control61)
                {
                    Caption = 'SET UP VIRTUAL TABLES';
                    InstructionalText = 'Set up Business Central Virtual Tables app in a Dataverse environment to allow Business Central to send business events to Dataverse.';
                }
                group(Control62)
                {
                    InstructionalText = 'Use the link below to go to AppSource and get the the Business Central Virtual Table app, so you can install it in your Dataverse environment. To refresh status after you install, click back and next.';
                    ShowCaption = false;

                    field(InstallVirtualTableApp; VirtualTableAppInstallTxt)
                    {
                        ApplicationArea = All;
                        Editable = false;
                        ShowCaption = false;
                        Caption = ' ';
                        ToolTip = 'Get the Business Central Virtual Table app from Microsoft AppSource.';

                        trigger OnDrillDown()
                        begin
                            Hyperlink(CDSIntegrationImpl.GetVirtualTablesAppSourceLink());
                            FinishActionEnabled := true;
                        end;
                    }
                }
                group(Control63)
                {
                    Visible = VirtualTableAppInstalled;
                    ShowCaption = false;

                    field(VirtualTableAppInstalledLbl; VirtualTableAppInstalledTxt)
                    {
                        ApplicationArea = Suite;
                        ToolTip = 'Indicates whether the Business Central Virtual Table app is installed in the Dataverse environment.';
                        Caption = 'The Business Central Virtual Table app is installed.';
                        Editable = false;
                        ShowCaption = false;
                        Style = Favorable;
                    }
                    field(EnableVirtualTablesLbl; 'Review and enable virtual tables')
                    {
                        ApplicationArea = Suite;
                        Caption = ' ';
                        Editable = false;
                        ShowCaption = false;
                        Style = StrongAccent;
                        StyleExpr = true;

                        trigger OnDrillDown()
                        var
                            CDSAvailableVirtualTables: Page "CDS Available Virtual Tables";
                        begin
                            SetupBusinessEvents();
                            CDSAvailableVirtualTables.Run();
                        end;
                    }
                }
                group(Control64)
                {
                    Visible = not VirtualTableAppInstalled;
                    ShowCaption = false;

                    field(VirtualTableAppNotInstalledLbl; VirtualTableAppNotInstalledTxt)
                    {
                        ApplicationArea = Suite;
                        Tooltip = 'Indicates that the Business Central Virtual Table app is not installed in the Dataverse environment.';
                        Caption = 'The Business Central Virtual Table app is not installed.';
                        Editable = false;
                        ShowCaption = false;
                        Style = Ambiguous;
                    }
                }
                group(Control66)
                {
                    InstructionalText = 'Choose Finish to set up the connection from Dataverse to Business Central and configure virtual tables in your Dataverse environment.';
                    ShowCaption = false;
                }
            }
        }
    }

    actions
    {
        area(Processing)
        {
            action(ActionBack)
            {
                ApplicationArea = Basic, Suite;
                Caption = 'Back';
                Enabled = BackActionEnabled;
                Image = PreviousRecord;
                InFooterBar = true;

                trigger OnAction()
                var
                    CDSConnectionSetup: Record "CDS Connection Setup";
                begin
                    case Step of
                        Step::FullSynchReview:
                            if not IsPersonOwnershipModelSelected then begin
                                CDSConnectionSetup.Get();
                                CDSConnectionSetup.Validate("Is Enabled", false);
                                CDSConnectionSetup.Modify(true);
                                Commit();
                            end;
                        Step::CoupleSalespersons:
                            begin
                                CDSConnectionSetup.Get();
                                CDSConnectionSetup.Validate("Is Enabled", false);
                                CDSConnectionSetup.Modify(true);
                                Commit();
                            end;
                    end;

                    NextStep(true);
                end;
            }
            action(ActionNext)
            {
                ApplicationArea = Basic, Suite;
                Caption = 'Next';
                Enabled = NextActionEnabled;
                Image = NextRecord;
                InFooterBar = true;

                trigger OnAction()
                var
                    CDSConnectionSetup: Record "CDS Connection Setup";
                    AuthenticationType: Option Office365,AD,IFD,OAuth;
                begin
                    case Step of
                        Step::Consent:
                            begin
                                AuthenticationType := Rec."Authentication Type";
                                GetCDSEnvironment();
                                Rec."Authentication Type" := AuthenticationType;
                            end;

                        Step::Application:
                            begin
                                if not CDSConnectionSetup.Get() then begin
                                    CDSConnectionSetup.Init();
                                    CDSConnectionSetup.Insert();
                                end;

                                CDSConnectionSetup.Validate("Client Id", Rec."Client Id");
                                if ClientSecretEdited then
                                    CDSConnectionSetup.SetClientSecret(ClientSecret)
                                else
                                    CDSConnectionSetup.SetClientSecret(CDSConnectionSetup.GetSecretClientSecret());
                                CDSConnectionSetup.Validate("Redirect URL", Rec."Redirect URL");
                                Rec.Modify();
                            end;

                        Step::Admin:
                            begin
                                if (Rec."Server Address" = '') then
                                    Error(URLShouldNotBeEmptyErr);

                                if Synchronization then
                                    ImportCDSSolution();
                            end;

                        Step::IntegrationUser:
                            begin
                                if (Rec."User Name" = '') or (UserPassword = '') then
                                    Error(UsernameAndPasswordShouldNotBeEmptyErr);
                                if UserPasswordEdited then
                                    Rec.SetPassword(UserPassword)
                                else
                                    Rec.SetPassword(CurrentCDSConnectionSetupPassword());
                                if not CDSIntegrationImpl.TryCheckCredentials(Rec) then
                                    Error(WrongCredentialsErr);
                                CDSIntegrationImpl.CheckIntegrationUserPrerequisites(Rec, AdminUserName, AdminPassword, AdminAccessToken, AdminADDomain);
                            end;

                        Step::CoupleSalespersons:
                            begin
                                if (CoupledSalesPeople = false) then
                                    Error(SalespeoplShouldBeCoupledErr);
                                Window.Open(GettingThingsReadyTxt);
                                CRMFullSynchReviewLine.DeleteAll();
                                CRMFullSynchReviewLine.Generate();
                                Commit();
                                Window.Close();
                            end;

                        Step::OwnershipModel:
                            begin
                                Window.Open(GettingThingsReadyTxt);
                                ConfigureCDSSolution();
                                if not IsPersonOwnershipModelSelected then begin
                                    CRMFullSynchReviewLine.DeleteAll();
                                    CRMFullSynchReviewLine.Generate();
                                    Commit();
                                end;
                                Window.Close();
                            end;
                    end;

                    NextStep(false);

                    if Step = Step::BusinessEvents then begin
                        VirtualTableAppInstalled := IsVirtualTablesAppInstalled();
                        FinishActionEnabled := VirtualTableAppInstalled;
                    end;
                end;
            }
            action(ActionRefresh)
            {
                ApplicationArea = Basic, Suite;
                Caption = 'Refresh';
                Visible = Step = Step::BusinessEvents;
                Enabled = not VirtualTableAppInstalled;
                Image = Approve;
                InFooterBar = true;

                trigger OnAction()
                begin
                    VirtualTableAppInstalled := IsVirtualTablesAppInstalled();
                    ShowBusinessEventsStep();
                    CurrPage.Update();
                end;
            }
            action(ActionFinish)
            {
                ApplicationArea = Basic, Suite;
                Caption = 'Finish';
                Enabled = FinishActionEnabled;
                Image = Approve;
                InFooterBar = true;

                trigger OnAction()
                var
                    GuidedExperience: Codeunit "Guided Experience";
                    FeatureTelemetry: Codeunit "Feature Telemetry";
                    CRMFullSynchReview: Page "CRM Full Synch. Review";
                    CDSCoupleSalespersons: Page "CDS Couple Salespersons";
                begin
                    if Synchronization then begin
                        Session.LogMessage('0000GBE', SetupSynchronizationTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
                        if FinishWithoutSynchronizingData then begin
                            Window.Open(GettingThingsReadyTxt);
                            ConfigureCDSSolution();
                            Session.LogMessage('0000CDW', FinishWithoutSynchronizingDataTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
                            if IsPersonOwnershipModelSelected then
                                if Confirm(OpenCoupleSalespeoplePageQst) then begin
                                    Window.Close();
                                    CDSCoupleSalespersons.Initialize(CrmHelper);
                                    CDSCoupleSalespersons.Run();
                                    GuidedExperience.CompleteAssistedSetup(ObjectType::Page, PAGE::"CDS Connection Setup Wizard");
                                    SetupCompleted := true;
                                    AddCoupledUsersToDefaultOwningTeam();
                                    CurrPage.Close();
                                    exit;
                                end;
                            Window.Close();
                            Page.Run(Page::"CDS Connection Setup");
                        end else begin
                            Window.Open(GettingThingsReadyTxt);
                            CRMFullSynchReviewLine.DeleteAll(true);
                            CRMFullSynchReviewLine.Generate(InitialSynchRecommendations);
                            CRMFullSynchReviewLine.Start();
                            CRMFullSynchReview.SetRecord(CRMFullSynchReviewLine);
                            CRMFullSynchReview.SetTableView(CRMFullSynchReviewLine);
                            CRMFullSynchReview.LookupMode := true;
                            Session.LogMessage('0000CDZ', FinishWithSynchronizingDataTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
                            Window.Close();
                            CRMFullSynchReview.Run();
                        end;
                    end;

                    if BusinessEvents then
                        SetupBusinessEvents();

                    GuidedExperience.CompleteAssistedSetup(ObjectType::Page, PAGE::"CDS Connection Setup Wizard");
                    FeatureTelemetry.LogUptake('0000H7H', 'Dataverse', Enum::"Feature Uptake Status"::"Set up");
                    FeatureTelemetry.LogUptake('0000IIO', 'Dataverse Base Entities', Enum::"Feature Uptake Status"::"Set up");
                    SetupCompleted := true;
                    CurrPage.Close();
                end;
            }
        }
    }

    trigger OnInit()
    var
        EnvironmentInfo: Codeunit "Environment Information";
    begin
        LoadTopBanners();
        SoftwareAsAService := EnvironmentInfo.IsSaaSInfrastructure();
        BusinessEventsSupported := CDSIntegrationImpl.GetBusinessEventsSupported();
        Synchronization := true;
        BusinessEvents := BusinessEventsSupported;
    end;

    trigger OnOpenPage()
    var
        CDSConnectionSetup: Record "CDS Connection Setup";
        [SecurityFiltering(SecurityFilter::Ignored)]
        CDSConnectionSetup2: Record "CDS Connection Setup";
        OAuth2: Codeunit "OAuth2";
        FeatureTelemetry: Codeunit "Feature Telemetry";
        RedirectUrl: Text;
        SecretUserPassword: SecretText;
        SecretClientSecret: SecretText;
    begin
        if not CDSConnectionSetup2.WritePermission() then
            Error(NoPermissionsErr);
        FeatureTelemetry.LogUptake('0000H7I', 'Dataverse', Enum::"Feature Uptake Status"::Discovered);
        FeatureTelemetry.LogUptake('0000IIP', 'Dataverse Base Entities', Enum::"Feature Uptake Status"::Discovered);
        CDSConnectionSetup.EnsureCRMConnectionSetupIsDisabled();
        Rec.Init();
        if CDSConnectionSetup.Get() then begin
            TempCDSConnectionSetup."Ownership Model" := CDSConnectionSetup."Ownership Model";
            Rec."Proxy Version" := CDSConnectionSetup."Proxy Version";
            Rec."Authentication Type" := CDSConnectionSetup."Authentication Type";
            Rec."Server Address" := CDSConnectionSetup."Server Address";
            Rec."User Name" := CDSConnectionSetup."User Name";
            UserPassword := '**********';
            SecretUserPassword := CDSConnectionSetup.GetSecretPassword();
            Rec.SetPassword(SecretUserPassword);
            if not SoftwareAsAService then begin
                Rec."Client Id" := CDSConnectionSetup."Client Id";
                ClientSecret := '**********';
                SecretClientSecret := CDSConnectionSetup.GetSecretClientSecret();
                Rec.SetClientSecret(SecretClientSecret);
                Rec."Redirect URL" := CDSConnectionSetup."Redirect URL";
            end;
        end else begin
            CDSConnectionSetup.Init();
            CDSConnectionSetup.Insert();
            TempCDSConnectionSetup."Ownership Model" := TempCDSConnectionSetup."Ownership Model"::Team;
            InitializeDefaultAuthenticationType();
            InitializeDefaultProxyVersion();
        end;
        if not SoftwareAsAService then
            if Rec."Redirect URL" = '' then begin
                OAuth2.GetDefaultRedirectUrl(RedirectUrl);
                Rec."Redirect URL" := CopyStr(RedirectUrl, 1, MaxStrLen(Rec."Redirect URL"));
            end;
        IsPersonOwnershipModelSelected := TempCDSConnectionSetup."Ownership Model" = TempCDSConnectionSetup."Ownership Model"::Person;
        Rec.Insert();
        Step := Step::Info;
        EnableControls();
    end;

    trigger OnQueryClosePage(CloseAction: Action): Boolean
    var
        CDSConnectionSetup: Record "CDS Connection Setup";
    begin
        if CloseAction <> ACTION::OK then
            exit;

        if SetupCompleted then
            exit;

        if CDSConnectionSetup.Get() then
            if CDSConnectionSetup."Is Enabled" then begin
                if not Confirm(ConnectionNotCompletedQst, false) then
                    Error('');
                CDSConnectionSetup.Validate("Is Enabled", false);
                CDSConnectionSetup.Modify(true);
                exit;
            end;

        if not Confirm(ConnectionNotSetUpQst, false) then
            Error('');
    end;

    var
        MediaRepositoryStandard: Record "Media Repository";
        MediaRepositoryDone: Record "Media Repository";
        MediaResourcesStandard: Record "Media Resources";
        MediaResourcesDone: Record "Media Resources";
        CRMFullSynchReviewLine: Record "CRM Full Synch. Review Line";
        TempCDSConnectionSetup: Record "CDS Connection Setup" temporary;
        CDSIntegrationImpl: Codeunit "CDS Integration Impl.";
        CDSEnvironment: Codeunit "CDS Environment";
        ClientTypeManagement: Codeunit "Client Type Management";
        CrmHelper: DotNet CrmHelper;
        Step: Option Info,Consent,Application,Admin,IntegrationUser,OwnershipModel,CoupleSalespersons,FullSynchReview,BusinessEvents,Finish;
        Window: Dialog;
        AdminAccessToken: SecretText;
        [NonDebuggable]
        AdminUserName: Text;
        AdminPassword: SecretText;
        [NonDebuggable]
        AdminADDomain: Text;
        [NonDebuggable]
        ClientSecret: Text;
        ClientSecretEdited: Boolean;
        SoftwareAsAService: Boolean;
        ApplicationStepVisible: Boolean;
        TopBannerVisible: Boolean;
        BackActionEnabled: Boolean;
        NextActionEnabled: Boolean;
        FinishActionEnabled: Boolean;
        InfoStepVisible: Boolean;
        AdminStepVisible: Boolean;
        CredentialsStepVisible: Boolean;
        OwnershipModelStepVisible: Boolean;
        CoupleSalespersonsStepVisible: Boolean;
        FullSynchReviewStepVisible: Boolean;
        BusinessEventsStepVisible: Boolean;
        CoupledSalesPeople: Boolean;
        IsPersonOwnershipModelSelected: Boolean;
        HasAdminSignedIn: Boolean;
        AreAdminCredentialsCorrect: Boolean;
        FinishWithoutSynchronizingData: Boolean;
        SetupCompleted: Boolean;
        Synchronization: Boolean;
        BusinessEvents: Boolean;
        BusinessEventsSupported: Boolean;
        VirtualTableAppInstalled: Boolean;
        ConsentVar: Boolean;
        ConsentStepVisible: Boolean;
        ShowDifferentTenantWarning: Boolean;
        InitialSynchRecommendations: Dictionary of [Code[20], Integer];
        OpenCoupleSalespeoplePageQst: Label 'The Person ownership model requires that you couple salespeople in Business Central with users in Dataverse before you synchronize data. Otherwise, synchronization will not be successful.\\ Do you want to want to couple salespeople and users now?';
        SynchronizationRecommendationsLbl: Label 'Show synchronization recommendations';
        ConsentLbl: Label 'By enabling this feature, you consent to your data being shared with a Microsoft service that might be outside of your organization''s selected geographic boundaries and might have different compliance and security standards than Microsoft Dynamics Business Central. Your privacy is important to us, and you can choose whether to share data with the service. To learn more, follow the link below.';
        PrivacyLinkTxt: Label 'https://go.microsoft.com/fwlink/?linkid=521839';
        LearnMoreTok: Label 'Privacy and Cookies';
        [NonDebuggable]
        UserPassword: Text;
        UserPasswordEdited: Boolean;
        SuccesfullyLoggedInTxt: Label 'The administrator is signed in.';
        UnsuccesfullyLoggedInTxt: Label 'Could not sign in the administrator.';
        VirtualTableAppInstalledTxt: Label 'The Business Central Virtual Table app is installed.';
        VirtualTableAppNotInstalledTxt: Label 'The Business Central Virtual Table app is not installed.';
        SignInAdminTxt: Label 'Sign in with administrator user';
        CoupleSalesPeopleTxt: Label 'Couple Salespeople to Users';
        NoEnvironmentSelectedErr: Label 'To sign in the administrator user you must specify an environment.';
        ConnectionNotSetUpQst: Label 'The connection to Dataverse environment has not been set up.\\Are you sure you want to exit?';
        ConnectionNotCompletedQst: Label 'The setup for Dataverse is not complete. The connection to the Dataverse environment will be disabled.\\Are you sure you want to exit?';
        WrongCredentialsErr: Label 'The credentials provided are incorrect.';
        UsernameAndPasswordShouldNotBeEmptyErr: Label 'You must specify a username and a password for the integration user';
        SalespeoplShouldBeCoupledErr: Label 'When the Person ownership model is selected, coupling of salespeople is required.';
        URLShouldNotBeEmptyErr: Label 'You must specify the URL of your Dataverse environment.';
        AdminUserShouldBesignedInErr: Label 'The admin user must be connected in order to proceed.';
        CategoryTok: Label 'AL Dataverse Integration', Locked = true;
        SetupVirtualTablesTxt: Label 'Setup virtual tables.', Locked = true;
        SetupSynchronizationTxt: Label 'Setup data synchronization.', Locked = true;
        FinishWithoutSynchronizingDataTxt: Label 'User has chosen to finalize Dataverse configuration without synchronizing data.', Locked = true;
        FinishWithSynchronizingDataTxt: Label 'User has chosen to finalize Dataverse configuration also synchronizing data.', Locked = true;
        GettingThingsReadyTxt: Label 'Getting things ready for you.';
        VirtualTableAppNotInstalledErr: Label 'Business Central Virtual Table app is not installed.';
        VirtualTableAppInstallTxt: Label 'Install Business Central Virtual Table app';
        NoPermissionsErr: Label 'Your license does not allow you to set up the connection to Dataverse. To view details about your permissions, see the Effective Permissions page.';
        DifferentTenantWarningTxt: Label 'Environment URL is from a different tenant. Virtual tables won''t work.';

    [NonDebuggable]
    [Scope('OnPrem')]
    local procedure GetCDSEnvironment()
    var
        OAuth2: Codeunit OAuth2;
        Endpoints: Interface "Dataverse Cloud Endpoints";
        Scopes: List of [Text];
        Token: SecretText;
        RedirectUrl: Text;
    begin
        Endpoints := Rec.GetDataverseCloudEndpoints();
        if SoftwareAsAService then
            RedirectUrl := CDSIntegrationImpl.GetRedirectURL()
        else
            RedirectUrl := Rec."Redirect URL";
        Scopes.Add(Endpoints.GetGlobalDiscoveryScope());
        OAuth2.AcquireOnBehalfOfToken(RedirectUrl, Scopes, Token);
        CDSEnvironment.SelectTenantEnvironment(Rec, Token, false);
    end;

    local procedure LoadTopBanners()
    begin
        if MediaRepositoryStandard.Get('AssistedSetup-NoText-400px.png', Format(ClientTypeManagement.GetCurrentClientType())) and
           MediaRepositoryDone.Get('AssistedSetupDone-NoText-400px.png', Format(ClientTypeManagement.GetCurrentClientType()))
        then
            if MediaResourcesStandard.Get(MediaRepositoryStandard."Media Resources Ref") and
               MediaResourcesDone.Get(MediaRepositoryDone."Media Resources Ref")
            then
                TopBannerVisible := MediaResourcesDone."Media Reference".HasValue();
    end;

    local procedure NextStep(Backward: Boolean)
    begin
        UpdateAvailableStepNumber(Backward);
        EnableControls();
        SetupCompleted := false;
    end;

    local procedure UpdateAvailableStepNumber(Backward: Boolean)
    begin
        repeat
            UpdateStepNumber(Backward);
        until IsStepAvailable();
    end;

    local procedure UpdateStepNumber(Backward: Boolean)
    begin
        if Backward then
            Step := Step - 1
        else
            Step := Step + 1;
    end;

    local procedure IsStepAvailable(): Boolean
    begin
        case Step of
            Step::OwnershipModel:
                if not Synchronization then
                    exit(false);

            Step::FullSynchReview:
                if (not Synchronization) or FinishWithoutSynchronizingData then
                    exit(false);

            Step::IntegrationUser:
                begin
                    if not Synchronization then
                        exit(false);
                    if Rec."Authentication Type" = Rec."Authentication Type"::Office365 then
                        // skip the user credentials step in Office365 authentication
                        // we don't use username/password authentication
                        // we inject an application user and use ClientId/ClientSecret authentication
                        exit(false);
                end;

            Step::CoupleSalespersons:
                begin
                    if not Synchronization then
                        exit(false);
                    if not IsPersonOwnershipModelSelected then
                        exit(false);
                end;

            Step::Application:
                if SoftwareAsAService then
                    // skip the application step in SaaS as we use the default application
                    exit(false);

            Step::BusinessEvents:
                if not BusinessEvents then
                    exit(false);
        end;

        exit(true);
    end;

    local procedure EnableControls()
    begin
        case Step of
            Step::Info:
                ShowInfoStep();
            Step::Consent:
                ShowConsentStep();
            Step::Application:
                ShowApplicationStep();
            Step::Admin:
                ShowAdminStep();
            Step::IntegrationUser:
                ShowIntegrationUserStep();
            Step::OwnershipModel:
                ShowOwnershipModelStep();
            Step::CoupleSalespersons:
                ShowCoupleSalespersonsStep();
            Step::FullSynchReview:
                ShowFullSynchReviewStep();
            Step::BusinessEvents:
                ShowBusinessEventsStep();
        end;
    end;

    local procedure ShowInfoStep()
    begin
        BackActionEnabled := false;
        NextActionEnabled := true;
        FinishActionEnabled := false;

        InfoStepVisible := true;
        ConsentStepVisible := false;
        ApplicationStepVisible := false;
        AdminStepVisible := false;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := false;
    end;

    local procedure ShowConsentStep()
    begin
        BackActionEnabled := true;
        NextActionEnabled := true;
        if not ConsentVar then
            NextActionEnabled := false;
        FinishActionEnabled := false;

        InfoStepVisible := false;
        ConsentStepVisible := true;
        ApplicationStepVisible := false;
        AdminStepVisible := false;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := false;
    end;

    local procedure ShowApplicationStep()
    begin
        BackActionEnabled := true;
        NextActionEnabled := true;
        FinishActionEnabled := false;

        ConsentStepVisible := false;
        InfoStepVisible := false;
        ApplicationStepVisible := true;
        AdminStepVisible := false;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := false;
    end;

    local procedure ShowAdminStep()
    begin
        BackActionEnabled := true;
        if HasAdminSignedIn then
            NextActionEnabled := true
        else
            NextActionEnabled := false;
        FinishActionEnabled := false;

        InfoStepVisible := false;
        ConsentStepVisible := false;
        ApplicationStepVisible := false;
        AdminStepVisible := true;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := false;

        Rec."Authentication Type" := Rec."Authentication Type"::Office365;
    end;

    local procedure ShowIntegrationUserStep()
    begin
        BackActionEnabled := true;
        NextActionEnabled := true;
        FinishActionEnabled := false;

        InfoStepVisible := false;
        ConsentStepVisible := false;
        ApplicationStepVisible := false;
        AdminStepVisible := false;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := true;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := false;
    end;

    local procedure ShowOwnershipModelStep()
    begin
        BackActionEnabled := true;
        if FinishWithoutSynchronizingData then begin
            NextActionEnabled := BusinessEvents;
            FinishActionEnabled := not BusinessEvents;
        end else begin
            NextActionEnabled := true;
            FinishActionEnabled := false;
        end;

        InfoStepVisible := false;
        ApplicationStepVisible := false;
        AdminStepVisible := false;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := true;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := false;

        CoupledSalesPeople := false;
    end;

    local procedure ShowCoupleSalespersonsStep()
    begin
        BackActionEnabled := true;
        NextActionEnabled := true;
        FinishActionEnabled := false;

        InfoStepVisible := false;
        ApplicationStepVisible := false;
        AdminStepVisible := false;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := true;
        FullSynchReviewStepVisible := false;

        CoupledSalesPeople := false;
    end;

    local procedure ShowFullSynchReviewStep()
    begin
        BackActionEnabled := true;
        NextActionEnabled := BusinessEvents;
        FinishActionEnabled := not BusinessEvents;

        InfoStepVisible := false;
        ApplicationStepVisible := false;
        AdminStepVisible := false;
        BusinessEventsStepVisible := false;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := true;
    end;

    local procedure ShowBusinessEventsStep()
    begin
        BackActionEnabled := true;
        NextActionEnabled := false;
        FinishActionEnabled := VirtualTableAppInstalled;

        InfoStepVisible := false;
        ApplicationStepVisible := false;
        AdminStepVisible := false;
        BusinessEventsStepVisible := true;
        CredentialsStepVisible := false;
        OwnershipModelStepVisible := false;
        CoupleSalespersonsStepVisible := false;
        FullSynchReviewStepVisible := false;
    end;

    local procedure InitializeDefaultAuthenticationType()
    begin
        Rec.Validate("Authentication Type", Rec."Authentication Type"::Office365);
    end;

    local procedure InitializeDefaultProxyVersion()
    begin
        Rec.Validate("Proxy Version", CDSIntegrationImpl.GetLastProxyVersionItem());
    end;

    local procedure FinalizeBusinessEventsSetup()
    begin
        Rec."Business Events Enabled" := true;
        if not SoftwareAsAService then
            if ClientSecretEdited then
                Rec.SetClientSecret(ClientSecret)
            else
                Rec.SetClientSecret(CurrentCDSConnectionSetupClientSecret());
        CDSIntegrationImpl.UpdateBusinessEventsSetupFromWizard(Rec);
    end;

    local procedure FinalizeSynchronizationSetup()
    begin
        Rec."Ownership Model" := TempCDSConnectionSetup."Ownership Model";
        Rec."Is Enabled" := true;
        if not SoftwareAsAService then
            if ClientSecretEdited then
                Rec.SetClientSecret(ClientSecret)
            else
                Rec.SetClientSecret(CurrentCDSConnectionSetupClientSecret());
        if UserPasswordEdited then
            CDSIntegrationImpl.UpdateConnectionSetupFromWizard(Rec, UserPassword)
        else
            CDSIntegrationImpl.UpdateConnectionSetupFromWizard(Rec, CurrentCDSConnectionSetupPassword());
    end;

    local procedure CurrentCDSConnectionSetupClientSecret(): SecretText
    var
        CDSConnectionSetup: Record "CDS Connection Setup";
    begin
        CDSConnectionSetup.Get();
        exit(CDSConnectionSetup.GetSecretClientSecret());
    end;

    local procedure CurrentCDSConnectionSetupPassword(): SecretText
    var
        CDSConnectionSetup: Record "CDS Connection Setup";
    begin
        CDSConnectionSetup.Get();
        exit(CDSConnectionSetup.GetSecretPassword());
    end;

    [NonDebuggable]
    local procedure ConfigureCDSSolution()
    var
        CDSConectionSetup: Record "CDS Connection Setup";
    begin
        if Rec."Authentication Type" <> Rec."Authentication Type"::Office365 then begin
            if UserPasswordEdited then
                Rec.SetPassword(UserPassword)
            else
                Rec.SetPassword(CurrentCDSConnectionSetupPassword());
            CDSIntegrationImpl.CheckCredentials(Rec);
        end;
        CDSIntegrationImpl.ConfigureIntegrationSolution(Rec, CrmHelper, AdminUserName, AdminPassword, AdminAccessToken, AdminADDomain, true);

        FinalizeSynchronizationSetup();

        if CDSConectionSetup.Get() then begin
            CDSIntegrationImpl.RegisterConnection(CDSConectionSetup, false);
            CDSIntegrationImpl.ActivateConnection();
            CDSIntegrationImpl.ClearConnectionDisableReason(CDSConectionSetup);
            CDSConectionSetup.EnableIntegrationTables();
        end;

        Commit();
    end;

    [NonDebuggable]
    local procedure ImportCDSSolution()
    begin
        if not HasAdminSignedIn then
            Error(AdminUserShouldBesignedInErr);

        Window.Open(GettingThingsReadyTxt);
        CDSIntegrationImpl.ImportIntegrationSolution(Rec, CrmHelper, AdminUserName, AdminPassword, AdminAccessToken, AdminADDomain, false);
        Window.Close();
    end;

    local procedure AddCoupledUsersToDefaultOwningTeam()
    begin
        CDSIntegrationImpl.AddCoupledUsersToDefaultOwningTeam(Rec, CrmHelper);
    end;

    local procedure IsVirtualTablesAppInstalled(): Boolean
    var
        [NonDebuggable]
        TempAdminCDSConnectionSetup: Record "CDS Connection Setup" temporary;
    begin
        CDSIntegrationImpl.GetTempConnectionSetup(TempAdminCDSConnectionSetup, Rec, AdminAccessToken);
        exit(CDSIntegrationImpl.IsVirtualTablesAppInstalled(TempAdminCDSConnectionSetup));
    end;

    local procedure SetupBusinessEvents()
    begin
        VirtualTableAppInstalled := IsVirtualTablesAppInstalled();
        if not VirtualTableAppInstalled then begin
            FinishActionEnabled := false;
            Error(VirtualTableAppNotInstalledErr);
        end;

        Session.LogMessage('0000GBD', SetupVirtualTablesTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
        Window.Open(GettingThingsReadyTxt);
        CDSIntegrationImpl.SetupVirtualTables(Rec, CrmHelper, AdminAccessToken, Rec."Virtual Tables Config Id");
        FinalizeBusinessEventsSetup();
        Window.Close();
    end;
}