Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,26 @@ page 4404 "SOA Email Message"
Editable = false;
}
}

group(SendingStatusGroup)
{
ShowCaption = false;
Visible = RetrySendingVisible;

field(SendingStatus; SendingStatusTxt)
{
ApplicationArea = All;
Caption = 'Sending status';
ToolTip = 'Specifies that the reply could not be sent after all retry attempts.';
Editable = false;
Style = Unfavorable;
}
}
}
}
}
}

group(Message)
{
Caption = 'Message';
Expand Down Expand Up @@ -244,6 +260,44 @@ page 4404 "SOA Email Message"
}
}

actions
{
area(Processing)
{
action(RetrySending)
{
ApplicationArea = All;
Caption = 'Retry sending';
Image = Refresh;
ToolTip = 'Reset the failed sending attempts so the reply is retried during the next agent run.';
Visible = RetrySendingVisible;

trigger OnAction()
var
SOAReplyRetryMgt: Codeunit "SOA Reply Retry Mgt.";
begin
if not Confirm(RetrySendingQst) then
exit;

SOAReplyRetryMgt.ResetAttempts(Rec."Task ID", Rec.ID);
Message(RetrySendingScheduledMsg);
UpdateControls();
end;
}
}
area(Promoted)
{
group(Category_Process)
Comment thread
qasimikram marked this conversation as resolved.
{
Caption = 'Process';

actionref(RetrySending_Promoted; RetrySending)
{
}
}
}
}

trigger OnAfterGetRecord()
begin
UpdateControls();
Expand All @@ -256,11 +310,17 @@ page 4404 "SOA Email Message"

local procedure UpdateControls()
var
SOAReplyRetryMgt: Codeunit "SOA Reply Retry Mgt.";
EmailAddress: Text;
begin
UpdatePageCaption();
UpdateEmailFields(EmailAddress);
UpdateContactInformation(EmailAddress);
RetrySendingVisible := (Rec.Type = Rec.Type::Output) and (Rec.Status = Rec.Status::Reviewed) and SOAReplyRetryMgt.IsExhausted(Rec."Task ID", Rec.ID);
if RetrySendingVisible then
SendingStatusTxt := SendingFailedTxt
else
Clear(SendingStatusTxt);
CurrPage.Attachments.Page.LoadRecords(Rec);
end;

Expand Down Expand Up @@ -422,8 +482,13 @@ page 4404 "SOA Email Message"
ShowAttachmentTxt: Text;
AttachmentsVisible: Boolean;
BlockedStatusVisible: Boolean;
RetrySendingVisible: Boolean;
SendingStatusTxt: Text;
OutgoingMessageTxt: Label 'Outgoing email';
IncomingMessageTxt: Label 'Incoming email';
SelectContactOrCreateLbl: Label 'Select an existing contact, or create a new one';
ShowAttachmentLbl: Label 'Show attachments (%1)', Comment = '%1 = Attachment count';
SendingFailedTxt: Label 'Failed to send';
RetrySendingQst: Label 'Do you want to retry sending this reply?';
RetrySendingScheduledMsg: Label 'The reply will be retried during the next agent run.';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

#pragma warning disable AS0007
namespace Microsoft.Agent.SalesOrderAgent;

using System.Agents;

table 4589 "SOA Reply Attempt"
{
Access = Internal;
DataClassification = SystemMetadata;
InherentEntitlements = RIMDX;
InherentPermissions = RIMDX;
ReplicateData = false;

fields
{
field(1; "Task ID"; BigInteger)
{
DataClassification = SystemMetadata;
TableRelation = "Agent Task".ID;
}
field(2; "Message ID"; Guid)
{
DataClassification = SystemMetadata;
}
field(3; "Attempt Count"; Integer)
{
DataClassification = SystemMetadata;
}
Comment thread
qasimikram marked this conversation as resolved.
}

keys
{
key(Key1; "Task ID", "Message ID")
{
Clustered = true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

#pragma warning disable AS0007
namespace Microsoft.Agent.SalesOrderAgent;

using System.Agents;

codeunit 4418 "SOA Reply Retry Mgt."
{
Access = Internal;
Comment thread
qasimikram marked this conversation as resolved.
InherentEntitlements = X;
InherentPermissions = X;
Permissions = tabledata "SOA Reply Attempt" = RIMD;

var
ReplyNotAuthorizedErr: Label 'You are not authorized to send this reply.';

internal procedure RegisterFailedAttempt(TaskId: BigInteger; MessageId: Guid)
var
SOAReplyAttempt: Record "SOA Reply Attempt";
begin
SOAReplyAttempt.LockTable();
if SOAReplyAttempt.Get(TaskId, MessageId) then begin
if SOAReplyAttempt."Attempt Count" < GetMaxAttempts() then begin
SOAReplyAttempt."Attempt Count" += 1;
SOAReplyAttempt.Modify();
end;
end else begin
SOAReplyAttempt."Task ID" := TaskId;
SOAReplyAttempt."Message ID" := MessageId;
SOAReplyAttempt."Attempt Count" := 1;
SOAReplyAttempt.Insert();
end;
end;

internal procedure ResetAttempts(TaskId: BigInteger; MessageId: Guid)
var
AgentTaskMessage: Record "Agent Task Message";
begin
AgentTaskMessage.Get(TaskId, MessageId);
ValidateMessageAccess(AgentTaskMessage);

ClearAttempts(TaskId, MessageId);
end;

internal procedure IsExhausted(TaskId: BigInteger; MessageId: Guid): Boolean
var
SOAReplyAttempt: Record "SOA Reply Attempt";
begin
if not SOAReplyAttempt.Get(TaskId, MessageId) then
exit(false);

exit(SOAReplyAttempt."Attempt Count" >= GetMaxAttempts());
end;

internal procedure ClearAttempts(TaskId: BigInteger; MessageId: Guid)
var
SOAReplyAttempt: Record "SOA Reply Attempt";
begin
if SOAReplyAttempt.Get(TaskId, MessageId) then
SOAReplyAttempt.Delete();
end;

internal procedure GetMaxAttempts(): Integer
begin
exit(5);
end;

local procedure ValidateMessageAccess(AgentTaskMessage: Record "Agent Task Message")
var
SOASetup: Record "SOA Setup";
begin
ValidateMessageAccess(AgentTaskMessage, SOASetup);
end;

local procedure ValidateMessageAccess(AgentTaskMessage: Record "Agent Task Message"; var SOASetup: Record "SOA Setup")
var
OwnerUserSecurityID: Guid;
begin
SOASetup.GetBasedOnAgentUserSecurityID(AgentTaskMessage."Agent User Security ID", true);
OwnerUserSecurityID := SOASetup."Owner User Security ID";
if IsNullGuid(OwnerUserSecurityID) then
OwnerUserSecurityID := SOASetup."User Security ID";

if (UserSecurityId() <> OwnerUserSecurityID) and (UserSecurityId() <> SOASetup."User Security ID") then
Error(ReplyNotAuthorizedErr);
end;

[EventSubscriber(ObjectType::Table, Database::"Agent Task Message", 'OnAfterDeleteEvent', '', false, false)]
local procedure DeleteAttemptsOnAfterDeleteAgentTaskMessage(var Rec: Record "Agent Task Message"; RunTrigger: Boolean)
begin
if Rec.IsTemporary() then
Comment thread
qasimikram marked this conversation as resolved.
exit;

if Rec.Type <> Rec.Type::Output then
exit;

ClearAttempts(Rec."Task ID", Rec.ID);
end;
}
Loading
Loading