Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public void EstateIndex_RendersCorrectly()
.ReturnsAsync(Result.Success(new List<RecentContractModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<EstateQueries.GetAssignedOperatorsQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<OperatorQueries.GetOperatorsQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<OperatorQueries.GetOperatorsForDropDownQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorDropDownModel>()));

// Act
var cut = RenderComponent<EstateIndex>();
Expand Down Expand Up @@ -65,8 +65,8 @@ public void EstateIndex_DisplaysEstateDetails()
.ReturnsAsync(Result.Success(new List<RecentContractModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<EstateQueries.GetAssignedOperatorsQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<OperatorQueries.GetOperatorsQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<OperatorQueries.GetOperatorsForDropDownQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorDropDownModel>()));

// Act
var cut = RenderComponent<EstateIndex>();
Expand All @@ -87,8 +87,8 @@ public void EstateIndex_HasCorrectPageTitle()
.ReturnsAsync(Result.Success(new List<RecentContractModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<EstateQueries.GetAssignedOperatorsQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<OperatorQueries.GetOperatorsQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorModel>()));
_mockMediator.Setup(x => x.Send(It.IsAny<OperatorQueries.GetOperatorsForDropDownQuery>(), default))
.ReturnsAsync(Result.Success(new List<OperatorDropDownModel>()));

// Act
var cut = RenderComponent<EstateIndex>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,6 @@

<PageTitle>Edit Contract</PageTitle>

@if (!hasPermission)
{
<div class="flex items-center justify-center py-12">
<div class="bg-red-50 border border-red-200 rounded-lg p-6 max-w-md">
<div class="flex items-center space-x-3">
<svg class="w-8 h-8 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
<div>
<h3 class="text-lg font-semibold text-red-900">Access Denied</h3>
<p class="text-sm text-red-700 mt-1">You don't have permission to edit contracts.</p>
</div>
</div>
<button class="btn btn-secondary mt-4 w-full" @onclick='() => NavigationManager.NavigateTo("/contracts")'>
Back to Contracts
</button>
</div>
</div>
}
else
{
<div class="space-y-6">
@if (isLoading)
{
Expand Down Expand Up @@ -415,8 +394,12 @@ else
private string? feeErrorMessage;
private Guid currentProductId;

protected override async Task OnInitializedAsync()
{

protected override async Task OnAfterRenderAsync(bool firstRender) {
if (!firstRender) {
await base.OnAfterRenderAsync(firstRender);
return;
}
await RequirePermission(PermissionSection.Contract, PermissionFunction.Edit);
await LoadContract();
}
Expand All @@ -426,7 +409,8 @@ else
try
{
isLoading = true;
var result = await Mediator.Send(new ContractQueries.GetContractQuery(CorrelationIdHelper.New(), Guid.Parse("11111111-1111-1111-1111-111111111111"), ContractId));
Guid estateId = await GetEstateId();
var result = await Mediator.Send(new ContractQueries.GetContractQuery(CorrelationIdHelper.New(), estateId, ContractId));

if (result.IsSuccess && result.Data != null)
{
Expand All @@ -442,6 +426,7 @@ else
finally
{
isLoading = false;
StateHasChanged();
}
}

Expand Down Expand Up @@ -663,4 +648,3 @@ else
public decimal? FeeValue { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,6 @@

<PageTitle>Create New Contract</PageTitle>

@if (!hasPermission)
{
<div class="flex items-center justify-center py-12">
<div class="bg-red-50 border border-red-200 rounded-lg p-6 max-w-md">
<div class="flex items-center space-x-3">
<svg class="w-8 h-8 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
<div>
<h3 class="text-lg font-semibold text-red-900">Access Denied</h3>
<p class="text-sm text-red-700 mt-1">You don't have permission to create contracts.</p>
</div>
</div>
<button class="btn btn-secondary mt-4 w-full" @onclick='() => NavigationManager.NavigateTo("/contracts")'>
Back to Contracts
</button>
</div>
</div>
}
else
{
<div class="space-y-6">
<!-- Page Header -->
<div class="flex items-center justify-between">
Expand Down Expand Up @@ -83,7 +62,7 @@ else
<option value="">-- Select Operator --</option>
@foreach (var op in operators)
{
<option value="@op.OperatorId">@op.Name</option>
<option value="@op.OperatorId">@op.OperatorName</option>
}
</InputSelect>
<ValidationMessage For="@(() => model.OperatorId)" class="text-red-600 text-sm mt-1" />
Expand Down Expand Up @@ -123,20 +102,25 @@ else
private bool isLoadingOperators = true;
private bool hasPermission = false;
private string? errorMessage;
private List<OperatorModel>? operators;
private List<OperatorDropDownModel>? operators;

protected override async Task OnInitializedAsync()
{
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 result = await Mediator.Send(new OperatorQueries.GetOperatorsQuery(CorrelationIdHelper.New(), Guid.Parse("11111111-1111-1111-1111-111111111111")));
var estateId = await GetEstateId();
var result = await Mediator.Send(new OperatorQueries.GetOperatorsForDropDownQuery(CorrelationIdHelper.New(), estateId));
if (result.IsSuccess)
{
operators = ModelFactory.ConvertFrom(result.Data);
Expand All @@ -145,6 +129,7 @@ else
finally
{
isLoadingOperators = false;
StateHasChanged();
}
}

Expand Down Expand Up @@ -202,4 +187,3 @@ else
public string? OperatorId { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@
{
@foreach (var op in availableOperators)
{
<option value="@op.OperatorId">@op.Name</option>
<option value="@op.OperatorId">@op.OperatorName</option>
}
}
</select>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public partial class Index
private bool isLoading = true;
private EstateModel? estate;
private List<RecentMerchantsModel> merchants;
private List<OperatorModel>? availableOperators;
private List<OperatorDropDownModel>? availableOperators;
private List<OperatorModel> assignedOperators = new();
private List<RecentContractModel> contracts;
private string activeTab = "overview";
Expand Down Expand Up @@ -54,7 +54,7 @@ private async Task<Result> LoadEstateData(CorrelationId correlationId, Guid esta
Task<Result<List<BusinessLogic.Models.RecentMerchantsModel>>> merchantTask = Mediator.Send(new MerchantQueries.GetRecentMerchantsQuery(correlationId, estateId));
Task<Result<List<BusinessLogic.Models.RecentContractModel>>> contractsTask = Mediator.Send(new ContractQueries.GetRecentContractsQuery(correlationId, estateId));
Task<Result<List<BusinessLogic.Models.OperatorModel>>> assignedOperatorsTask = Mediator.Send(new EstateQueries.GetAssignedOperatorsQuery(correlationId, estateId));
Task<Result<List<BusinessLogic.Models.OperatorModel>>> allOperatorsTask= Mediator.Send(new OperatorQueries.GetOperatorsQuery(correlationId, estateId));
Task<Result<List<BusinessLogic.Models.OperatorDropDownModel>>> allOperatorsTask= Mediator.Send(new OperatorQueries.GetOperatorsForDropDownQuery(correlationId, estateId));

await Task.WhenAll(estateTask, merchantTask, contractsTask, assignedOperatorsTask, allOperatorsTask);

Expand All @@ -77,9 +77,17 @@ private async Task<Result> LoadEstateData(CorrelationId correlationId, Guid esta
if (allOperatorsTask.Result.IsFailed)
return ResultHelpers.CreateFailure(allOperatorsTask.Result);

List<OperatorModel> unfiltered = ModelFactory.ConvertFrom(allOperatorsTask.Result.Data);
this.availableOperators = unfiltered.Where(u => this.assignedOperators.Select(a => a.OperatorId).Contains(u.OperatorId) == false).ToList();

List<OperatorDropDownModel> unfiltered = ModelFactory.ConvertFrom(allOperatorsTask.Result.Data);
this.availableOperators = unfiltered
.Where(u => !this.assignedOperators.Any(a => a.OperatorId == u.OperatorId))
.Select(u => new OperatorDropDownModel
{
OperatorId = u.OperatorId,
OperatorName = u.OperatorName
})
.ToList();


return Result.Success();
}

Expand Down Expand Up @@ -124,9 +132,18 @@ private async Task AddOperatorToEstate()

// Add to assigned list
var op = availableOperators?.FirstOrDefault(o => o.OperatorId == operatorId);
if (op != null && !assignedOperators.Any(a => a.OperatorId == operatorId))
{
assignedOperators.Add(op);
if (op != null && !assignedOperators.Any(a => a.OperatorId == operatorId)) {
OperatorQueries.GetOperatorQuery query = new OperatorQueries.GetOperatorQuery(CorrelationIdHelper.New(), await this.GetEstateId(), operatorId);
var operatorResult = await Mediator.Send(query);
if (operatorResult.IsFailed)
this.NavigationManager.NavigateToErrorPage();

assignedOperators.Add(new OperatorModel() {
OperatorId = operatorResult.Data.OperatorId,
Name = operatorResult.Data.Name,
RequireCustomMerchantNumber = operatorResult.Data.RequireCustomMerchantNumber,
RequireCustomTerminalNumber = operatorResult.Data.RequireCustomTerminalNumber
});
}
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
<option value="">Select an operator...</option>
@if (availableOperators != null) {
@foreach (var op in availableOperators) {
<option value="@op.OperatorId">@op.Name</option>
<option value="@op.OperatorId">@op.OperatorName</option>
}
}
</select>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public partial class Edit
private MerchantEditModel merchantEditModel = new();

// Operators
private List<OperatorModel>? availableOperators;
private List<OperatorDropDownModel>? availableOperators;
private List<MerchantOperatorModel> assignedOperators = new();
private bool showAddOperator = false;
private string? selectedOperatorId;
Expand Down Expand Up @@ -150,7 +150,7 @@ private async Task<Result> LoadOperators() {
var correlationId = new CorrelationId(Guid.NewGuid());
var estateId = await this.GetEstateId();

var result = await Mediator.Send(new OperatorQueries.GetOperatorsQuery(correlationId, estateId));
var result = await Mediator.Send(new OperatorQueries.GetOperatorsForDropDownQuery(correlationId, estateId));

if (result.IsFailed) {
return ResultHelpers.CreateFailure(result);
Expand Down Expand Up @@ -250,7 +250,7 @@ private async Task SaveAllChanges()
}
}

private void OnOperatorSelected()
private async Task OnOperatorSelected()
{
if (string.IsNullOrEmpty(selectedOperatorId))
{
Expand All @@ -263,7 +263,12 @@ private void OnOperatorSelected()
else
{
var operatorId = Guid.Parse(selectedOperatorId);
selectedOperator = availableOperators?.FirstOrDefault(o => o.OperatorId == operatorId);
OperatorQueries.GetOperatorQuery query = new OperatorQueries.GetOperatorQuery(CorrelationIdHelper.New(), await this.GetEstateId(), operatorId);
var getOperatorResult = await this.Mediator.Send(query);
if (getOperatorResult.IsFailed)
NavigationManager.NavigateToErrorPage();

selectedOperator = ModelFactory.ConvertFrom(getOperatorResult.Data);
merchantNumber = null;
terminalNumber = null;
merchantNumberError = null;
Expand Down Expand Up @@ -357,7 +362,7 @@ private async Task AddOperatorToMerchant()
{
assignedOperators.Add(new MerchantOperatorModel() {
OperatorId = op.OperatorId,
OperatorName = op.Name
OperatorName = op.OperatorName,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@using ContractProductModel = EstateManagementUI.BlazorServer.Models.ContractProductModel
@using MerchantDropDownModel = EstateManagementUI.BlazorServer.Models.MerchantDropDownModel
@using MerchantModel = EstateManagementUI.BlazorServer.Models.MerchantModel
@using OperatorDropDownModel = EstateManagementUI.BlazorServer.Models.OperatorDropDownModel
@using OperatorModel = EstateManagementUI.BlazorServer.Models.OperatorModel
@using TransactionDetailModel = EstateManagementUI.BlazorServer.Models.TransactionDetailModel
@inject IMediator Mediator
Expand Down Expand Up @@ -91,12 +92,12 @@
<!-- Operator Filter -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Operator</label>
<MultiSelectDropdown TItem="OperatorModel"
<MultiSelectDropdown TItem="OperatorDropDownModel"
Items="operators"
SelectedItems="_selectedOperatorIds"
SelectedItemsChanged="OnOperatorSelectionChanged"
GetItemId="o => o.OperatorId.ToString()"
GetItemText="o => o.Name ?? string.Empty"
GetItemText="o => o.OperatorName ?? string.Empty"
Placeholder="All Operators"
AriaLabel="Select one or more operators" />
</div>
Expand Down Expand Up @@ -338,7 +339,7 @@
// Data
private List<TransactionDetailModel>? detailData;
private List<MerchantDropDownModel>? merchants;
private List<OperatorModel>? operators;
private List<OperatorDropDownModel>? operators;
private List<ContractProductModel>? products;

// KPIs
Expand Down Expand Up @@ -433,7 +434,7 @@

// Load filter options
var merchantsTask = Mediator.Send(new MerchantQueries.GetMerchantsForDropDownQuery(correlationId, estateId));
var operatorsTask = Mediator.Send(new OperatorQueries.GetOperatorsQuery(correlationId, estateId));
var operatorsTask = Mediator.Send(new OperatorQueries.GetOperatorsForDropDownQuery(correlationId, estateId));
var contractsTask = Mediator.Send(new ContractQueries.GetContractsQuery(correlationId, estateId));

await Task.WhenAll(merchantsTask, operatorsTask, contractsTask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@using EstateManagementUI.BusinessLogic.Requests
@using MerchantDropDownModel = EstateManagementUI.BlazorServer.Models.MerchantDropDownModel
@using MerchantTransactionSummaryModel = EstateManagementUI.BlazorServer.Models.MerchantTransactionSummaryModel
@using OperatorDropDownModel = EstateManagementUI.BlazorServer.Models.OperatorDropDownModel
@using OperatorModel = EstateManagementUI.BlazorServer.Models.OperatorModel
@rendermode InteractiveServer
@inject IMediator Mediator
Expand Down Expand Up @@ -94,7 +95,7 @@
{
@foreach (var op in operators)
{
<option value="@op.OperatorId">@op.Name</option>
<option value="@op.OperatorId">@op.OperatorName</option>
}
}
</select>
Expand Down Expand Up @@ -250,7 +251,7 @@
// Data
private List<MerchantTransactionSummaryModel>? summaryData;
private List<MerchantDropDownModel>? merchants;
private List<OperatorModel>? operators;
private List<OperatorDropDownModel>? operators;

// KPIs
private int totalMerchants = 0;
Expand All @@ -277,7 +278,7 @@

// Load filter options
var merchantsTask = Mediator.Send(new MerchantQueries.GetMerchantsForDropDownQuery(correlationId, estateId));
var operatorsTask = Mediator.Send(new OperatorQueries.GetOperatorsQuery(correlationId, estateId));
var operatorsTask = Mediator.Send(new OperatorQueries.GetOperatorsForDropDownQuery(correlationId, estateId));

await Task.WhenAll(merchantsTask, operatorsTask);

Expand Down
Loading
Loading