Das Codeunit-Objekt der Erweiterungsverwaltung für Debitorenbelohnungen erstellen
Die Codeunit „Erweiterungsverwaltung für Debitorenbelohnungen“ enthält den größten Teil der Logik und Funktionalität, die für die Debitorenbelohnungserweiterung erforderlich sind. Diese Codeunit enthält Beispiele dafür, wie Sie Ereignisse verwenden können, um auf bestimmte Aktionen oder Verhaltensweisen in Ihrer Erweiterung zu reagieren.
Diese Erweiterung enthält die Anforderung, einen externen Dienst oder eine externe API aufzurufen, um die vom Benutzer eingegebenen Aktivierungscodes zu überprüfen. In der Regel schließen Sie diese Überprüfung ab, indem Sie Prozeduren definieren, die den Aktivierungscode ausführen, und dann die API aufrufen. Anstatt dieses Ansatzes können Sie auch Ereignisse in AL verwenden.
Erstellen Sie eine neue Datei mit dem Namen CustomerRewardsExtMgt.Codeunit.al, um eine neue Codeunit in Ihrem Projekt zu erstellen.
Fügen Sie als Nächstes der Codeunit folgenden Code hinzu:
codeunit 50101 "Customer Rewards Ext. Mgt"
{
EventSubscriberInstance = StaticAutomatic;
// Determines if the extension is activated
procedure IsCustomerRewardsActivated(): Boolean;
var
ActivationCodeInformation: Record "Activation Code Information";
begin
if not ActivationCodeInformation.FindFirst() then
exit(false);
if (ActivationCodeInformation."Date Activated" <= Today) and (Today <= ActivationCodeInformation."Expiration Date") then
exit(true);
exit(false);
end;
// Opens the Customer Rewards Assisted Setup Guide
procedure OpenCustomerRewardsWizard();
var
CustomerRewardsWizard: Page "Customer Rewards Wizard";
begin
CustomerRewardsWizard.RunModal();
end;
// Opens the Reward Level page
procedure OpenRewardsLevelPage();
var
RewardsLevelList: Page "Rewards Level List";
begin
RewardsLevelList.Run();
end;
// Determines the corresponding reward level and returns it
procedure GetRewardLevel(RewardPoints: Integer) RewardLevelTxt: Text;
var
RewardLevel: Record "Reward Level";
MinRewardLevelPoints: Integer;
begin
RewardLevelTxt := NoRewardlevelTxt;
if RewardLevel.IsEmpty() then
exit;
RewardLevel.SetRange("Minimum Reward Points", 0, RewardPoints);
RewardLevel.SetCurrentKey("Minimum Reward Points"); // sorted in ascending order
if not RewardLevel.FindFirst() then
exit;
MinRewardLevelPoints := RewardLevel."Minimum Reward Points";
if RewardPoints >= MinRewardLevelPoints then begin
RewardLevel.Reset();
RewardLevel.SetRange("Minimum Reward Points", MinRewardLevelPoints, RewardPoints);
RewardLevel.SetCurrentKey("Minimum Reward Points"); // sorted in ascending order
RewardLevel.FindLast();
RewardLevelTxt := RewardLevel.Level;
end;
end;
// Activates Customer Rewards if activation code is validated successfully
procedure ActivateCustomerRewards(ActivationCode: Text): Boolean;
var
ActivationCodeInformation: Record "Activation Code Information";
begin
// raise event
OnGetActivationCodeStatusFromServer(ActivationCode);
exit(ActivationCodeInformation.Get(ActivationCode));
end;
// publishes event
[IntegrationEvent(false, false)]
procedure OnGetActivationCodeStatusFromServer(ActivationCode: Text);
begin
end;
// Subscribes to OnGetActivationCodeStatusFromServer event and handles it when the event is raised
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Customer Rewards Ext Mgt", 'OnGetActivationCodeStatusFromServer', '', false, false)]
local procedure OnGetActivationCodeStatusFromServerSubscriber(ActivationCode: Text);
var
ActivationCodeInfo: Record "Activation Code Information";
ResponseText: Text;
Result: JsonToken;
JsonRepsonse: JsonToken;
begin
if not CanHandle() then
exit; // use the mock
// Get response from external service and update activation code information if successful
if (GetHttpResponse(ActivationCode, ResponseText)) then begin
JsonRepsonse.ReadFrom(ResponseText);
if (JsonRepsonse.SelectToken('ActivationResponse', Result)) then
if (Result.AsValue().AsText() = 'Success') then begin
if (ActivationCodeInfo.FindFirst()) then
ActivationCodeInfo.Delete();
ActivationCodeInfo.Init();
ActivationCodeInfo.ActivationCode := ActivationCode;
ActivationCodeInfo."Date Activated" := Today;
ActivationCodeInfo."Expiration Date" := CALCDATE('<1Y>', Today);
ActivationCodeInfo.Insert();
end;
end;
end;
// Helper method to make calls to a service to validate activation code
local procedure GetHttpResponse(ActivationCode: Text; var ResponseText: Text): Boolean;
begin
// You will typically make external calls / http requests to your service to validate the activation code
// here but for the sample extension we simply return a successful dummy response
if ActivationCode = '' then
exit(false);
ResponseText := DummySuccessResponseTxt;
exit(true);
end;
// Subscribes to the OnAfterReleaseSalesDoc event and increases reward points for the sell to customer in posted sales order
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Release Sales Document", 'OnAfterReleaseSalesDoc', '', false, false)]
local procedure OnAfterReleaseSalesDocSubscriber(VAR SalesHeader: Record "Sales Header"; PreviewMode: Boolean; LinesWereModified: Boolean);
var
Customer: Record Customer;
begin
if SalesHeader.Status <> SalesHeader.Status::Released then
exit;
Customer.Get(SalesHeader."Sell-to Customer No.");
Customer.RewardPoints += 1; // Add a point for each new sales order
Customer.Modify();
end;
// Checks if the current codeunit is allowed to handle Customer Rewards Activation requests rather than a mock.
local procedure CanHandle(): Boolean;
var
CustomerRewardsMgtSetup: Record "Customer Rewards Mgt Setup";
begin
if CustomerRewardsMgtSetup.Get() then
exit(CustomerRewardsMgtSetup."Cust. Rew. Ext. Mgt. Cod. ID" = CODEUNIT::"Customer Rewards Ext Mgt");
exit(false);
end;
var
DummySuccessResponseTxt: Label '{"ActivationResponse": "Success"}', Locked = true;
NoRewardlevelTxt: TextConst ENU = 'NONE';
}
In den folgenden Abschnitten wird der Code aus der Codeunit Schritt für Schritt untersucht.
Die Eigenschaft EventSubscriberInstance legt fest, wie Ereignisabonnentenmethoden in einer Codeunit an die Codeunit-Instanz und die Ereignisse gebunden sind, die sie abonnieren. In diesem Beispiel wurde die Eigenschaft auf StaticAutomatic festgelegt. Dies bedeutet, dass Abonnenten statisch an Ereignisse gebunden sind und die Codeunit-Instanzen vom System gesteuert werden. Dies ist der Standardwert.
codeunit 50101 "Customer Rewards Ext Mgt"
{
EventSubscriberInstance = StaticAutomatic;
Es wurde die Ereignisherausgebermethode OnGetActivationCodeStatusFromServer definiert, die den vom Benutzer als Parameter eingegebenen Aktivierungscode akzeptiert. Darüber wurde die Abonnentenmethode OnGetActivationCodeStatusFromServerSubscriber definiert, um das Ereignis zu überwachen und zu verarbeiten.
// publishes event
[IntegrationEvent(false, false)]
procedure OnGetActivationCodeStatusFromServer(ActivationCode: Text);
begin
end;
al-languageCopy
// Subscribes to OnGetActivationCodeStatusFromServer event and handles it when the event is raised
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Customer Rewards Ext Mgt", 'OnGetActivationCodeStatusFromServer', '', false, false)]
local procedure OnGetActivationCodeStatusFromServerSubscriber(ActivationCode: Text);
var
ActivationCodeInfo: Record "Activation Code Information";
ResponseText: Text;
Result: JsonToken;
JsonRepsonse: JsonToken;
begin
if not CanHandle() then
exit; // use the mock
// Get response from external service and update activation code information if successful
if (GetHttpResponse(ActivationCode, ResponseText)) then begin
JsonRepsonse.ReadFrom(ResponseText);
if (JsonRepsonse.SelectToken('ActivationResponse', Result)) then
if (Result.AsValue().AsText() = 'Success') then begin
if (ActivationCodeInfo.FindFirst()) then
ActivationCodeInfo.Delete();
ActivationCodeInfo.Init();
ActivationCodeInfo.ActivationCode := ActivationCode;
ActivationCodeInfo."Date Activated" := Today;
ActivationCodeInfo."Expiration Date" := CALCDATE('<1Y>', Today);
ActivationCodeInfo.Insert();
end;
end;
end;
Beim Ausführen der Prozedur ActivateCustomerRewards wird das Ereignis OnGetActivationCodeStatusFromServer ausgelöst.
// Activates Customer Rewards if activation code is validated successfully
procedure ActivateCustomerRewards(ActivationCode: Text): Boolean;
var
ActivationCodeInformation: Record "Activation Code Information";
begin
// raise event
OnGetActivationCodeStatusFromServer(ActivationCode);
exit(ActivationCodeInformation.Get(ActivationCode));
end;
Da die Eigenschaft EventSubscriberInstance für die Codeunit standardmäßig auf Static-Automatic festgelegt ist, wird die Prozedur OnGetActivationCodeStatusFromServerSubscriber aufgerufen.
In dieser Prozedur behandeln Sie das ausgelöste Ereignis, indem Sie zunächst überprüfen, ob die aktuelle Codeunit für die Verarbeitung dieses Ereignisses definiert wurde.
if not CanHandle() then
exit; // use the mock
al-languageCopy
// Checks if the current codeunit is allowed to handle Customer Rewards Activation requests rather than a mock.
local procedure CanHandle(): Boolean;
var
CustomerRewardsMgtSetup: Record "Customer Rewards Mgt Setup";
begin
if CustomerRewardsMgtSetup.Get() then
exit(CustomerRewardsMgtSetup."Cust. Rew. Ext. Mgt. Cod. ID" = CODEUNIT::"Customer Rewards Ext Mgt");
exit(false);
end;
Wenn die Codeunit das Ereignis verarbeiten kann, wird die GetHttpResponse-Hilfsprozedur aufgerufen, um den Aktivierungscode zu überprüfen. Je nach Antwort werden Kundenbelohnungen aktiviert oder nicht.
// Get response from external service and update activation code information if successful
if (GetHttpResponse(ActivationCode, ResponseText)) then begin
JsonRepsonse.ReadFrom(ResponseText);
// Helper method to make calls to a service to validate activation code
local procedure GetHttpResponse(ActivationCode: Text; var ResponseText: Text): Boolean;
begin
// You will typically make external calls / http requests to your service to validate the activation code
// here but for the sample extension we simply return a successful dummy response
if ActivationCode = '' then
exit(false);
ResponseText := DummySuccessResponseTxt;
exit(true);
end;
Wenn die Erweiterung einen Dienst mithilfe von Ereignissen aufruft, können Sie das Verhalten dessen simulieren, was beim Auslösen von Ereignissen geschieht.
Die Prozedur IsCustomerRewardsActivated sucht in der Tabelle mit den Activation Code Information nach einem Aktivierungscode und überprüft außerdem, ob dieser Code aktiv oder abgelaufen ist.
// Determines if the extension is activated
procedure IsCustomerRewardsActivated(): Boolean;
var
ActivationCodeInformation: Record "Activation Code Information";
begin
if not ActivationCodeInformation.FindFirst() then
exit(false);
if (ActivationCodeInformation."Date Activated" <= Today) and (Today <= ActivationCodeInformation."Expiration Date") then
exit(true);
exit(false);
end;
Auf diese Prozedur wird auf der Seite Reward Level List und in der Seitenerweiterung Debitorenlistenerw. verwiesen.
Die Prozedur OpenCustomerRewardsWizard führt die Seite Assistent für Debitorenbelohnungen aus:
// Opens the Customer Rewards Assisted Setup Guide
procedure OpenCustomerRewardsWizard();
var
CustomerRewardsWizard: Page "Customer Rewards Wizard";
begin
CustomerRewardsWizard.RunModal();
end;
Diese Seite wird in einem späteren Modul erstellt, daher wird sie vorerst nicht kompiliert. Sie können die Prozedur auskommentieren und die Kommentare entfernen, nachdem Sie die Erweiterung getestet haben.
Die Prozedur OpenRewardsLevelPage öffnet die Seite Reward Level List.
// Opens the Reward Level page
procedure OpenRewardsLevelPage();
var
RewardsLevelList: Page "Rewards Level List";
begin
RewardsLevelList.Run();
end;
Die folgenden Objekte verweisen auf diese Prozedur:
Seitenerweiterung Debitorenlistenerweiterung
Seite Customer Rewards Wizard
Die Prozedur GetRewardLevel bestimmt den entsprechende Reward-Level und gibt sie dann zurück.
// Determines the corresponding reward level and returns it
procedure GetRewardLevel(RewardPoints: Integer) RewardLevelTxt: Text;
var
RewardLevel: Record "Reward Level";
MinRewardLevelPoints: Integer;
begin
RewardLevelTxt := NoRewardlevelTxt;
if RewardLevel.IsEmpty() then
exit;
RewardLevel.SetRange("Minimum Reward Points", 0, RewardPoints);
RewardLevel.SetCurrentKey("Minimum Reward Points"); // sorted in ascending order
if not RewardLevel.FindFirst() then
exit;
MinRewardLevelPoints := RewardLevel."Minimum Reward Points";
if RewardPoints >= MinRewardLevelPoints then begin
RewardLevel.Reset();
RewardLevel.SetRange("Minimum Reward Points", MinRewardLevelPoints, RewardPoints);
RewardLevel.SetCurrentKey("Minimum Reward Points"); // sorted in ascending order
RewardLevel.FindLast();
RewardLevelTxt := RewardLevel.Level;
end;
end;
Auf diese Prozedur wird von der Seitenerweiterung Debitorenkartenerweiterung verwiesen.
Schließlich wird die Prozedur OnAfterReleaseSalesDocSubscriber ausgeführt.
// Subscribes to the OnAfterReleaseSalesDoc event and increases reward points for the sell to customer in posted sales order
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Release Sales Document", 'OnAfterReleaseSalesDoc', '', false, false)]
local procedure OnAfterReleaseSalesDocSubscriber(VAR SalesHeader: Record "Sales Header"; PreviewMode: Boolean; LinesWereModified: Boolean);
var
Customer: Record Customer;
begin
if SalesHeader.Status <> SalesHeader.Status::Released then
exit;
Customer.Get(SalesHeader."Sell-to Customer No.");
Customer.RewardPoints += 1; // Add a point for each new sales order
Customer.Modify();
end;
Die Prozedur wird ausgeführt, wenn ein Verkaufsbeleg freigegeben wird, da die Prozedur das Ereignis OnAfterReleaseSalesDoc in der Codeunit Verkaufsbeleg freigeben abonniert hat.
Die Prozedur fügt einem Debitoren einen Belohnungspunkt für jeden neuen Verkaufsauftrag hinzu. Die Belohnungspunkte für jeden Verkauf an einen Debitor werden für jeden gebuchten Verkaufsauftrag erhöht.