From a639ec8198f0e51ab288c1e249143e94b8c629ed Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Fri, 16 Jan 2026 09:10:29 +0000 Subject: [PATCH] Add support for retrieving merchant KPI data from API Introduced MerchantKpi DTO and related model mapping to enable fetching merchant KPI data from the backend API. Updated IEstateReportingApiClient and ApiClient with new GetMerchantKpi methods, and refactored DashboardRequestHandler to use real API data instead of stubs. Adjusted endpoint URLs and dependency injection as needed. This allows the UI to display live merchant KPI statistics. --- .../DataTransferObjects.cs | 10 +++++++ .../BackendAPI/IEstateReportingApiClient.cs | 28 ++++++++++++++++++- .../Client/APIModelFactory.cs | 10 +++++++ .../Client/MerchantMethods.cs | 27 ++++++++++++++++++ .../RequestHandlers/DateRequestHandler.cs | 15 ++++++++-- 5 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 EstateManagmentUI.BusinessLogic/Client/MerchantMethods.cs diff --git a/EstateManagmentUI.BusinessLogic/BackendAPI/DataTransferObjects/DataTransferObjects.cs b/EstateManagmentUI.BusinessLogic/BackendAPI/DataTransferObjects/DataTransferObjects.cs index 8028a740..898aed1e 100644 --- a/EstateManagmentUI.BusinessLogic/BackendAPI/DataTransferObjects/DataTransferObjects.cs +++ b/EstateManagmentUI.BusinessLogic/BackendAPI/DataTransferObjects/DataTransferObjects.cs @@ -11,4 +11,14 @@ public class ComparisonDate [JsonProperty("description")] public String Description { get; set; } } + + public class MerchantKpi + { + [JsonProperty("merchants_with_sale_in_last_hour")] + public Int32 MerchantsWithSaleInLastHour { get; set; } + [JsonProperty("merchants_with_no_sale_today")] + public Int32 MerchantsWithNoSaleToday { get; set; } + [JsonProperty("merchants_with_no_sale_in_last7_days")] + public Int32 MerchantsWithNoSaleInLast7Days { get; set; } + } } diff --git a/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs b/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs index 7bb37497..5980f44c 100644 --- a/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs +++ b/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs @@ -10,6 +10,7 @@ namespace EstateManagementUI.BusinessLogic.BackendAPI public interface IEstateReportingApiClient { Task>> GetComparisonDates(String accessToken, Guid estateId, CancellationToken cancellationToken); + Task> GetMerchantKpi(String accessToken, Guid estateId, CancellationToken cancellationToken); } public class EstateReportingApiClient : ClientProxyBase.ClientProxyBase, IEstateReportingApiClient { @@ -24,7 +25,7 @@ public EstateReportingApiClient(Func baseAddressResolver, public async Task>> GetComparisonDates(String accessToken, Guid estateId, CancellationToken cancellationToken) { - String requestUri = this.BuildRequestUrl("/api/dimensions/calendar/comparisondates"); + String requestUri = this.BuildRequestUrl("/api/calendars/comparisondates"); try { @@ -48,6 +49,31 @@ public async Task>> GetComparisonDates(String access } } + public async Task> GetMerchantKpi(String accessToken, Guid estateId, CancellationToken cancellationToken) + { + String requestUri = this.BuildRequestUrl("/api/merchants/kpis"); + + try + { + List<(String headerName, String headerValue)> additionalHeaders = [ + (EstateIdHeaderName, estateId.ToString()) + ]; + Result? result = await this.SendHttpGetRequest(requestUri, accessToken, additionalHeaders, cancellationToken); + + if (result.IsFailed) + return ResultHelpers.CreateFailure(result); + + return result; + } + catch (Exception ex) + { + // An exception has occurred, add some additional information to the message + Exception exception = new Exception($"Error getting merchant kpis for estate {estateId}.", ex); + + return Result.Failure(exception.Message); + } + } + private String BuildRequestUrl(String route) { String baseAddress = this.BaseAddressResolver("EstateReportingApi"); diff --git a/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs b/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs index a6e4df53..3e423141 100644 --- a/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs +++ b/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs @@ -20,4 +20,14 @@ public static List ConvertFrom(List apiResu return comparisonDates; } + + public static MerchantKpiModel ConvertFrom(MerchantKpi apiResult) { + MerchantKpiModel model = new MerchantKpiModel { + MerchantsWithNoSaleInLast7Days = apiResult.MerchantsWithNoSaleInLast7Days, + MerchantsWithNoSaleToday = apiResult.MerchantsWithNoSaleToday, + MerchantsWithSaleInLastHour = apiResult.MerchantsWithSaleInLastHour + }; + + return model; + } } \ No newline at end of file diff --git a/EstateManagmentUI.BusinessLogic/Client/MerchantMethods.cs b/EstateManagmentUI.BusinessLogic/Client/MerchantMethods.cs new file mode 100644 index 00000000..6c0bdba8 --- /dev/null +++ b/EstateManagmentUI.BusinessLogic/Client/MerchantMethods.cs @@ -0,0 +1,27 @@ +using EstateManagementUI.BusinessLogic.Models; +using Shared.Results; +using SimpleResults; + +namespace EstateManagementUI.BusinessLogic.Client +{ + public partial interface IApiClient + { + Task> GetMerchantKpi(String accessToken, Guid actionId, Guid estateId, CancellationToken cancellationToken); + } + + public partial class ApiClient : IApiClient { + public async Task> GetMerchantKpi(String accessToken, + Guid actionId, + Guid estateId, + CancellationToken cancellationToken) { + var apiResult = await this.EstateReportingApiClient.GetMerchantKpi(accessToken, estateId, cancellationToken); + + if (apiResult.IsFailed) + return ResultHelpers.CreateFailure(apiResult); + + MerchantKpiModel merchantKpiModel = APIModelFactory.ConvertFrom(apiResult.Data); + + return Result.Success(merchantKpiModel); + } + } +} diff --git a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs index 7b4895d4..c6b34659 100644 --- a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs +++ b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs @@ -5,6 +5,7 @@ using SimpleResults; using System.Threading.Tasks; using SecurityService.Client; +using SecurityService.DataTransferObjects.Responses; using Shared.Results; namespace EstateManagementUI.BusinessLogic.RequestHandlers @@ -261,10 +262,11 @@ public class DashboardRequestHandler : IRequestHandler>> { private readonly IApiClient ApiClient; + private readonly ISecurityServiceClient SecurityServiceClient; - public DashboardRequestHandler(IApiClient apiClient) - { + public DashboardRequestHandler(IApiClient apiClient, ISecurityServiceClient securityServiceClient) { this.ApiClient = apiClient; + this.SecurityServiceClient = securityServiceClient; } // Implementations similar to above handlers returning stub data @@ -290,7 +292,14 @@ public async Task>> Handle(Queries.GetT public async Task> Handle(Queries.GetMerchantKpiQuery request, CancellationToken cancellationToken) { - return Result.Success(StubTestData.GetMockMerchantKpi()); + + // Get a token here + Result? token = await this.SecurityServiceClient.GetToken("serviceClient", "d192cbc46d834d0da90e8a9d50ded543", cancellationToken); + if (token.IsFailed) + return ResultHelpers.CreateFailure(token); + + return await this.ApiClient.GetMerchantKpi(token.Data.AccessToken, request.CorrelationId.Value, request.EstateId, cancellationToken); + } public async Task> Handle(Queries.GetTodaysFailedSalesQuery request,