From fde4cce99fa0082afd3363605a6b01c9587439b8 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Wed, 28 Jan 2026 15:18:34 +0000 Subject: [PATCH] Refactor contract creation to use new command structure - Move contract creation from Commands.CreateContractCommand to ContractCommands.CreateContractCommand and update all usages. - Add CreateContract method to API client and implement backend call. - Update request handler and test mediator for new command. - Move contract creation logic from New.razor to New.razor.cs for better separation and maintainability. - Improve estate/operator ID handling and remove hardcoded access token. - Maintain UI state and error handling in new code-behind structure. --- .../Components/Pages/Contracts/New.razor | 92 ---------------- .../Components/Pages/Contracts/New.razor.cs | 100 ++++++++++++++++++ .../Client/ContractMethods.cs | 19 ++++ .../RequestHandlers/DateRequestHandler.cs | 6 +- .../Requests/Requests.cs | 6 +- .../Services/TestMediatorService.cs | 4 +- 6 files changed, 128 insertions(+), 99 deletions(-) create mode 100644 EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor.cs diff --git a/EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor b/EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor index a13890b0..1bc66ca9 100644 --- a/EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor +++ b/EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor @@ -95,95 +95,3 @@ - -@code { - private CreateContractFormModel model = new(); - private bool isSaving = false; - private bool isLoadingOperators = true; - private bool hasPermission = false; - private string? errorMessage; - private List? operators; - - protected override async Task OnAfterRenderAsync(bool firstRender) { - if (!firstRender) { - await base.OnAfterRenderAsync(firstRender); - return; - } - await RequirePermission(PermissionSection.Contract, PermissionFunction.Create); - await LoadOperators(); - } - - - private async Task LoadOperators() - { - try - { - isLoadingOperators = true; - var estateId = await GetEstateId(); - var result = await Mediator.Send(new OperatorQueries.GetOperatorsForDropDownQuery(CorrelationIdHelper.New(), estateId)); - if (result.IsSuccess) - { - operators = ModelFactory.ConvertFrom(result.Data); - } - } - finally - { - isLoadingOperators = false; - StateHasChanged(); - } - } - - private async Task HandleSubmit() - { - isSaving = true; - errorMessage = null; - - try - { - var estateId = Guid.Parse("11111111-1111-1111-1111-111111111111"); - var accessToken = "stubbed-token"; - - // Create contract - var createCommand = new Commands.CreateContractCommand( - CorrelationIdHelper.New(), - accessToken, - estateId, - model.Description!, - Guid.Parse(model.OperatorId!) - ); - - var createResult = await Mediator.Send(createCommand); - - if (!createResult.IsSuccess) - { - errorMessage = createResult.Message ?? "Failed to create contract"; - return; - } - - // Navigate to contracts list with success - NavigationManager.NavigateTo("/contracts"); - } - catch (Exception ex) - { - errorMessage = $"An error occurred: {ex.Message}"; - } - finally - { - isSaving = false; - } - } - - private void Cancel() - { - NavigationManager.NavigateTo("/contracts"); - } - - public class CreateContractFormModel - { - [Required(ErrorMessage = "Description is required")] - public string? Description { get; set; } - - [Required(ErrorMessage = "Operator is required")] - public string? OperatorId { get; set; } - } -} diff --git a/EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor.cs b/EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor.cs new file mode 100644 index 00000000..6657c060 --- /dev/null +++ b/EstateManagementUI.BlazorServer/Components/Pages/Contracts/New.razor.cs @@ -0,0 +1,100 @@ +using EstateManagementUI.BlazorServer.Factories; +using EstateManagementUI.BlazorServer.Permissions; +using EstateManagementUI.BusinessLogic.Requests; +using System.ComponentModel.DataAnnotations; +using EstateManagementUI.BlazorServer.Models; + +namespace EstateManagementUI.BlazorServer.Components.Pages.Contracts +{ + public partial class New + { + private CreateContractFormModel model = new(); + private bool isSaving = false; + private bool isLoadingOperators = true; + private bool hasPermission = false; + private string? errorMessage; + private List? operators; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (!firstRender) + { + await base.OnAfterRenderAsync(firstRender); + return; + } + await RequirePermission(PermissionSection.Contract, PermissionFunction.Create); + await LoadOperators(); + } + + + private async Task LoadOperators() + { + try + { + isLoadingOperators = true; + var estateId = await GetEstateId(); + var result = await Mediator.Send(new OperatorQueries.GetOperatorsForDropDownQuery(CorrelationIdHelper.New(), estateId)); + if (result.IsSuccess) + { + operators = ModelFactory.ConvertFrom(result.Data); + } + } + finally + { + isLoadingOperators = false; + StateHasChanged(); + } + } + + private async Task HandleSubmit() + { + isSaving = true; + errorMessage = null; + + try { + var estateId = await this.GetEstateId(); + + // Create contract + var createCommand = new ContractCommands.CreateContractCommand( + CorrelationIdHelper.New(), + estateId, + model.Description!, + Guid.Parse(model.OperatorId!) + ); + + var createResult = await Mediator.Send(createCommand); + + if (!createResult.IsSuccess) + { + errorMessage = createResult.Message ?? "Failed to create contract"; + return; + } + + // Navigate to contracts list with success + NavigationManager.NavigateTo("/contracts"); + } + catch (Exception ex) + { + errorMessage = $"An error occurred: {ex.Message}"; + } + finally + { + isSaving = false; + } + } + + private void Cancel() + { + NavigationManager.NavigateTo("/contracts"); + } + + public class CreateContractFormModel + { + [Required(ErrorMessage = "Description is required")] + public string? Description { get; set; } + + [Required(ErrorMessage = "Operator is required")] + public string? OperatorId { get; set; } + } + } +} diff --git a/EstateManagmentUI.BusinessLogic/Client/ContractMethods.cs b/EstateManagmentUI.BusinessLogic/Client/ContractMethods.cs index 57ae2d63..dca2ac9c 100644 --- a/EstateManagmentUI.BusinessLogic/Client/ContractMethods.cs +++ b/EstateManagmentUI.BusinessLogic/Client/ContractMethods.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Text; using EstateManagementUI.BusinessLogic.BackendAPI.DataTransferObjects; +using TransactionProcessor.DataTransferObjects.Requests.Contract; namespace EstateManagementUI.BusinessLogic.Client { public partial interface IApiClient { @@ -18,6 +19,9 @@ Task>> GetContracts(ContractQueries.GetContractsQuery CancellationToken cancellationToken); Task> GetContract(ContractQueries.GetContractQuery request, CancellationToken cancellationToken); + + Task CreateContract(ContractCommands.CreateContractCommand request, + CancellationToken cancellationToken); } public partial class ApiClient : IApiClient { @@ -87,5 +91,20 @@ public async Task> GetContract(ContractQueries.GetContract return Result.Success(contractModel); } + + public async Task CreateContract(ContractCommands.CreateContractCommand request, + CancellationToken cancellationToken) { + var token = await this.GetToken(cancellationToken); + if (token.IsFailed) + return ResultHelpers.CreateFailure(token); + + var apiRequest = new CreateContractRequest() { Description = request.Description, OperatorId = request.OperatorId }; + + var apiResult = await this.TransactionProcessorClient.CreateContract(token.Data, request.EstateId, apiRequest, cancellationToken); + if (apiResult.IsFailed) + return ResultHelpers.CreateFailure(apiResult); + + return Result.Success(); + } } } diff --git a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs index 59b81164..8e95211d 100644 --- a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs +++ b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs @@ -172,7 +172,7 @@ public async Task>> Handle(MerchantQueries.GetM public class ContractRequestHandler : IRequestHandler>>, IRequestHandler>, - IRequestHandler, + IRequestHandler, IRequestHandler, IRequestHandler, IRequestHandler>>, @@ -196,9 +196,9 @@ public async Task> Handle(ContractQueries.GetContractQuery return await this.ApiClient.GetContract(request, cancellationToken); } - public async Task Handle(Commands.CreateContractCommand request, + public async Task Handle(ContractCommands.CreateContractCommand request, CancellationToken cancellationToken) { - return Result.Success(); + return await this.ApiClient.CreateContract(request, cancellationToken); } public async Task Handle(Commands.AddProductToContractCommand request, diff --git a/EstateManagmentUI.BusinessLogic/Requests/Requests.cs b/EstateManagmentUI.BusinessLogic/Requests/Requests.cs index f051df05..02533ae8 100644 --- a/EstateManagmentUI.BusinessLogic/Requests/Requests.cs +++ b/EstateManagmentUI.BusinessLogic/Requests/Requests.cs @@ -95,10 +95,12 @@ public record UpdateOperatorCommand(CorrelationId CorrelationId,Guid EstateId, G public record CreateOperatorCommand(CorrelationId CorrelationId, Guid EstateId, string Name, bool RequireCustomMerchantNumber, bool RequireCustomTerminalNumber) : IRequest; } +public static class ContractCommands { + public record CreateContractCommand(CorrelationId CorrelationId, Guid EstateId, string Description, Guid OperatorId) : IRequest; +} + public static class Commands { - - public record CreateContractCommand(CorrelationId CorrelationId, string AccessToken, Guid EstateId, string Description, Guid OperatorId) : IRequest; public record CreateMerchantUserCommand(CorrelationId CorrelationId, string AccessToken, Guid EstateId, Guid MerchantId, string EmailAddress, string Password) : IRequest; diff --git a/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs b/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs index c90d0514..baf25662 100644 --- a/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs +++ b/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs @@ -71,7 +71,7 @@ public Task Send(IRequest request, Cancellation MerchantCommands.UpdateMerchantCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteUpdateMerchant(cmd)), OperatorCommands.CreateOperatorCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteCreateOperator(cmd)), OperatorCommands.UpdateOperatorCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteUpdateOperator(cmd)), - Commands.CreateContractCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteCreateContract(cmd)), + ContractCommands.CreateContractCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteCreateContract(cmd)), Commands.AddProductToContractCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteAddProductToContract(cmd)), Commands.AddTransactionFeeForProductToContractCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteAddTransactionFee(cmd)), MerchantCommands.AssignContractToMerchantCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteAssignContractToMerchant(cmd)), @@ -196,7 +196,7 @@ private Result ExecuteUpdateOperator(OperatorCommands.UpdateOperatorCommand cmd) return Result.Success(); } - private Result ExecuteCreateContract(Commands.CreateContractCommand cmd) + private Result ExecuteCreateContract(ContractCommands.CreateContractCommand cmd) { var contract = new ContractModel {