Table 6751 Reminder Action Group
- App
- Base Application
- Namespace
- Microsoft.Sales.Reminder
- Versions
- 24-28
Fields, 7Keys, 1Procedures, 16
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Sales/Reminder/Automation/ReminderActionGroup.Table.al346 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.Sales.Reminder;
using System.Threading;
/// <summary>
/// Manages a group of reminder automation actions with scheduling and job queue integration.
/// </summary>
table 6751 "Reminder Action Group"
{
DataClassification = CustomerContent;
Caption = 'Reminder Automation Group';
DrillDownPageId = "Reminder Automation List";
LookupPageId = "Reminder Automation List";
fields
{
/// <summary>
/// Specifies the unique code identifying this reminder automation group.
/// </summary>
field(1; Code; Code[50])
{
ToolTip = 'Specifies a code that identifies a reminder action group.';
}
/// <summary>
/// Specifies a description of the automation group.
/// </summary>
field(2; Description; Text[100])
{
ToolTip = 'Specifies a description for the reminder action group.';
}
/// <summary>
/// Specifies the execution schedule type: manual, weekly, monthly, or custom.
/// </summary>
field(3; Schedule; Enum "Reminder Action Schedule")
{
ToolTip = 'Specifies the cadence of the automation job. The cadence determines how often the automation job is run.';
}
/// <summary>
/// Specifies the date and time when the automation should first run.
/// </summary>
field(4; "Start DateTime"; DateTime)
{
ToolTip = 'Specifies the date and time when the automation job is started for the first time.';
}
/// <summary>
/// Specifies the date formula for calculating the next run date when using custom schedule.
/// </summary>
field(6; "Next Run Date Formula"; DateFormula)
{
ToolTip = 'Specifies the formula that is used to calculate the date and time when the automation job is run next time.';
}
/// <summary>
/// Indicates whether this automation group is blocked from execution.
/// </summary>
field(7; Blocked; Boolean)
{
ToolTip = 'Specifies whether the reminder action group is blocked. Blocked reminder action groups cannot be used in the system.';
}
/// <summary>
/// Stores the filter string of selected reminder terms codes for this automation group.
/// </summary>
field(12; "Reminder Terms"; Blob)
{
}
}
keys
{
key(Key1; Code)
{
Clustered = true;
}
}
/// <summary>
/// Gets the stored reminder terms selection filter text.
/// </summary>
/// <returns>The reminder terms selection filter text.</returns>
procedure GetReminderTermsSelectionFilter(): Text
var
SelectionFilterInStream: InStream;
SelectionFilterText: Text;
begin
Clear(SelectionFilterText);
CalcFields("Reminder Terms");
Rec."Reminder Terms".CreateInStream(SelectionFilterInStream, TextEncoding::UTF16);
if not Rec."Reminder Terms".HasValue() then
exit;
SelectionFilterInStream.ReadText(SelectionFilterText);
exit(SelectionFilterText);
end;
/// <summary>
/// Sets the reminder terms selection filter text.
/// </summary>
/// <param name="SelectionFilterText">The filter text to store for selecting reminder terms.</param>
procedure SetReminderTermsSelectionFilter(SelectionFilterText: Text)
var
SelectionFilterOutStream: OutStream;
begin
if SelectionFilterText = '' then begin
Clear(Rec."Reminder Terms");
Rec.Modify();
exit;
end;
Clear(Rec."Reminder Terms");
Rec."Reminder Terms".CreateOutStream(SelectionFilterOutStream, TextEncoding::UTF16);
SelectionFilterOutStream.WriteText(SelectionFilterText);
Rec.Modify();
end;
internal procedure GetNextRunDate(): DateTime
var
NextDate: Date;
begin
case Rec.Schedule of
Rec.Schedule::Manual:
exit(0DT);
Rec.Schedule::Monthly:
begin
NextDate := CalcDate('<+1M>', DT2Date(Rec."Start DateTime"));
exit(CreateDateTime(NextDate, DT2Time(Rec."Start DateTime")));
end;
Rec.Schedule::Weekly:
begin
NextDate := CalcDate('<+1W>', DT2Date(Rec."Start DateTime"));
exit(CreateDateTime(NextDate, DT2Time(Rec."Start DateTime")));
end;
Rec.Schedule::"Custom schedule":
begin
NextDate := CalcDate(Rec."Next Run Date Formula", DT2Date(Rec."Start DateTime"));
exit(CreateDateTime(NextDate, DT2Time(Rec."Start DateTime")));
end;
end;
exit(0DT);
end;
internal procedure GetLastRunStatusText(): Text
var
ReminderActionGroupLog: Record "Reminder Action Group Log";
ReminderActionProgress: Codeunit "Reminder Action Progress";
begin
if not ReminderActionProgress.GetLastEntryForGroup(Rec.Code, ReminderActionGroupLog) then
exit('');
exit(StrSubstNo(ReminderActionStatusLbl, ReminderActionGroupLog.Status, Format(ReminderActionGroupLog.SystemCreatedAt)));
end;
internal procedure VerifyDefinition()
var
ReminderAction: Record "Reminder Action";
ReminderActionInterface: Interface "Reminder Action";
begin
ReminderAction.SetRange("Reminder Action Group Code", Rec.Code);
if not ReminderAction.FindSet() then
Error(NoReminderActionsAreDefinedErr);
if GetReminderTermsSelectionFilter() = '' then
Error(NoReminderTermsAreDefinedErr);
repeat
ReminderActionInterface := ReminderAction.GetReminderActionInterface();
ReminderActionInterface.Initialize(ReminderAction.SystemId);
ReminderActionInterface.ValidateSetup();
until ReminderAction.Next() = 0;
end;
internal procedure ShowHistory()
var
ReminderActionGroupLog: Record "Reminder Action Group Log";
begin
ReminderActionGroupLog.SetCurrentKey("Run Id");
ReminderActionGroupLog.Ascending(false);
ReminderActionGroupLog.SetRange("Reminder Action Group ID", Rec.Code);
Page.Run(Page::"Reminder Action History", ReminderActionGroupLog);
end;
/// <summary>
/// Schedules the automation job for this action group in the job queue.
/// </summary>
/// <param name="ReminderActionGroup">The reminder action group to schedule.</param>
procedure ScheduleAutomationJob(var ReminderActionGroup: Record "Reminder Action Group")
var
JobQueueEntry: Record "Job Queue Entry";
begin
CreateUniqueJobQueue(ReminderActionGroup, JobQueueEntry);
JobQueueEntry.SetStatus(JobQueueEntry.Status::Ready);
end;
/// <summary>
/// Creates or updates a unique job queue entry for the automation group.
/// </summary>
/// <param name="ReminderActionGroup">The reminder action group for the job queue entry.</param>
/// <param name="JobQueueEntry">Returns the created or updated job queue entry.</param>
procedure CreateUniqueJobQueue(var ReminderActionGroup: Record "Reminder Action Group"; var JobQueueEntry: Record "Job Queue Entry")
var
JobQueueExist: Boolean;
begin
JobQueueExist := GetJobQueueEntry(JobQueueEntry);
if JobQueueExist then
if JobQueueEntry.Status = JobQueueEntry.Status::"In Process" then
Error(JobQueueIsRunningErr);
JobQueueEntry."Object Type to Run" := JobQueueEntry."Object Type to Run"::Codeunit;
JobQueueEntry."Object ID to Run" := Codeunit::"Reminders Automation Job";
JobQueueEntry."Rerun Delay (sec.)" := 1;
JobQueueEntry."Maximum No. of Attempts to Run" := 3;
JobQueueEntry."Recurring Job" := true;
if ReminderActionGroup.Schedule = ReminderActionGroup.Schedule::Manual then
JobQueueEntry."Recurring Job" := false;
JobQueueEntry."Record ID to Process" := ReminderActionGroup.RecordId;
JobQueueEntry.Status := JobQueueEntry.Status::"On Hold";
JobQueueEntry."Job Queue Category Code" := JobQueueCategoryCodeTxt;
JobQueueEntry."Earliest Start Date/Time" := Rec.GetNextRunDate();
Clear(JobQueueEntry."Error Message");
Clear(JobQueueEntry."Error Message Register Id");
JobQueueEntry.Description := CopyStr(StrSubstNo(JobQueueEntryDescTxt, ReminderActionGroup.Code), 1, MaxStrLen(JobQueueEntry.Description));
if JobQueueExist then
JobQueueEntry.Modify(true)
else
JobQueueEntry.Insert(true);
end;
internal procedure GetJobQueueEntry(var JobQueueEntry: Record "Job Queue Entry"): Boolean
begin
JobQueueEntry.SetRange("Object Type to Run", JobQueueEntry."Object Type to Run"::Codeunit);
JobQueueEntry.SetRange("Object ID to Run", Codeunit::"Reminders Automation Job");
JobQueueEntry.SetRange("Record ID to Process", Rec.RecordId);
exit(JobQueueEntry.FindFirst());
end;
internal procedure GetStatus(var StatusMessage: Text; var ErrorText: Text)
var
JobQueueEntry: Record "Job Queue Entry";
begin
if Rec.Blocked then begin
StatusMessage := BlockedManuallyTxt;
exit;
end;
if GetJobQueueEntry(JobQueueEntry) then
case JobQueueEntry.Status of
JobQueueEntry.Status::Error:
begin
StatusMessage := ErrorTok;
ErrorText := JobQueueEntry."Error Message";
end;
JobQueueEntry.Status::"On Hold":
StatusMessage := OnHoldTxt;
JobQueueEntry.Status::Ready:
if Rec.Schedule = Rec.Schedule::Manual then
StatusMessage := StrSubstNo(ScheduledTxt, SingleRunTxt)
else
StatusMessage := StrSubstNo(ScheduledTxt, LowerCase(Format(Rec.Schedule)));
JobQueueEntry.Status::"In Process":
StatusMessage := RunningTok;
end
else
StatusMessage := OnHoldTxt;
end;
internal procedure InProgress(): Boolean
var
JobQueueEntry: Record "Job Queue Entry";
begin
if not GetJobQueueEntry(JobQueueEntry) then
exit(false);
exit(JobQueueEntry.Status = JobQueueEntry.Status::"In Process");
end;
internal procedure GetNextStartDate(): Text
var
JobQueueEntry: Record "Job Queue Entry";
begin
if not Rec.GetJobQueueEntry(JobQueueEntry) then
exit('');
if JobQueueEntry.Status in [JobQueueEntry.Status::Ready, JobQueueEntry.Status::"In Process"] then
exit(Format(JobQueueEntry."Earliest Start Date/Time"));
exit('');
end;
internal procedure PauseJobQueueEntry()
var
JobQueueEntry: Record "Job Queue Entry";
begin
if not Rec.GetJobQueueEntry(JobQueueEntry) then
exit;
if JobQueueEntry.Status = JobQueueEntry.Status::"In Process" then
Error(JobQueueIsRunningErr);
JobQueueEntry.SetStatus(JobQueueEntry.Status::"On Hold");
end;
internal procedure GetNumberOfActiveErrors(): Integer
var
ReminderAutomationError: Record "Reminder Automation Error";
begin
GetActiveErrors(ReminderAutomationError);
exit(ReminderAutomationError.Count());
end;
internal procedure GetActiveErrors(var ReminderAutomationError: Record "Reminder Automation Error")
begin
ReminderAutomationError.SetRange("Reminder Action Group Code", Rec.Code);
ReminderAutomationError.SetRange(Dismissed, false);
end;
internal procedure GetFeatureTelemetryName(): Text
begin
exit('Reminder Automation');
end;
trigger OnDelete()
var
ReminderAction: Record "Reminder Action";
begin
ReminderAction.SetRange("Reminder Action Group Code", Rec.Code);
ReminderAction.DeleteAll(true);
end;
var
OnHoldTxt: Label 'On Hold';
ErrorTok: Label 'Error';
JobQueueIsRunningErr: Label 'Job queue entry is running';
ScheduledTxt: Label 'Scheduled %1', Comment = '%1 - is a text that can be (single run) or (weekly, monthly, custom)';
SingleRunTxt: Label 'single run';
RunningTok: Label 'Running';
BlockedManuallyTxt: Label 'Blocked manually';
JobQueueCategoryCodeTxt: Label 'REMINDERS', Comment = 'Job Queue Category Code for Reminder Automation, abreviated to 10 characters', MaxLength = 10;
JobQueueEntryDescTxt: Label 'Reminder Automation - %1.', Comment = '%1 - Code of the Reminder Action Group';
ReminderActionStatusLbl: Label 'Status: %1. Completed on: %2', Comment = '%1 - Status, succeded, failed etc... %2 - When it was completed';
NoReminderActionsAreDefinedErr: Label 'No actions are defined for this reminder action group.';
NoReminderTermsAreDefinedErr: Label 'No reminder terms are selected for this reminder action group. Please select reminder terms under Reminder Terms Filter.';
}