Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.ExternalFileStorage;

codeunit 9459 "Default File Scenario Impl." implements "File Scenario"
{
Access = Internal;
InherentPermissions = X;
InherentEntitlements = X;

/// <summary>
/// Called before adding or modifying a file scenario.
/// </summary>
/// <param name="Scenario">The ID of the file scenario.</param>
/// <param name="Connector">The file storage connector.</param>
/// <returns>True if the operation is allowed, otherwise false.</returns>
procedure BeforeAddOrModifyFileScenarioCheck(Scenario: Enum "File Scenario"; Connector: Enum System.ExternalFileStorage."Ext. File Storage Connector") SkipInsertOrModify: Boolean
begin
SkipInsertOrModify := false;
end;

/// <summary>
/// Called to get additional setup for a file scenario.
/// </summary>
/// <param name="Scenario">The ID of the file scenario.</param>
/// <param name="Connector">The file storage connector.</param>
/// <returns>True if additional setup is available, otherwise false.</returns>
procedure GetAdditionalScenarioSetup(Scenario: Enum "File Scenario"; Connector: Enum System.ExternalFileStorage."Ext. File Storage Connector") SetupExist: Boolean
begin
SetupExist := false;
end;

/// <summary>
/// Called before deleting a file scenario.
/// </summary>
/// <param name="Scenario">The ID of the file scenario.</param>
/// <param name="Connector">The file storage connector.</param>
/// <returns>True if the delete operation is handled and should not proceed, otherwise false.</returns>
procedure BeforeDeleteFileScenarioCheck(Scenario: Enum "File Scenario"; Connector: Enum System.ExternalFileStorage."Ext. File Storage Connector") SkipDelete: Boolean
begin
SkipDelete := false;
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ codeunit 9452 "File Scenario"
/// <returns>True if an account for the default scenario was found; otherwise - false.</returns>
procedure GetDefaultFileAccount(var TempFileAccount: Record "File Account" temporary): Boolean
begin
exit(FileScenarioImpl.GetFileAccount(Enum::"File Scenario"::Default, TempFileAccount));
exit(FileScenarioImpl.GetFileAccountOrDefault(Enum::"File Scenario"::Default, TempFileAccount));
end;

/// <summary>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@StefanSosic you changed the behaviour of the method GetFileAccount.

    /// <summary>
    /// Gets the file account used by the given file scenario.
    /// If the no account is defined for the provided scenario, the default account (if defined) will be returned.
    /// </summary>
    /// <param name="Scenario">The scenario to look for.</param>
    /// <param name="TempFileAccount">Out parameter holding information about the file account.</param>
    /// <returns>True if an account for the specified scenario was found; otherwise - false.</returns>
    procedure GetFileAccount(Scenario: Enum "File Scenario"; var TempFileAccount: Record "File Account" temporary): Boolean
    begin
        exit(FileScenarioImpl.GetFileAccount(Scenario, TempFileAccount));
        // Needs to be changed to:
        // exit(FileScenarioImpl.GetFileAccountOrDefault(Scenario, TempFileAccount));
    end;

Now this method won't return the Default File Account.
To be non breaking I would suggest to call the new method GetFileAccountOrDefault.

Furthermore I would suggest to add a new procedure in the public facade:

    /// Gets the file account used by the given file scenario.
    /// </summary>
    /// <param name="Scenario">The scenario to look for.</param>
    /// <param name="TempFileAccount">Out parameter holding information about the file account.</param>
    /// <returns>True if an account for the specified scenario was found; otherwise - false.</returns>
    procedure GetSpecificFileAccount(Scenario: Enum "File Scenario"; var TempFileAccount: Record "File Account" temporary): Boolean
    begin
        exit(FileScenarioImpl.GetFileAccount(Scenario, TempFileAccount));
    end;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not return default at first place, so in this case it's by design

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then you should update the documentation.

Copy link
Contributor Author

@StefanSosic StefanSosic Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since tests are complaining to this point likewise
I think we will do here a bit refactoring, something like you mentioned in first comment. Naming will still be wrong, so thinking still whats best to do, maybe even adjusting tests, but let's see
Thanks for pointing it out 🚀

Expand All @@ -32,6 +32,17 @@ codeunit 9452 "File Scenario"
exit(FileScenarioImpl.GetFileAccount(Scenario, TempFileAccount));
end;

/// <summary>
/// Gets the file account used by the given file scenario or the default file account if no specific account is assigned to the scenario.
/// </summary>
/// <param name="Scenario">The scenario to look for.</param>
/// <param name="TempFileAccount">Out parameter holding information about the file account.</param>
/// <returns>True if an account for the specified scenario was found; otherwise - false.</returns>
procedure GetFileAccountOrDefault(Scenario: Enum "File Scenario"; var TempFileAccount: Record "File Account" temporary): Boolean
begin
exit(FileScenarioImpl.GetFileAccountOrDefault(Scenario, TempFileAccount));
end;

/// <summary>
/// Sets a default file account.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ namespace System.ExternalFileStorage;
/// File scenarios.
/// Used to decouple file accounts from sending files.
/// </summary>
enum 9451 "File Scenario"
enum 9451 "File Scenario" implements "File Scenario"
{
Extensible = true;
DefaultImplementation = "File Scenario" = "Default File Scenario Impl.";

/// <summary>
/// The default file scenario.
Expand All @@ -20,5 +21,6 @@ enum 9451 "File Scenario"
value(0; Default)
{
Caption = 'Default';
Implementation = "File Scenario" = "Default File Scenario Impl.";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.ExternalFileStorage;

interface "File Scenario"
{
/// <summary>
/// Called before adding or modifying a file scenario.
/// </summary>
/// <param name="Scenario">The ID of the file scenario.</param>
/// <param name="Connector">The file storage connector.</param>
/// <returns>True if the operation is allowed; otherwise false.</returns>
procedure BeforeAddOrModifyFileScenarioCheck(Scenario: Enum "File Scenario"; Connector: Enum System.ExternalFileStorage."Ext. File Storage Connector") SkipInsertOrModify: Boolean;

/// <summary>
/// Called to get additional setup for a file scenario.
/// </summary>
/// <param name="Scenario">The ID of the file scenario.</param>
/// <param name="Connector">The file storage connector.</param>
/// <returns>True if additional setup is available, otherwise false.</returns>
procedure GetAdditionalScenarioSetup(Scenario: Enum "File Scenario"; Connector: Enum System.ExternalFileStorage."Ext. File Storage Connector") SetupExist: Boolean;

/// <summary>
/// Called before deleting a file scenario.
/// </summary>
/// <param name="Scenario">The ID of the file scenario.</param>
/// <param name="Connector">The file storage connector.</param>
/// <returns>True if the delete operation is handled and should not proceed; otherwise false.</returns>
procedure BeforeDeleteFileScenarioCheck(Scenario: Enum "File Scenario"; Connector: Enum System.ExternalFileStorage."Ext. File Storage Connector") SkipDelete: Boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,20 @@ codeunit 9453 "File Scenario Impl."
TempFileAccount := TempAllFileAccounts;
exit(true);
end;
end;

procedure GetFileAccountOrDefault(Scenario: Enum "File Scenario"; var TempFileAccount: Record "File Account" temporary): Boolean
var
TempAllFileAccounts: Record "File Account" temporary;
FileScenario: Record "File Scenario";
FileAccounts: Codeunit "File Account";
begin
// Find the account for the provided scenario
if GetFileAccount(Scenario, TempFileAccount) then
exit(true);

// Fallback to the default account if the scenario isn't mapped or the mapped account doesn't exist
FileAccounts.GetAllAccounts(TempAllFileAccounts);
if FileScenario.Get(Enum::"File Scenario"::Default) then
if TempAllFileAccounts.Get(FileScenario."Account Id", FileScenario.Connector) then begin
TempFileAccount := TempAllFileAccounts;
Expand Down Expand Up @@ -174,6 +186,8 @@ codeunit 9453 "File Scenario Impl."
TempSelectedFileAccScenarios: Record "File Account Scenario" temporary;
FileScenario: Record "File Scenario";
FileScenariosForAccount: Page "File Scenarios for Account";
FileScenarioInterface: Interface "File Scenario";
FileScenarioEnum: Enum "File Scenario";
begin
FileAccountImpl.CheckPermissions();

Expand All @@ -193,6 +207,11 @@ codeunit 9453 "File Scenario Impl."
exit;

repeat
FileScenarioEnum := Enum::"File Scenario".FromInteger(TempSelectedFileAccScenarios.Scenario);
FileScenarioInterface := FileScenarioEnum;
if FileScenarioInterface.BeforeAddOrModifyFileScenarioCheck(FileScenarioEnum, TempSelectedFileAccScenarios.Connector) then
exit;

if not FileScenario.Get(TempSelectedFileAccScenarios.Scenario) then begin
FileScenario."Account Id" := TempFileAccountScenario."Account Id";
FileScenario.Connector := TempFileAccountScenario.Connector;
Expand Down Expand Up @@ -289,6 +308,8 @@ codeunit 9453 "File Scenario Impl."
procedure DeleteScenario(var TempFileAccountScenario: Record "File Account Scenario" temporary): Boolean
var
FileScenario: Record "File Scenario";
FileScenarioInterface: Interface "File Scenario";
FileScenarioEnum: Enum "File Scenario";
begin
FileAccountImpl.CheckPermissions();

Expand All @@ -301,7 +322,10 @@ codeunit 9453 "File Scenario Impl."
FileScenario.SetRange("Account Id", TempFileAccountScenario."Account Id");
FileScenario.SetRange(Connector, TempFileAccountScenario.Connector);

FileScenario.DeleteAll();
FileScenarioEnum := Enum::"File Scenario".FromInteger(TempFileAccountScenario.Scenario);
FileScenarioInterface := FileScenarioEnum;
if not FileScenarioInterface.BeforeDeleteFileScenarioCheck(FileScenarioEnum, TempFileAccountScenario.Connector) then
FileScenario.DeleteAll();
end;
until TempFileAccountScenario.Next() = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,25 @@ page 9452 "File Scenario Setup"

group(Scenario)
{
action(ScenarioSetup)
{
Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
Caption = 'Additional Scenario Setup';
ToolTip = 'Additional scenario setup for the selected scenario.';
Image = Setup;
Scope = Repeater;
trigger OnAction()
var
FileScenarioInterface: Interface "File Scenario";
FileScenarioEnum: Enum "File Scenario";
NoSetupAvailableMsg: Label 'No additional setup is available for this scenario.';
begin
FileScenarioEnum := Enum::"File Scenario".FromInteger(Rec.Scenario);
FileScenarioInterface := FileScenarioEnum;
if not FileScenarioInterface.GetAdditionalScenarioSetup(FileScenarioEnum, Rec.Connector) then
Message(NoSetupAvailableMsg);
end;
}
action(ChangeAccount)
{
Visible = (TypeOfEntry = TypeOfEntry::Scenario) and CanUserManageFileSetup;
Expand Down Expand Up @@ -123,6 +142,7 @@ page 9452 "File Scenario Setup"
group(Category_Process)
{
actionref(AddScenario_Promoted; AddScenario) { }
actionref(ScenarioSetup_Promoted; ScenarioSetup) { }
actionref(ChangeAccount_Promoted; ChangeAccount) { }
actionref(Unassign_Promoted; Unassign) { }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,28 @@ page 9453 "File Scenarios FactBox"
}
}
}
actions
{
area(Processing)
{
action(ScenarioSetup)
{
Caption = 'Additional Scenario Setup';
ToolTip = 'Additional scenario setup for the selected scenario.';
Image = Setup;
Scope = Repeater;
trigger OnAction()
var
FileScenarioInterface: Interface "File Scenario";
FileScenarioEnum: Enum "File Scenario";
NoSetupAvailableMsg: Label 'No additional setup is available for this scenario.';
begin
FileScenarioEnum := Rec.Scenario;
FileScenarioInterface := FileScenarioEnum;
if not FileScenarioInterface.GetAdditionalScenarioSetup(Rec.Scenario, Rec.Connector) then
Message(NoSetupAvailableMsg);
end;
}
}
}
}
Loading