Subscription plan details added in update subscription API
This commit is contained in:
parent
c65d73ff87
commit
640b80ea82
@ -1,6 +1,4 @@
|
|||||||
using Marco.Pms.Model.TenantModels;
|
namespace Marco.Pms.Model.Dtos.Tenant
|
||||||
|
|
||||||
namespace Marco.Pms.Model.Dtos.Tenant
|
|
||||||
{
|
{
|
||||||
public class UpdateSubscriptionDto
|
public class UpdateSubscriptionDto
|
||||||
{
|
{
|
||||||
@ -8,6 +6,5 @@ namespace Marco.Pms.Model.Dtos.Tenant
|
|||||||
public Guid PlanId { get; set; }
|
public Guid PlanId { get; set; }
|
||||||
public Guid CurrencyId { get; set; }
|
public Guid CurrencyId { get; set; }
|
||||||
public double? MaxUsers { get; set; }
|
public double? MaxUsers { get; set; }
|
||||||
public PLAN_FREQUENCY Frequency { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,271 +780,272 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//[HttpPut("update-subscription")]
|
[HttpPut("update-subscription")]
|
||||||
//public async Task<IActionResult> UpdateSubscriptionAsync(UpdateSubscriptionDto model)
|
public async Task<IActionResult> UpdateSubscriptionAsync(UpdateSubscriptionDto model)
|
||||||
//{
|
{
|
||||||
// // 1. Get the logged-in user's employee record.
|
// 1. Get the logged-in user's employee record.
|
||||||
// var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|
||||||
// // 2. Create a new DbContext instance for this request.
|
// 2. Create a new DbContext instance for this request.
|
||||||
// await using var context = await _dbContextFactory.CreateDbContextAsync();
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
// // 3. Get PermissionServices from DI inside a fresh scope (rarely needed, but retained for your design).
|
// 3. Get PermissionServices from DI inside a fresh scope (rarely needed, but retained for your design).
|
||||||
// using var scope = _serviceScopeFactory.CreateScope();
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
// var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
|
|
||||||
// // 4. Check user permissions: must be both Root user and have ManageTenants permission.
|
// 4. Check user permissions: must be both Root user and have ManageTenants permission.
|
||||||
// var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
||||||
// var hasPermission = await permissionService.HasPermission(PermissionsMaster.ManageTenants, loggedInEmployee.Id);
|
var hasPermission = await permissionService.HasPermission(PermissionsMaster.ManageTenants, loggedInEmployee.Id);
|
||||||
|
|
||||||
// if (!isRootUser || !hasPermission)
|
if (!isRootUser || !hasPermission)
|
||||||
// {
|
{
|
||||||
// _logger.LogWarning("Permission denied for EmployeeId={EmployeeId}. Root: {IsRoot}, HasPermission: {HasPermission}",
|
_logger.LogWarning("Permission denied for EmployeeId={EmployeeId}. Root: {IsRoot}, HasPermission: {HasPermission}",
|
||||||
// loggedInEmployee.Id, isRootUser, hasPermission);
|
loggedInEmployee.Id, isRootUser, hasPermission);
|
||||||
// return StatusCode(403, ApiResponse<object>.ErrorResponse("Access denied",
|
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access denied",
|
||||||
// "User does not have the required permissions.", 403));
|
"User does not have the required permissions.", 403));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // 5. Fetch Tenant, SubscriptionPlan, and TenantSubscription in parallel (efficiently).
|
// 5. Fetch Tenant, SubscriptionPlan, and TenantSubscription in parallel (efficiently).
|
||||||
// var tenantTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(ctx =>
|
var tenantTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(ctx =>
|
||||||
// ctx.Result.Tenants.AsNoTracking().FirstOrDefaultAsync(t => t.Id == model.TenantId)).Unwrap();
|
ctx.Result.Tenants.AsNoTracking().FirstOrDefaultAsync(t => t.Id == model.TenantId)).Unwrap();
|
||||||
|
|
||||||
// var subscriptionPlanTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(ctx =>
|
var planDetailsTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(ctx =>
|
||||||
// ctx.Result.SubscriptionPlans.AsNoTracking().FirstOrDefaultAsync(sp => sp.Id == model.PlanId)).Unwrap();
|
ctx.Result.SubscriptionPlanDetails.Include(sp => sp.Plan).AsNoTracking().FirstOrDefaultAsync(sp => sp.Id == model.PlanId)).Unwrap();
|
||||||
|
|
||||||
// var currentSubscriptionTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(ctx =>
|
var currentSubscriptionTask = _dbContextFactory.CreateDbContextAsync().ContinueWith(ctx =>
|
||||||
// ctx.Result.TenantSubscriptions.AsNoTracking().FirstOrDefaultAsync(ts => ts.TenantId == model.TenantId)).Unwrap();
|
ctx.Result.TenantSubscriptions.Include(ts => ts.Currency).AsNoTracking().FirstOrDefaultAsync(ts => ts.TenantId == model.TenantId && !ts.IsCancelled)).Unwrap();
|
||||||
|
|
||||||
// await Task.WhenAll(tenantTask, subscriptionPlanTask, currentSubscriptionTask);
|
await Task.WhenAll(tenantTask, planDetailsTask, currentSubscriptionTask);
|
||||||
|
|
||||||
// var tenant = tenantTask.Result;
|
var tenant = tenantTask.Result;
|
||||||
// if (tenant == null)
|
if (tenant == null)
|
||||||
// {
|
{
|
||||||
// _logger.LogWarning("Tenant {TenantId} not found.", model.TenantId);
|
_logger.LogWarning("Tenant {TenantId} not found.", model.TenantId);
|
||||||
// return NotFound(ApiResponse<object>.ErrorResponse("Tenant not found", "Tenant not found", 404));
|
return NotFound(ApiResponse<object>.ErrorResponse("Tenant not found", "Tenant not found", 404));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// var subscriptionPlan = subscriptionPlanTask.Result;
|
var subscriptionPlan = planDetailsTask.Result;
|
||||||
// if (subscriptionPlan == null)
|
if (subscriptionPlan == null)
|
||||||
// {
|
{
|
||||||
// _logger.LogWarning("Subscription plan {PlanId} not found.", model.PlanId);
|
_logger.LogWarning("Subscription plan {PlanId} not found.", model.PlanId);
|
||||||
// return NotFound(ApiResponse<object>.ErrorResponse("Subscription plan not found", "Subscription plan not found", 404));
|
return NotFound(ApiResponse<object>.ErrorResponse("Subscription plan not found", "Subscription plan not found", 404));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// var currentSubscription = currentSubscriptionTask.Result;
|
var currentSubscription = currentSubscriptionTask.Result;
|
||||||
// var utcNow = DateTime.UtcNow;
|
var utcNow = DateTime.UtcNow;
|
||||||
|
|
||||||
// // 6. If the tenant already has this plan, extend/renew it.
|
// 6. If the tenant already has this plan, extend/renew it.
|
||||||
// if (currentSubscription != null && currentSubscription.PlanId == model.PlanId)
|
if (currentSubscription != null && currentSubscription.PlanId == subscriptionPlan.Id)
|
||||||
// {
|
{
|
||||||
// DateTime newEndDate;
|
DateTime newEndDate;
|
||||||
// // 6a. If the subscription is still active, extend from current EndDate; else start from now.
|
// 6a. If the subscription is still active, extend from current EndDate; else start from now.
|
||||||
// if (currentSubscription.EndDate.Date >= utcNow.Date)
|
if (currentSubscription.EndDate.Date >= utcNow.Date)
|
||||||
// {
|
{
|
||||||
// newEndDate = model.Frequency switch
|
newEndDate = subscriptionPlan.Frequency switch
|
||||||
// {
|
{
|
||||||
// PLAN_FREQUENCY.MONTHLY => currentSubscription.EndDate.AddMonths(1),
|
PLAN_FREQUENCY.MONTHLY => currentSubscription.EndDate.AddMonths(1),
|
||||||
// PLAN_FREQUENCY.QUARTERLY => currentSubscription.EndDate.AddMonths(3),
|
PLAN_FREQUENCY.QUARTERLY => currentSubscription.EndDate.AddMonths(3),
|
||||||
// PLAN_FREQUENCY.HALF_MONTHLY => currentSubscription.EndDate.AddMonths(6),
|
PLAN_FREQUENCY.HALF_MONTHLY => currentSubscription.EndDate.AddMonths(6),
|
||||||
// PLAN_FREQUENCY.YEARLY => currentSubscription.EndDate.AddMonths(12),
|
PLAN_FREQUENCY.YEARLY => currentSubscription.EndDate.AddMonths(12),
|
||||||
// _ => currentSubscription.EndDate
|
_ => currentSubscription.EndDate
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// {
|
{
|
||||||
// newEndDate = model.Frequency switch
|
newEndDate = subscriptionPlan.Frequency switch
|
||||||
// {
|
{
|
||||||
// PLAN_FREQUENCY.MONTHLY => utcNow.AddMonths(1),
|
PLAN_FREQUENCY.MONTHLY => utcNow.AddMonths(1),
|
||||||
// PLAN_FREQUENCY.QUARTERLY => utcNow.AddMonths(3),
|
PLAN_FREQUENCY.QUARTERLY => utcNow.AddMonths(3),
|
||||||
// PLAN_FREQUENCY.HALF_MONTHLY => utcNow.AddMonths(6),
|
PLAN_FREQUENCY.HALF_MONTHLY => utcNow.AddMonths(6),
|
||||||
// PLAN_FREQUENCY.YEARLY => utcNow.AddMonths(12),
|
PLAN_FREQUENCY.YEARLY => utcNow.AddMonths(12),
|
||||||
// _ => utcNow
|
_ => utcNow
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // 6b. Update subscription details
|
// 6b. Update subscription details
|
||||||
// if (model.MaxUsers != null && model.MaxUsers > 0)
|
if (model.MaxUsers != null && model.MaxUsers > 0)
|
||||||
// {
|
{
|
||||||
// currentSubscription.MaxUsers = model.MaxUsers.Value;
|
currentSubscription.MaxUsers = model.MaxUsers.Value;
|
||||||
// }
|
}
|
||||||
// currentSubscription.EndDate = newEndDate;
|
currentSubscription.StartDate = utcNow;
|
||||||
// currentSubscription.NextBillingDate = newEndDate;
|
currentSubscription.EndDate = newEndDate;
|
||||||
// currentSubscription.UpdateAt = utcNow;
|
currentSubscription.NextBillingDate = newEndDate;
|
||||||
// currentSubscription.UpdatedById = loggedInEmployee.Id;
|
currentSubscription.UpdateAt = utcNow;
|
||||||
|
currentSubscription.UpdatedById = loggedInEmployee.Id;
|
||||||
|
|
||||||
// context.TenantSubscriptions.Update(currentSubscription);
|
context.TenantSubscriptions.Update(currentSubscription);
|
||||||
// await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
|
||||||
// _logger.LogInfo("Subscription renewed: Tenant={TenantId}, Plan={PlanId}, NewEnd={EndDate}",
|
_logger.LogInfo("Subscription renewed: Tenant={TenantId}, Plan={PlanId}, NewEnd={EndDate}",
|
||||||
// model.TenantId, model.PlanId, newEndDate);
|
model.TenantId, model.PlanId, newEndDate);
|
||||||
|
|
||||||
// return Ok(ApiResponse<object>.SuccessResponse(currentSubscription, "Subscription renewed/extended", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(currentSubscription, "Subscription renewed/extended", 200));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // 7. Else, change plan: new subscription record, close the old if exists.
|
// 7. Else, change plan: new subscription record, close the old if exists.
|
||||||
// await using var transaction = await context.Database.BeginTransactionAsync();
|
await using var transaction = await context.Database.BeginTransactionAsync();
|
||||||
// try
|
try
|
||||||
// {
|
{
|
||||||
// // 7a. Compute new plan dates
|
// 7a. Compute new plan dates
|
||||||
// var endDate = model.Frequency switch
|
var endDate = subscriptionPlan.Frequency switch
|
||||||
// {
|
{
|
||||||
// PLAN_FREQUENCY.MONTHLY => utcNow.AddMonths(1),
|
PLAN_FREQUENCY.MONTHLY => utcNow.AddMonths(1),
|
||||||
// PLAN_FREQUENCY.QUARTERLY => utcNow.AddMonths(3),
|
PLAN_FREQUENCY.QUARTERLY => utcNow.AddMonths(3),
|
||||||
// PLAN_FREQUENCY.HALF_MONTHLY => utcNow.AddMonths(6),
|
PLAN_FREQUENCY.HALF_MONTHLY => utcNow.AddMonths(6),
|
||||||
// PLAN_FREQUENCY.YEARLY => utcNow.AddMonths(12),
|
PLAN_FREQUENCY.YEARLY => utcNow.AddMonths(12),
|
||||||
// _ => utcNow
|
_ => utcNow
|
||||||
// };
|
};
|
||||||
|
|
||||||
// var newSubscription = new TenantSubscriptions
|
var newSubscription = new TenantSubscriptions
|
||||||
// {
|
{
|
||||||
// TenantId = model.TenantId,
|
TenantId = model.TenantId,
|
||||||
// PlanId = model.PlanId,
|
PlanId = model.PlanId,
|
||||||
// StatusId = activePlanStatus,
|
StatusId = activePlanStatus,
|
||||||
// CreatedAt = utcNow,
|
CreatedAt = utcNow,
|
||||||
// MaxUsers = model.MaxUsers ?? (currentSubscription?.MaxUsers ?? subscriptionPlan.MaxUser),
|
MaxUsers = model.MaxUsers ?? (currentSubscription?.MaxUsers ?? subscriptionPlan.MaxUser),
|
||||||
// CreatedById = loggedInEmployee.Id,
|
CreatedById = loggedInEmployee.Id,
|
||||||
// CurrencyId = model.CurrencyId,
|
CurrencyId = model.CurrencyId,
|
||||||
// StartDate = utcNow,
|
StartDate = utcNow,
|
||||||
// EndDate = endDate,
|
EndDate = endDate,
|
||||||
// NextBillingDate = endDate,
|
NextBillingDate = endDate,
|
||||||
// IsTrial = currentSubscription?.IsTrial ?? false,
|
IsTrial = currentSubscription?.IsTrial ?? false,
|
||||||
// AutoRenew = currentSubscription?.AutoRenew ?? false
|
AutoRenew = currentSubscription?.AutoRenew ?? false
|
||||||
// };
|
};
|
||||||
// context.TenantSubscriptions.Add(newSubscription);
|
context.TenantSubscriptions.Add(newSubscription);
|
||||||
|
|
||||||
// // 7b. If an old subscription exists, cancel it.
|
// 7b. If an old subscription exists, cancel it.
|
||||||
// if (currentSubscription != null)
|
if (currentSubscription != null)
|
||||||
// {
|
{
|
||||||
// currentSubscription.IsCancelled = true;
|
currentSubscription.IsCancelled = true;
|
||||||
// currentSubscription.CancellationDate = utcNow;
|
currentSubscription.CancellationDate = utcNow;
|
||||||
// currentSubscription.UpdateAt = utcNow;
|
currentSubscription.UpdateAt = utcNow;
|
||||||
// currentSubscription.UpdatedById = loggedInEmployee.Id;
|
currentSubscription.UpdatedById = loggedInEmployee.Id;
|
||||||
// context.TenantSubscriptions.Update(currentSubscription);
|
context.TenantSubscriptions.Update(currentSubscription);
|
||||||
// }
|
}
|
||||||
// await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
// _logger.LogInfo("Subscription plan changed: Tenant={TenantId}, NewPlan={PlanId}",
|
_logger.LogInfo("Subscription plan changed: Tenant={TenantId}, NewPlan={PlanId}",
|
||||||
// model.TenantId, model.PlanId);
|
model.TenantId, model.PlanId);
|
||||||
|
|
||||||
// // 8. Update tenant permissions based on subscription features.
|
// 8. Update tenant permissions based on subscription features.
|
||||||
// var features = await _featureDetailsHelper.GetFeatureDetails(subscriptionPlan.FeaturesId);
|
var features = await _featureDetailsHelper.GetFeatureDetails(subscriptionPlan.FeaturesId);
|
||||||
// if (features == null)
|
if (features == null)
|
||||||
// {
|
{
|
||||||
// _logger.LogInfo("No features for Plan={PlanId}.", model.PlanId);
|
_logger.LogInfo("No features for Plan={PlanId}.", model.PlanId);
|
||||||
// await transaction.CommitAsync();
|
await transaction.CommitAsync();
|
||||||
// return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription updated (no features)", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription updated (no features)", 200));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // 8a. Async helper to get all permission IDs for a given module.
|
// 8a. Async helper to get all permission IDs for a given module.
|
||||||
// async Task<List<Guid>> GetPermissionsForFeaturesAsync(List<Guid>? featureIds)
|
async Task<List<Guid>> GetPermissionsForFeaturesAsync(List<Guid>? featureIds)
|
||||||
// {
|
{
|
||||||
// if (featureIds == null || featureIds.Count == 0) return new List<Guid>();
|
if (featureIds == null || featureIds.Count == 0) return new List<Guid>();
|
||||||
|
|
||||||
// await using var ctx = await _dbContextFactory.CreateDbContextAsync();
|
await using var ctx = await _dbContextFactory.CreateDbContextAsync();
|
||||||
// return await ctx.FeaturePermissions.AsNoTracking()
|
return await ctx.FeaturePermissions.AsNoTracking()
|
||||||
// .Where(fp => featureIds.Contains(fp.FeatureId))
|
.Where(fp => featureIds.Contains(fp.FeatureId))
|
||||||
// .Select(fp => fp.Id)
|
.Select(fp => fp.Id)
|
||||||
// .ToListAsync();
|
.ToListAsync();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // 8b. Fetch all module permissions concurrently.
|
// 8b. Fetch all module permissions concurrently.
|
||||||
// var projectPermTask = GetPermissionsForFeaturesAsync(features.Modules?.ProjectManagement?.FeatureId);
|
var projectPermTask = GetPermissionsForFeaturesAsync(features.Modules?.ProjectManagement?.FeatureId);
|
||||||
// var attendancePermTask = GetPermissionsForFeaturesAsync(features.Modules?.Attendance?.FeatureId);
|
var attendancePermTask = GetPermissionsForFeaturesAsync(features.Modules?.Attendance?.FeatureId);
|
||||||
// var directoryPermTask = GetPermissionsForFeaturesAsync(features.Modules?.Directory?.FeatureId);
|
var directoryPermTask = GetPermissionsForFeaturesAsync(features.Modules?.Directory?.FeatureId);
|
||||||
// var expensePermTask = GetPermissionsForFeaturesAsync(features.Modules?.Expense?.FeatureId);
|
var expensePermTask = GetPermissionsForFeaturesAsync(features.Modules?.Expense?.FeatureId);
|
||||||
// var employeePermTask = GetPermissionsForFeaturesAsync(new List<Guid> { EmployeeFeatureId }); // assumed defined
|
var employeePermTask = GetPermissionsForFeaturesAsync(new List<Guid> { EmployeeFeatureId }); // assumed defined
|
||||||
|
|
||||||
// await Task.WhenAll(projectPermTask, attendancePermTask, directoryPermTask, expensePermTask, employeePermTask);
|
await Task.WhenAll(projectPermTask, attendancePermTask, directoryPermTask, expensePermTask, employeePermTask);
|
||||||
|
|
||||||
// // 8c. Prepare add and remove permission lists.
|
// 8c. Prepare add and remove permission lists.
|
||||||
// var newPermissionIds = new List<Guid>();
|
var newPermissionIds = new List<Guid>();
|
||||||
// var revokePermissionIds = new List<Guid>();
|
var revokePermissionIds = new List<Guid>();
|
||||||
|
|
||||||
// void ProcessPerms(bool? enabled, List<Guid> ids)
|
void ProcessPerms(bool? enabled, List<Guid> ids)
|
||||||
// {
|
{
|
||||||
// if (enabled == true) newPermissionIds.AddRange(ids);
|
if (enabled == true) newPermissionIds.AddRange(ids);
|
||||||
// else revokePermissionIds.AddRange(ids);
|
else revokePermissionIds.AddRange(ids);
|
||||||
// }
|
}
|
||||||
// ProcessPerms(features.Modules?.ProjectManagement?.Enabled, projectPermTask.Result);
|
ProcessPerms(features.Modules?.ProjectManagement?.Enabled, projectPermTask.Result);
|
||||||
// ProcessPerms(features.Modules?.Attendance?.Enabled, attendancePermTask.Result);
|
ProcessPerms(features.Modules?.Attendance?.Enabled, attendancePermTask.Result);
|
||||||
// ProcessPerms(features.Modules?.Directory?.Enabled, directoryPermTask.Result);
|
ProcessPerms(features.Modules?.Directory?.Enabled, directoryPermTask.Result);
|
||||||
// ProcessPerms(features.Modules?.Expense?.Enabled, expensePermTask.Result);
|
ProcessPerms(features.Modules?.Expense?.Enabled, expensePermTask.Result);
|
||||||
|
|
||||||
// newPermissionIds = newPermissionIds.Distinct().ToList();
|
newPermissionIds = newPermissionIds.Distinct().ToList();
|
||||||
// revokePermissionIds = revokePermissionIds.Distinct().ToList();
|
revokePermissionIds = revokePermissionIds.Distinct().ToList();
|
||||||
|
|
||||||
// // 8d. Find root employee & role for this tenant.
|
// 8d. Find root employee & role for this tenant.
|
||||||
// var rootEmployee = await context.Employees
|
var rootEmployee = await context.Employees
|
||||||
// .Include(e => e.ApplicationUser)
|
.Include(e => e.ApplicationUser)
|
||||||
// .FirstOrDefaultAsync(e => e.ApplicationUser != null && (e.ApplicationUser.IsRootUser ?? false) && e.TenantId == model.TenantId);
|
.FirstOrDefaultAsync(e => e.ApplicationUser != null && (e.ApplicationUser.IsRootUser ?? false) && e.TenantId == model.TenantId);
|
||||||
|
|
||||||
// if (rootEmployee == null)
|
if (rootEmployee == null)
|
||||||
// {
|
{
|
||||||
// _logger.LogWarning("No root employee for Tenant={TenantId}.", model.TenantId);
|
_logger.LogWarning("No root employee for Tenant={TenantId}.", model.TenantId);
|
||||||
// await transaction.CommitAsync();
|
await transaction.CommitAsync();
|
||||||
// return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription updated (no root employee)", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription updated (no root employee)", 200));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// var rootRoleId = await context.EmployeeRoleMappings
|
var rootRoleId = await context.EmployeeRoleMappings
|
||||||
// .AsNoTracking()
|
.AsNoTracking()
|
||||||
// .Where(er => er.EmployeeId == rootEmployee.Id && er.TenantId == model.TenantId)
|
.Where(er => er.EmployeeId == rootEmployee.Id && er.TenantId == model.TenantId)
|
||||||
// .Select(er => er.RoleId)
|
.Select(er => er.RoleId)
|
||||||
// .FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
// if (rootRoleId == Guid.Empty)
|
if (rootRoleId == Guid.Empty)
|
||||||
// {
|
{
|
||||||
// _logger.LogWarning("No root role for Employee={EmployeeId}, Tenant={TenantId}.", rootEmployee.Id, model.TenantId);
|
_logger.LogWarning("No root role for Employee={EmployeeId}, Tenant={TenantId}.", rootEmployee.Id, model.TenantId);
|
||||||
// await transaction.CommitAsync();
|
await transaction.CommitAsync();
|
||||||
// return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription updated (no root role)", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription updated (no root role)", 200));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// var dbOldRolePerms = await context.RolePermissionMappings.Where(x => x.ApplicationRoleId == rootRoleId).ToListAsync();
|
var dbOldRolePerms = await context.RolePermissionMappings.Where(x => x.ApplicationRoleId == rootRoleId).ToListAsync();
|
||||||
// var oldPermIds = dbOldRolePerms.Select(rp => rp.FeaturePermissionId).ToList();
|
var oldPermIds = dbOldRolePerms.Select(rp => rp.FeaturePermissionId).ToList();
|
||||||
|
|
||||||
// // 8e. Prevent accidental loss of basic employee permissions.
|
// 8e. Prevent accidental loss of basic employee permissions.
|
||||||
// if (oldPermIds.Count - revokePermissionIds.Count <= 4 && revokePermissionIds.Any())
|
if ((oldPermIds.Count - revokePermissionIds.Count) >= 4 && revokePermissionIds.Any())
|
||||||
// {
|
{
|
||||||
// var employeePerms = employeePermTask.Result;
|
var employeePerms = employeePermTask.Result;
|
||||||
// revokePermissionIds = revokePermissionIds.Where(pid => !employeePerms.Contains(pid)).ToList();
|
revokePermissionIds = revokePermissionIds.Where(pid => !employeePerms.Contains(pid)).ToList();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // 8f. Prepare permission-mapping records to add/remove.
|
// 8f. Prepare permission-mapping records to add/remove.
|
||||||
// var mappingsToRemove = dbOldRolePerms.Where(rp => revokePermissionIds.Contains(rp.FeaturePermissionId)).ToList();
|
var mappingsToRemove = dbOldRolePerms.Where(rp => revokePermissionIds.Contains(rp.FeaturePermissionId)).ToList();
|
||||||
// var mappingsToAdd = newPermissionIds
|
var mappingsToAdd = newPermissionIds
|
||||||
// .Where(pid => !oldPermIds.Contains(pid))
|
.Where(pid => !oldPermIds.Contains(pid))
|
||||||
// .Select(pid => new RolePermissionMappings { ApplicationRoleId = rootRoleId, FeaturePermissionId = pid })
|
.Select(pid => new RolePermissionMappings { ApplicationRoleId = rootRoleId, FeaturePermissionId = pid })
|
||||||
// .ToList();
|
.ToList();
|
||||||
|
|
||||||
// if (mappingsToAdd.Any())
|
if (mappingsToAdd.Any())
|
||||||
// {
|
{
|
||||||
// context.RolePermissionMappings.AddRange(mappingsToAdd);
|
context.RolePermissionMappings.AddRange(mappingsToAdd);
|
||||||
// _logger.LogInfo("Permissions granted: {Count} for Role={RoleId}", mappingsToAdd.Count, rootRoleId);
|
_logger.LogInfo("Permissions granted: {Count} for Role={RoleId}", mappingsToAdd.Count, rootRoleId);
|
||||||
// }
|
}
|
||||||
// if (mappingsToRemove.Any())
|
if (mappingsToRemove.Any())
|
||||||
// {
|
{
|
||||||
// context.RolePermissionMappings.RemoveRange(mappingsToRemove);
|
context.RolePermissionMappings.RemoveRange(mappingsToRemove);
|
||||||
// _logger.LogInfo("Permissions revoked: {Count} for Role={RoleId}", mappingsToRemove.Count, rootRoleId);
|
_logger.LogInfo("Permissions revoked: {Count} for Role={RoleId}", mappingsToRemove.Count, rootRoleId);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
// await transaction.CommitAsync();
|
await transaction.CommitAsync();
|
||||||
|
|
||||||
// _logger.LogInfo("Tenant subscription and permissions updated: Tenant={TenantId}", model.TenantId);
|
_logger.LogInfo("Tenant subscription and permissions updated: Tenant={TenantId}", model.TenantId);
|
||||||
|
|
||||||
// return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription successfully updated", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(newSubscription, "Tenant subscription successfully updated", 200));
|
||||||
// }
|
}
|
||||||
// catch (DbUpdateException dbEx)
|
catch (DbUpdateException dbEx)
|
||||||
// {
|
{
|
||||||
// await transaction.RollbackAsync();
|
await transaction.RollbackAsync();
|
||||||
// _logger.LogError(dbEx, "Database exception updating subscription for TenantId={TenantId}", model.TenantId);
|
_logger.LogError(dbEx, "Database exception updating subscription for TenantId={TenantId}", model.TenantId);
|
||||||
// return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal database error", ExceptionMapper(dbEx), 500));
|
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal database error", ExceptionMapper(dbEx), 500));
|
||||||
// }
|
}
|
||||||
// catch (Exception ex)
|
catch (Exception ex)
|
||||||
// {
|
{
|
||||||
// await transaction.RollbackAsync();
|
await transaction.RollbackAsync();
|
||||||
// _logger.LogError(ex, "General exception for TenantId={TenantId}", model.TenantId);
|
_logger.LogError(ex, "General exception for TenantId={TenantId}", model.TenantId);
|
||||||
// return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal error occurred", ExceptionMapper(ex), 500));
|
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal error occurred", ExceptionMapper(ex), 500));
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user