diff --git a/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyShopReview.Codeunit.al b/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyShopReview.Codeunit.al new file mode 100644 index 0000000000..e3bf80bddf --- /dev/null +++ b/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyShopReview.Codeunit.al @@ -0,0 +1,121 @@ +// ------------------------------------------------------------------------------------------------ +// 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.Shopify; + +codeunit 30407 "Shpfy Shop Review" +{ + Access = Internal; + + procedure OpenReviewLink(Notification: Notification) + var + StoreURL: Text; + begin + Hyperlink(GetReviewLink()); + + StoreURL := Notification.GetData(GetStoreNameKey()); + if StoreURL <> '' then + MarkStoreAsReviewed(StoreURL); + end; + + procedure OpenReviewLinkFromShop(StoreURL: Text) + begin + Hyperlink(GetReviewLink()); + + MarkStoreAsReviewed(StoreURL); + end; + + procedure MarkReviewCompleted(Notification: Notification) + var + StoreURL: Text; + begin + StoreURL := Notification.GetData(GetStoreNameKey()); + if StoreURL <> '' then + MarkStoreAsReviewed(StoreURL); + end; + + local procedure MarkStoreAsReviewed(StoreURL: Text) + var + RegisteredStore: Record "Shpfy Registered Store New"; + begin + if not RegisteredStore.Get(StoreURL) then + exit; + + RegisteredStore."Review Completed" := true; + RegisteredStore.Modify(true); + end; + + local procedure GetReviewLink(): Text + begin + exit('https://aka.ms/bcshopifyvote'); + end; + + procedure MaybeShowReviewReminder(StoreURL: Text) + var + RegisteredStore: Record "Shpfy Registered Store New"; + OrderHeader: Record "Shpfy Order Header"; + begin + if not RegisteredStore.Get(StoreURL) then + exit; + + if RegisteredStore."Review Completed" then + exit; + + if RegisteredStore."Review Prompt Date" <> 0D then + if RegisteredStore."Review Prompt Date" > CalcDate('<-60D>', Today()) then + exit; + + OrderHeader.SetRange(Processed, true); + if OrderHeader.Count() < GetReviewReminderMinimumProcessedOrders() then + exit; + + ShowReviewReminder(RegisteredStore); + end; + + local procedure ShowReviewReminder(var RegisteredStore: Record "Shpfy Registered Store New") + var + ReminderNotification: Notification; + begin + RegisteredStore."Review Prompt Date" := Today(); + RegisteredStore.Modify(true); + + ReminderNotification.Id := GetReviewReminderNotificationId(); + ReminderNotification.Message := ReviewReminderMessageTxt; + ReminderNotification.Scope := NotificationScope::LocalScope; + ReminderNotification.SetData(GetStoreNameKey(), RegisteredStore.Store); + ReminderNotification.AddAction(ReviewReminderReviewActionLbl, Codeunit::"Shpfy Shop Review", 'OpenReviewLink'); + ReminderNotification.AddAction(ReviewReminderAlreadyDidActionLbl, Codeunit::"Shpfy Shop Review", 'MarkReviewCompleted'); + ReminderNotification.Send(); + + LogReviewReminderTelemetry(); + end; + + local procedure LogReviewReminderTelemetry() + begin + Session.LogMessage('0000QN1', ReviewReminderTelemetryMsg, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok); + end; + + local procedure GetReviewReminderNotificationId(): Guid + begin + exit('5aab1677-6f6a-4f86-9eca-3ad3dfd986b2'); + end; + + local procedure GetReviewReminderMinimumProcessedOrders(): Integer + begin + exit(10); + end; + + local procedure GetStoreNameKey(): Text + begin + exit('StoreURL'); + end; + + var + ReviewReminderMessageTxt: Label 'Relying on the Shopify connector for integration? Leave a review in the Shopify App Store to help others discover it.'; + ReviewReminderReviewActionLbl: Label 'Review'; + ReviewReminderAlreadyDidActionLbl: Label 'Already did'; + ReviewReminderTelemetryMsg: Label 'Shopify review reminder notification displayed.', Locked = true; + CategoryTok: Label 'Shopify Integration', Locked = true; +} diff --git a/src/Apps/W1/Shopify/App/src/Base/Pages/ShpfyShopCard.Page.al b/src/Apps/W1/Shopify/App/src/Base/Pages/ShpfyShopCard.Page.al index f2a4f29844..5f37ee8cd8 100644 --- a/src/Apps/W1/Shopify/App/src/Base/Pages/ShpfyShopCard.Page.al +++ b/src/Apps/W1/Shopify/App/src/Base/Pages/ShpfyShopCard.Page.al @@ -926,6 +926,21 @@ page 30101 "Shpfy Shop Card" CommunicationMgt.ClearApiVersionCache(); end; } + action(LeaveReview) + { + ApplicationArea = All; + Caption = 'Leave a Review'; + Image = CustomerRating; + ToolTip = 'Open the Shopify App Store to leave a review for the Shopify connector.'; + + trigger OnAction() + var + ShopReview: Codeunit "Shpfy Shop Review"; + begin + ShopReview.OpenReviewLinkFromShop(Rec.GetStoreName()); + end; + } + } group(Sync) { @@ -1234,6 +1249,7 @@ page 30101 "Shpfy Shop Card" FeatureTelemetry: Codeunit "Feature Telemetry"; AuthenticationMgt: Codeunit "Shpfy Authentication Mgt."; CommunicationMgt: Codeunit "Shpfy Communication Mgt."; + ShopReview: Codeunit "Shpfy Shop Review"; ApiVersionExpiryDateTime: DateTime; begin FeatureTelemetry.LogUptake('0000HUU', 'Shopify', Enum::"Feature Uptake Status"::Discovered); @@ -1255,6 +1271,7 @@ page 30101 "Shpfy Shop Card" #if not CLEAN28 Rec.UpdateFulfillmentService(); #endif + ShopReview.MaybeShowReviewReminder(Rec.GetStoreName()); end; end; diff --git a/src/Apps/W1/Shopify/App/src/Integration/Tables/ShpfyRegisteredStoreNew.Table.al b/src/Apps/W1/Shopify/App/src/Integration/Tables/ShpfyRegisteredStoreNew.Table.al index 429750197a..2339618a1f 100644 --- a/src/Apps/W1/Shopify/App/src/Integration/Tables/ShpfyRegisteredStoreNew.Table.al +++ b/src/Apps/W1/Shopify/App/src/Integration/Tables/ShpfyRegisteredStoreNew.Table.al @@ -31,6 +31,16 @@ table 30138 "Shpfy Registered Store New" Caption = 'Actual Scope'; DataClassification = SystemMetadata; } + field(4; "Review Prompt Date"; Date) + { + Caption = 'Review Prompt Date'; + DataClassification = SystemMetadata; + } + field(5; "Review Completed"; Boolean) + { + Caption = 'Review Completed'; + DataClassification = SystemMetadata; + } } keys { diff --git a/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al b/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al index 71015f4309..9d4d610d05 100644 --- a/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al +++ b/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al @@ -373,6 +373,7 @@ permissionset 30104 "Shpfy - Objects" codeunit "Shpfy Shipping Events" = X, codeunit "Shpfy Shipping Methods" = X, codeunit "Shpfy Shop Mgt." = X, + codeunit "Shpfy Shop Review" = X, codeunit "Shpfy Skipped Record" = X, codeunit "Shpfy Staff Member API" = X, codeunit "Shpfy Suggest Payments" = X,