From d8870b814076dba001c6a0bb23113daad32c1654 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Sat, 16 Aug 2025 16:59:36 +0530 Subject: [PATCH] Added default entries for the tenant in master tables depending upon its plan --- .../Data/ApplicationDbContext.cs | 7 +- .../Tenant/SubscriptionPlanDetailsVM.cs | 1 + .../ViewModels/Tenant/TenantDetailsVM.cs | 1 + .../Controllers/TenantController.cs | 86 ++++- Marco.Pms.Services/Program.cs | 1 + .../Service/MasterDataService.cs | 337 ++++++++++++++++++ 6 files changed, 430 insertions(+), 3 deletions(-) create mode 100644 Marco.Pms.Services/Service/MasterDataService.cs diff --git a/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs b/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs index 37b8c1c..f9c4813 100644 --- a/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs +++ b/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs @@ -301,7 +301,8 @@ namespace Marco.Pms.DataAccess.Data Level = 2, IsDefault = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") - }, new TicketPriorityMaster + }, + new TicketPriorityMaster { Id = new Guid("a13b7e59-16fd-4665-b5cf-a97399e8445a"), Name = "High", @@ -309,7 +310,8 @@ namespace Marco.Pms.DataAccess.Data Level = 3, IsDefault = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") - }, new TicketPriorityMaster + }, + new TicketPriorityMaster { Id = new Guid("f340fbc3-c9fd-46aa-b063-0093418830e4"), Name = "Critical", @@ -346,6 +348,7 @@ namespace Marco.Pms.DataAccess.Data TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") } ); + modelBuilder.Entity().HasData( new WorkCategoryMaster { diff --git a/Marco.Pms.Model/ViewModels/Tenant/SubscriptionPlanDetailsVM.cs b/Marco.Pms.Model/ViewModels/Tenant/SubscriptionPlanDetailsVM.cs index 71012c8..e137ef4 100644 --- a/Marco.Pms.Model/ViewModels/Tenant/SubscriptionPlanDetailsVM.cs +++ b/Marco.Pms.Model/ViewModels/Tenant/SubscriptionPlanDetailsVM.cs @@ -10,6 +10,7 @@ namespace Marco.Pms.Model.ViewModels.Tenant public string? PlanName { get; set; } public string? Description { get; set; } public double Price { get; set; } + public double MaxUsers { get; set; } public PLAN_FREQUENCY Frequency { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } diff --git a/Marco.Pms.Model/ViewModels/Tenant/TenantDetailsVM.cs b/Marco.Pms.Model/ViewModels/Tenant/TenantDetailsVM.cs index fb31f1f..8d01b42 100644 --- a/Marco.Pms.Model/ViewModels/Tenant/TenantDetailsVM.cs +++ b/Marco.Pms.Model/ViewModels/Tenant/TenantDetailsVM.cs @@ -23,6 +23,7 @@ namespace Marco.Pms.Model.ViewModels.Tenant public string Reference { get; set; } = string.Empty; public bool IsActive { get; set; } = true; public bool IsSuperTenant { get; set; } = false; + public int SeatsAvailable { get; set; } public int ActiveEmployees { get; set; } public int InActiveEmployees { get; set; } public int? ActiveProjects { get; set; } diff --git a/Marco.Pms.Services/Controllers/TenantController.cs b/Marco.Pms.Services/Controllers/TenantController.cs index 92873eb..fe6e521 100644 --- a/Marco.Pms.Services/Controllers/TenantController.cs +++ b/Marco.Pms.Services/Controllers/TenantController.cs @@ -338,7 +338,7 @@ namespace Marco.Pms.Services.Controllers response.OnHoldProjects = projects.Count(p => p.ProjectStatusId == projectOnHoldStatus); response.InActiveProjects = projects.Count(p => p.ProjectStatusId == projectInActiveStatus); response.CompletedProjects = projects.Count(p => p.ProjectStatusId == projectCompletedStatus); - + response.SeatsAvailable = (int)(currentPlan?.MaxUsers ?? 1) - activeEmployeesCount; response.ExpiryDate = expiryDate; response.NextBillingDate = nextBillingDate; response.CreatedBy = createdBy; @@ -1013,6 +1013,25 @@ namespace Marco.Pms.Services.Controllers _logger.LogInfo("Removed {Count} role permission mappings for role {RoleId}", deleteMappings.Count, roleId); } + var _masteData = scope.ServiceProvider.GetRequiredService(); + + if (features.Modules?.ProjectManagement?.Enabled ?? false) + { + var workCategoryMaster = _masteData.GetWorkCategoriesData(tenant.Id); + var workStatusMaster = _masteData.GetWorkStatusesData(tenant.Id); + + _context.WorkCategoryMasters.AddRange(workCategoryMaster); + _context.WorkStatusMasters.AddRange(workStatusMaster); + } + if (features.Modules?.Expense?.Enabled ?? false) + { + var expensesTypeMaster = _masteData.GetExpensesTypeesData(tenant.Id); + var paymentModeMatser = _masteData.GetPaymentModesData(tenant.Id); + + _context.ExpensesTypeMaster.AddRange(expensesTypeMaster); + _context.PaymentModeMatser.AddRange(paymentModeMatser); + } + await _context.SaveChangesAsync(); await transaction.CommitAsync(); @@ -1138,6 +1157,8 @@ namespace Marco.Pms.Services.Controllers UpdatedAt = DateTime.UtcNow }, "SubscriptionPlanModificationLog"); + + return Ok(ApiResponse.SuccessResponse(currentSubscription, "Subscription renewed/extended", 200)); } @@ -1285,6 +1306,69 @@ namespace Marco.Pms.Services.Controllers _logger.LogInfo("Permissions revoked: {Count} for Role={RoleId}", mappingsToRemove.Count, rootRoleId); } + var _masteData = scope.ServiceProvider.GetRequiredService(); + + if (features.Modules?.ProjectManagement?.Enabled ?? false) + { + var workCategoryMaster = _masteData.GetWorkCategoriesData(tenant.Id); + var workStatusMaster = _masteData.GetWorkStatusesData(tenant.Id); + + var workCategoryTask = Task.Run(async () => + { + await using var _context = await _dbContextFactory.CreateDbContextAsync(); + return await _context.WorkCategoryMasters.AnyAsync(wc => wc.IsSystem && wc.TenantId == tenant.Id); + }); + var workStatusTask = Task.Run(async () => + { + await using var _context = await _dbContextFactory.CreateDbContextAsync(); + return await _context.WorkStatusMasters.AnyAsync(ws => ws.IsSystem && ws.TenantId == tenant.Id); + }); + + await Task.WhenAll(workCategoryTask, workStatusTask); + + var workCategoryExist = workCategoryTask.Result; + var workStatusExist = workStatusTask.Result; + if (!workCategoryExist) + { + context.WorkCategoryMasters.AddRange(workCategoryMaster); + } + if (!workStatusExist) + { + context.WorkStatusMasters.AddRange(workStatusMaster); + } + } + if (features.Modules?.Expense?.Enabled ?? false) + { + var expensesTypeMaster = _masteData.GetExpensesTypeesData(tenant.Id); + var paymentModeMatser = _masteData.GetPaymentModesData(tenant.Id); + + var expensesTypeTask = Task.Run(async () => + { + await using var _context = await _dbContextFactory.CreateDbContextAsync(); + var expensesTypeNames = expensesTypeMaster.Select(et => et.Name).ToList(); + return await _context.ExpensesTypeMaster.AnyAsync(et => expensesTypeNames.Contains(et.Name) && et.TenantId == tenant.Id); + }); + var paymentModeTask = Task.Run(async () => + { + await using var _context = await _dbContextFactory.CreateDbContextAsync(); + var paymentModeNames = paymentModeMatser.Select(py => py.Name).ToList(); + return await _context.PaymentModeMatser.AnyAsync(py => paymentModeNames.Contains(py.Name) && py.TenantId == tenant.Id); + }); + + await Task.WhenAll(expensesTypeTask, paymentModeTask); + + var expensesTypeExist = expensesTypeTask.Result; + var paymentModeExist = paymentModeTask.Result; + if (!expensesTypeExist) + { + context.ExpensesTypeMaster.AddRange(expensesTypeMaster); + } + if (!paymentModeExist) + { + context.PaymentModeMatser.AddRange(paymentModeMatser); + } + } + await context.SaveChangesAsync(); await transaction.CommitAsync(); diff --git a/Marco.Pms.Services/Program.cs b/Marco.Pms.Services/Program.cs index a5c9ac8..702836e 100644 --- a/Marco.Pms.Services/Program.cs +++ b/Marco.Pms.Services/Program.cs @@ -172,6 +172,7 @@ builder.Services.AddTransient(); #region Customs Services builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Marco.Pms.Services/Service/MasterDataService.cs b/Marco.Pms.Services/Service/MasterDataService.cs new file mode 100644 index 0000000..d2ea959 --- /dev/null +++ b/Marco.Pms.Services/Service/MasterDataService.cs @@ -0,0 +1,337 @@ +using Marco.Pms.Model.Forum; +using Marco.Pms.Model.Master; + +namespace Marco.Pms.Services.Service +{ + public class MasterDataService + { + public List GetTicketStatusesData(Guid tenantId) + { + return new List + { + new TicketStatusMaster + { + Id = Guid.NewGuid(), + Name = "New", + Description = "This is a newly created issue.", + ColorCode = "#FFCC99", + IsDefault = true, + TenantId = tenantId + }, + new TicketStatusMaster + { + Id = Guid.NewGuid(), + Name = "Assigned", + Description = "Assigned to employee or team of employees", + ColorCode = "#E6FF99", + IsDefault = true, + TenantId = tenantId + }, + new TicketStatusMaster + { + Id = Guid.NewGuid(), + Name = "In Progress", + Description = "These issues are currently in progress", + ColorCode = "#99E6FF", + IsDefault = true, + TenantId = tenantId + }, + new TicketStatusMaster + { + Id = Guid.NewGuid(), + Name = "In Review", + Description = "These issues are currently under review", + ColorCode = "#8592a3", + IsDefault = true, + TenantId = tenantId + }, + new TicketStatusMaster + { + Id = Guid.NewGuid(), + Name = "Done", + Description = "The following issues are resolved and closed", + ColorCode = "#B399FF", + IsDefault = true, + TenantId = tenantId + } + }; + } + public List GetTicketTypesData(Guid tenantId) + { + return new List + { + new TicketTypeMaster + { + Id = Guid.NewGuid(), + Name = "Quality Issue", + Description = "An identified problem that affects the performance, reliability, or standards of a product or service", + IsDefault = true, + TenantId = tenantId + }, + new TicketTypeMaster + { + Id = Guid.NewGuid(), + Name = "Help Desk", + Description = "A support service that assists users with technical issues, requests, or inquiries.", + IsDefault = true, + TenantId = tenantId + } + }; + } + public List GetTicketPrioritysData(Guid tenantId) + { + return new List + { + new TicketPriorityMaster + { + Id = Guid.NewGuid(), + Name = "Low", + ColorCode = "008000", + Level = 1, + IsDefault = true, + TenantId = tenantId + }, + new TicketPriorityMaster + { + Id = Guid.NewGuid(), + Name = "Medium", + ColorCode = "FFFF00", + Level = 2, + IsDefault = true, + TenantId = tenantId + }, + new TicketPriorityMaster + { + Id = Guid.NewGuid(), + Name = "High", + ColorCode = "#FFA500", + Level = 3, + IsDefault = true, + TenantId = tenantId + }, + new TicketPriorityMaster + { + Id = Guid.NewGuid(), + Name = "Critical", + ColorCode = "#FFA500", + Level = 4, + IsDefault = true, + TenantId = tenantId + }, + new TicketPriorityMaster + { + Id = Guid.NewGuid(), + Name = "Urgent", + ColorCode = "#FF0000", + Level = 5, + IsDefault = true, + TenantId = tenantId + } + }; + } + public List GetTicketTagsData(Guid tenantId) + { + return new List + { + new TicketTagMaster + { + Id = Guid.NewGuid(), + Name = "Quality Issue", + ColorCode = "#e59866", + IsDefault = true, + TenantId = tenantId + }, + new TicketTagMaster + { + Id = Guid.NewGuid(), + Name = "Help Desk", + ColorCode = "#85c1e9", + IsDefault = true, + TenantId = tenantId + } + }; + } + public List GetWorkCategoriesData(Guid tenantId) + { + return new List + { + new WorkCategoryMaster + { + Id = Guid.NewGuid(), + Name = "Fresh Work", + Description = "Created new task in a professional or creative context", + IsSystem = true, + TenantId = tenantId + }, + new WorkCategoryMaster + { + Id = Guid.NewGuid(), + Name = "Rework", + Description = "Revising, modifying, or correcting a task to improve its quality or fix issues", + IsSystem = true, + TenantId = tenantId + }, + new WorkCategoryMaster + { + Id = Guid.NewGuid(), + Name = "Quality Issue", + Description = "Any defect, deviation, or non-conformance in a task that fails to meet established standards or customer expectations.", + IsSystem = true, + TenantId = tenantId + } + }; + } + public List GetWorkStatusesData(Guid tenantId) + { + return new List + { + new WorkStatusMaster + { + Id = Guid.NewGuid(), + Name = "Approve", + Description = "Confirm the tasks are actually finished as reported", + IsSystem = true, + TenantId = tenantId + }, + new WorkStatusMaster + { + Id = Guid.NewGuid(), + Name = "Partially Approve", + Description = "Not all tasks are actually finished as reported", + IsSystem = true, + TenantId = tenantId + }, + new WorkStatusMaster + { + Id = Guid.NewGuid(), + Name = "NCR", + Description = "Tasks are not finished as reported or have any issues in al the tasks", + IsSystem = true, + TenantId = tenantId + } + }; + } + public List GetExpensesTypeesData(Guid tenantId) + { + return new List + { + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Procurement", + Description = "Materials, equipment and supplies purchased for site operations.", + NoOfPersonsRequired = false, + IsActive = true, + TenantId = tenantId + }, + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Transport", + Description = "Vehicle fuel, logistics services and delivery of goods or personnel.", + NoOfPersonsRequired = false, + IsActive = true, + TenantId = tenantId + }, + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Travelling", + Description = "Delivery of personnel.", + NoOfPersonsRequired = true, + IsActive = true, + TenantId = tenantId + }, + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Mobilization", + Description = "Site setup costs including equipment deployment and temporary infrastructure.", + NoOfPersonsRequired = false, + IsActive = true, + TenantId = tenantId + }, + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Employee Welfare", + Description = " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", + NoOfPersonsRequired = true, + IsActive = true, + TenantId = tenantId + }, + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Maintenance & Utilities", + Description = "Machinery servicing, electricity, water, and temporary office needs.", + NoOfPersonsRequired = false, + IsActive = true, + TenantId = tenantId + }, + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Vendor/Supplier Payments", + Description = "Scheduled payments for external services or goods.", + NoOfPersonsRequired = false, + IsActive = true, + TenantId = tenantId + }, + new ExpensesTypeMaster + { + Id = Guid.NewGuid(), + Name = "Compliance & Safety", + Description = "Government fees, insurance, inspections and safety-related expenditures.", + NoOfPersonsRequired = false, + IsActive = true, + TenantId = tenantId + } + }; + } + public List GetPaymentModesData(Guid tenantId) + { + return new List + { + new PaymentModeMatser + { + Id = Guid.NewGuid(), + Name = "Cash", + Description = "Physical currency; still used for small or informal transactions.", + IsActive = true, + TenantId = tenantId + }, + new PaymentModeMatser + { + Id = Guid.NewGuid(), + Name = "Cheque", + Description = "Paper-based payment order; less common now due to processing delays and fraud risks.", + IsActive = true, + TenantId = tenantId + }, + new PaymentModeMatser + { + Id = Guid.NewGuid(), + Name = "NetBanking", + Description = "Online banking portals used to transfer funds directly between accounts", + IsActive = true, + TenantId = tenantId + }, + new PaymentModeMatser + { + Id = Guid.NewGuid(), + Name = "UPI", + Description = "Real-time bank-to-bank transfer using mobile apps; widely used for peer-to-peer and merchant payments.", + IsActive = true, + TenantId = tenantId + } + }; + } + public List GetData(Guid tenantId) + { + return new List + { + }; + } + } +}