Added update tenant API in tenant controller
This commit is contained in:
parent
f02eb32143
commit
9c6bd2c053
21
Marco.Pms.Model/Dtos/Tenant/UpdateTenantDto.cs
Normal file
21
Marco.Pms.Model/Dtos/Tenant/UpdateTenantDto.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
namespace Marco.Pms.Model.Dtos.Tenant
|
||||||
|
{
|
||||||
|
public class UpdateTenantDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public required string FirstName { get; set; }
|
||||||
|
public required string LastName { get; set; }
|
||||||
|
public string? Description { get; set; }
|
||||||
|
public string? DomainName { get; set; }
|
||||||
|
public required string BillingAddress { get; set; }
|
||||||
|
public string? TaxId { get; set; }
|
||||||
|
public string? logoImage { get; set; }
|
||||||
|
public required string OrganizationName { get; set; }
|
||||||
|
public string? OfficeNumber { get; set; }
|
||||||
|
public required string ContactNumber { get; set; }
|
||||||
|
//public required DateTime OnBoardingDate { get; set; }
|
||||||
|
public required string OrganizationSize { get; set; }
|
||||||
|
public required Guid IndustryId { get; set; }
|
||||||
|
public required string Reference { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -294,7 +294,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
.Include(sp => sp.UpdatedBy)
|
.Include(sp => sp.UpdatedBy)
|
||||||
.ThenInclude(e => e!.JobRole)
|
.ThenInclude(e => e!.JobRole)
|
||||||
.Include(sp => sp.Currency)
|
.Include(sp => sp.Currency)
|
||||||
.Include(ts => ts.Plan).ThenInclude(sp => sp.Plan)
|
.Include(ts => ts.Plan).ThenInclude(sp => sp!.Plan)
|
||||||
.Where(ts => ts.TenantId == tenant.Id && ts.Plan != null)
|
.Where(ts => ts.TenantId == tenant.Id && ts.Plan != null)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.OrderBy(ts => ts.CreatedBy)
|
.OrderBy(ts => ts.CreatedBy)
|
||||||
@ -587,12 +587,103 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUT api/<TenantController>/5
|
/// <summary>
|
||||||
[HttpPut("{id}")]
|
/// Updates tenant and root employee details for a specified tenant ID.
|
||||||
public void Put(int id, [FromBody] string value)
|
/// </summary>
|
||||||
|
/// <param name="id">ID of the tenant to update</param>
|
||||||
|
/// <param name="model">Details to update</param>
|
||||||
|
/// <returns>Result of the operation</returns>
|
||||||
|
|
||||||
|
[HttpPut("edit/{id}")]
|
||||||
|
public async Task<IActionResult> UpdateTenant(Guid id, [FromBody] UpdateTenantDto model)
|
||||||
{
|
{
|
||||||
|
_logger.LogInfo("UpdateTenant called for TenantId: {TenantId} by user.", id);
|
||||||
|
|
||||||
|
// 1. Retrieve the logged-in employee information
|
||||||
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
if (loggedInEmployee == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Unauthorized access - User not logged in.");
|
||||||
|
return StatusCode(403, ApiResponse<object>.ErrorResponse("Unauthorized", "User must be logged in.", 403));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Check permissions using a single service scope to avoid overhead
|
||||||
|
bool hasManagePermission, hasModifyPermission;
|
||||||
|
using (var scope = _serviceScopeFactory.CreateScope())
|
||||||
|
{
|
||||||
|
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
|
|
||||||
|
var manageTask = permissionService.HasPermission(PermissionsMaster.ManageTenants, loggedInEmployee.Id);
|
||||||
|
var modifyTask = permissionService.HasPermission(PermissionsMaster.ModifyTenant, loggedInEmployee.Id);
|
||||||
|
|
||||||
|
await Task.WhenAll(manageTask, modifyTask);
|
||||||
|
|
||||||
|
hasManagePermission = manageTask.Result;
|
||||||
|
hasModifyPermission = modifyTask.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasManagePermission && !hasModifyPermission)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Access denied: User {EmployeeId} lacks required permissions for UpdateTenant on TenantId: {TenantId}.", loggedInEmployee.Id, id);
|
||||||
|
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access denied", "User does not have the required permissions for this action.", 403));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Use a single DbContext instance for data access
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
// 4. Fetch tenant (with related Industry, TenantStatus), tracking enabled for updates
|
||||||
|
var tenant = await context.Tenants
|
||||||
|
.Include(t => t.Industry)
|
||||||
|
.Include(t => t.TenantStatus)
|
||||||
|
.FirstOrDefaultAsync(t => t.Id == id);
|
||||||
|
|
||||||
|
if (tenant == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Tenant not found: ID {TenantId}", id);
|
||||||
|
return NotFound(ApiResponse<object>.ErrorResponse("Tenant not found", "Tenant not found", 404));
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInfo("Tenant {TenantId} fetched for update.", tenant.Id);
|
||||||
|
|
||||||
|
// 5. Map update DTO properties to the tenant entity
|
||||||
|
_mapper.Map(model, tenant);
|
||||||
|
|
||||||
|
// 6. Fetch root employee for the tenant (includes ApplicationUser)
|
||||||
|
var rootEmployee = await context.Employees
|
||||||
|
.Include(e => e.ApplicationUser)
|
||||||
|
.FirstOrDefaultAsync(e => e.TenantId == tenant.Id && e.ApplicationUser != null && (e.ApplicationUser.IsRootUser ?? false));
|
||||||
|
|
||||||
|
if (rootEmployee == null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Root employee not found for tenant {TenantId}", id);
|
||||||
|
return NotFound(ApiResponse<object>.ErrorResponse("Root employee not found", "Root employee not found", 404));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Update root employee details
|
||||||
|
rootEmployee.FirstName = model.FirstName;
|
||||||
|
rootEmployee.LastName = model.LastName;
|
||||||
|
rootEmployee.PhoneNumber = model.ContactNumber;
|
||||||
|
rootEmployee.CurrentAddress = model.BillingAddress;
|
||||||
|
|
||||||
|
// 8. Save changes to DB
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
_logger.LogInfo("Tenant {TenantId} and root employee updated successfully.", tenant.Id);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error updating Tenant {TenantId} or root employee.", tenant.Id);
|
||||||
|
return StatusCode(500, ApiResponse<object>.ErrorResponse("Error updating tenant", "Unexpected error occurred while updating tenant.", 500));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. Map updated tenant to ViewModel for response
|
||||||
|
var response = _mapper.Map<TenantVM>(tenant);
|
||||||
|
|
||||||
|
return Ok(ApiResponse<object>.SuccessResponse(response, "Tenant updated successfully", 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DELETE api/<TenantController>/5
|
// DELETE api/<TenantController>/5
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
|
@ -33,6 +33,15 @@ namespace Marco.Pms.Services.MappingProfiles
|
|||||||
dest => dest.Name,
|
dest => dest.Name,
|
||||||
opt => opt.MapFrom(src => src.OrganizationName)
|
opt => opt.MapFrom(src => src.OrganizationName)
|
||||||
);
|
);
|
||||||
|
CreateMap<UpdateTenantDto, Tenant>()
|
||||||
|
.ForMember(
|
||||||
|
dest => dest.ContactName,
|
||||||
|
opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}")
|
||||||
|
)
|
||||||
|
.ForMember(
|
||||||
|
dest => dest.Name,
|
||||||
|
opt => opt.MapFrom(src => src.OrganizationName)
|
||||||
|
);
|
||||||
|
|
||||||
CreateMap<SubscriptionPlanDetails, SubscriptionPlanVM>()
|
CreateMap<SubscriptionPlanDetails, SubscriptionPlanVM>()
|
||||||
.ForMember(
|
.ForMember(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user