1999 lines
97 KiB
C#
1999 lines
97 KiB
C#
using FirebaseAdmin.Messaging;
|
|
using Marco.Pms.DataAccess.Data;
|
|
using Marco.Pms.Model.Dtos.Attendance;
|
|
using Marco.Pms.Model.Entitlements;
|
|
using Marco.Pms.Model.Expenses;
|
|
using Marco.Pms.Model.Projects;
|
|
using Marco.Pms.Services.Service.ServiceInterfaces;
|
|
using MarcoBMS.Services.Service;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Project = Marco.Pms.Model.Projects.Project;
|
|
|
|
namespace Marco.Pms.Services.Service
|
|
{
|
|
public class FirebaseService : IFirebaseService
|
|
{
|
|
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
|
|
private readonly IServiceScopeFactory _serviceScopeFactory;
|
|
|
|
private static readonly Guid Review = Guid.Parse("6537018f-f4e9-4cb3-a210-6c3b2da999d7");
|
|
private static readonly Guid RejectedByReviewer = Guid.Parse("965eda62-7907-4963-b4a1-657fb0b2724b");
|
|
private static readonly Guid Approve = Guid.Parse("4068007f-c92f-4f37-a907-bc15fe57d4d8");
|
|
private static readonly Guid RejectedByApprover = Guid.Parse("d1ee5eec-24b6-4364-8673-a8f859c60729");
|
|
private static readonly Guid ProcessPending = Guid.Parse("f18c5cfd-7815-4341-8da2-2c2d65778e27");
|
|
private static readonly Guid Processed = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95");
|
|
|
|
public FirebaseService(IDbContextFactory<ApplicationDbContext> dbContextFactory,
|
|
IServiceScopeFactory serviceScopeFactory)
|
|
{
|
|
_dbContextFactory = dbContextFactory ?? throw new ArgumentNullException(nameof(dbContextFactory));
|
|
_serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory));
|
|
}
|
|
|
|
// Auth Controller
|
|
public async Task SendLoginOnAnotherDeviceMessageAsync(Guid employeeId, string fcmToken, Guid tenentId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokens = await _context.FCMTokenMappings
|
|
.Where(ft => ft.EmployeeId == employeeId &&
|
|
ft.ExpiredAt >= DateTime.UtcNow &&
|
|
ft.FcmToken != fcmToken &&
|
|
ft.TenantId == tenentId)
|
|
.Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
var notificationFirebase = new Notification
|
|
{
|
|
Title = "Login Alert",
|
|
Body = $"You has successfully logged in to the application from another device"
|
|
};
|
|
|
|
await SendMessageToMultipleDevicesAsync(registrationTokens, notificationFirebase);
|
|
}
|
|
public async Task SendLoginMessageAsync(string name, Guid tenentId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokens = await _context.FCMTokenMappings
|
|
.Where(ft => ft.ExpiredAt >= DateTime.UtcNow &&
|
|
ft.TenantId == tenentId)
|
|
.Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
var notificationFirebase = new Notification
|
|
{
|
|
Title = "Login Alert",
|
|
Body = $"{name} has successfully logged in to the application"
|
|
};
|
|
|
|
await SendMessageToMultipleDevicesAsync(registrationTokens, notificationFirebase);
|
|
}
|
|
|
|
// Attendance Controller
|
|
public async Task SendAttendanceMessageAsync(Guid projectId, string name, ATTENDANCE_MARK_TYPE markType, Guid employeeId, Guid tenantId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var teamAttendanceRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.TeamAttendance)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
var regularizeAttendanceRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.RegularizeAttendance)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, teamAttendanceRoleTask, manageProjectsRoleTask, regularizeAttendanceRoleTask);
|
|
|
|
var teamAttendanceRoleIds = teamAttendanceRoleTask.Result;
|
|
var regularizeAttendanceRoleIds = regularizeAttendanceRoleTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er => (projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && teamAttendanceRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
var dataNotificationIds = new List<Guid>();
|
|
var mesaageNotificationIds = new List<Guid>();
|
|
|
|
Notification notificationFirebase;
|
|
switch (markType)
|
|
{
|
|
case ATTENDANCE_MARK_TYPE.CHECK_IN:
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = "Attendance Update",
|
|
Body = $" {name} has checked in for project {project?.ProjectName ?? ""}."
|
|
};
|
|
mesaageNotificationIds.AddRange(employeeIds);
|
|
break;
|
|
case ATTENDANCE_MARK_TYPE.CHECK_OUT:
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = "Attendance Update",
|
|
Body = $" {name} has checked out for project {project?.ProjectName ?? ""}."
|
|
};
|
|
mesaageNotificationIds.AddRange(employeeIds);
|
|
break;
|
|
case ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE:
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = "Regularization Request",
|
|
Body = $" {name} has submitted a regularization request for project {project?.ProjectName ?? ""}."
|
|
};
|
|
mesaageNotificationIds = await _context.EmployeeRoleMappings
|
|
.Where(er => (projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && regularizeAttendanceRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
dataNotificationIds = employeeIds;
|
|
break;
|
|
case ATTENDANCE_MARK_TYPE.REGULARIZE:
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = " Regularization Approved",
|
|
Body = $" {name}'s regularization request for project {project?.ProjectName ?? ""} has been accepted."
|
|
};
|
|
mesaageNotificationIds.Add(employeeId);
|
|
dataNotificationIds.AddRange(employeeIds);
|
|
break;
|
|
case ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT:
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = "Regularization Denied",
|
|
Body = $" {name}'s regularization request for project {project?.ProjectName ?? ""} has been rejected."
|
|
};
|
|
mesaageNotificationIds.Add(employeeId);
|
|
dataNotificationIds.AddRange(employeeIds);
|
|
break;
|
|
default:
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = "Attendance Update",
|
|
Body = $" {name} has update his/her attendance for project {project?.ProjectName ?? ""}."
|
|
};
|
|
break;
|
|
}
|
|
|
|
// List of device registration tokens to send the message to
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Attendance" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "Action", markType.ToString() }
|
|
};
|
|
|
|
var registrationTokensForNotificationTask = Task.Run(async () =>
|
|
{
|
|
if (mesaageNotificationIds.Any())
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForNotification = await dbContext.FCMTokenMappings.Where(ft => mesaageNotificationIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
});
|
|
var registrationTokensForDataTask = Task.Run(async () =>
|
|
{
|
|
if (dataNotificationIds.Any())
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForData = await dbContext.FCMTokenMappings.Where(ft => dataNotificationIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesOnlyDataAsync(registrationTokensForData, data);
|
|
}
|
|
});
|
|
|
|
await Task.WhenAll(registrationTokensForNotificationTask, registrationTokensForDataTask);
|
|
}
|
|
|
|
// Task Controller
|
|
public async Task SendAssignTaskMessageAsync(Guid workItemId, string name, List<Guid> teamMembers, Guid tenantId)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var workItem = await _context.WorkItems
|
|
.Include(wi => wi.WorkArea)
|
|
.ThenInclude(wa => wa!.Floor)
|
|
.ThenInclude(f => f!.Building)
|
|
.FirstOrDefaultAsync(wi => wi.Id == workItemId && wi.WorkArea != null && wi.WorkArea.Floor != null && wi.WorkArea.Floor.Building != null);
|
|
|
|
if (workItem == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = workItem.WorkArea!.Floor!.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewTaskRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewTask)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, viewTaskRoleTask, manageProjectsRoleTask);
|
|
|
|
var viewTaskRoleIds = viewTaskRoleTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var buildingName = workItem.WorkArea.Floor.Building.Name;
|
|
var FloorName = workItem.WorkArea.Floor.FloorName;
|
|
var AreaName = workItem.WorkArea.AreaName;
|
|
|
|
var location = $"{buildingName} > {FloorName} > {AreaName}";
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er => (projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && viewTaskRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Assign_Task" },
|
|
{ "ProjectId", projectId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
|
|
var registrationTokensForNotificationTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForNotification = await dbContext.FCMTokenMappings.Where(ft => teamMembers.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
var notificationFirebase = new Notification
|
|
{
|
|
Title = $"Task Assigned for {project?.ProjectName}",
|
|
Body = $"A task has been assigned to you by {name} at {location}"
|
|
};
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
});
|
|
var registrationTokensForDataTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForData = await dbContext.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesOnlyDataAsync(registrationTokensForData, data);
|
|
});
|
|
|
|
await Task.WhenAll(registrationTokensForNotificationTask, registrationTokensForDataTask);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
public async Task SendReportTaskMessageAsync(Guid taskAllocationId, string name, Guid tenantId)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var taskAllocation = await _context.TaskAllocations
|
|
.Include(t => t.WorkItem)
|
|
.ThenInclude(wi => wi!.WorkArea)
|
|
.ThenInclude(wa => wa!.Floor)
|
|
.ThenInclude(f => f!.Building)
|
|
.FirstOrDefaultAsync(t => t.Id == taskAllocationId &&
|
|
t.TenantId == tenantId &&
|
|
t.WorkItem != null &&
|
|
t.WorkItem.WorkArea != null &&
|
|
t.WorkItem.WorkArea.Floor != null &&
|
|
t.WorkItem.WorkArea.Floor.Building != null);
|
|
|
|
if (taskAllocation == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = taskAllocation.WorkItem!.WorkArea!.Floor!.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewTaskRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewTask)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
var teamMemberTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.TaskMembers
|
|
.Where(tm => tm.TaskAllocationId == taskAllocationId && tm.TenantId == tenantId)
|
|
.Select(tm => tm.EmployeeId).ToListAsync();
|
|
});
|
|
var approveTaskRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ApproveTask)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, teamMemberTask, viewTaskRoleTask, manageProjectsRoleTask, approveTaskRoleTask);
|
|
|
|
var viewTaskRoleIds = viewTaskRoleTask.Result;
|
|
var teamMembers = teamMemberTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var approveTaskRoleIds = approveTaskRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var buildingName = taskAllocation.WorkItem.WorkArea.Floor.Building.Name;
|
|
var FloorName = taskAllocation.WorkItem.WorkArea.Floor.FloorName;
|
|
var AreaName = taskAllocation.WorkItem.WorkArea.AreaName;
|
|
|
|
var location = $"{buildingName} > {FloorName} > {AreaName}";
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var dataNotificationTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er => (projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && viewTaskRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
employeeIds.AddRange(teamMembers);
|
|
|
|
return employeeIds;
|
|
});
|
|
var mesaageNotificationTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.EmployeeRoleMappings
|
|
.Where(er => (projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && approveTaskRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(dataNotificationTask, mesaageNotificationTask);
|
|
|
|
var dataNotificationIds = dataNotificationTask.Result;
|
|
var mesaageNotificationIds = mesaageNotificationTask.Result;
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Report_Task" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "TaskAllocationId", taskAllocationId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
|
|
var registrationTokensForNotificationTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForNotification = await dbContext.FCMTokenMappings.Where(ft => mesaageNotificationIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
var notificationFirebase = new Notification
|
|
{
|
|
Title = $"New Task Reported - {project?.ProjectName}",
|
|
Body = $"{name} reported a task at {location}."
|
|
};
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
});
|
|
var registrationTokensForDataTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForData = await dbContext.FCMTokenMappings.Where(ft => dataNotificationIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesOnlyDataAsync(registrationTokensForData, data);
|
|
});
|
|
|
|
await Task.WhenAll(registrationTokensForNotificationTask, registrationTokensForDataTask);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
public async Task SendTaskCommentMessageAsync(Guid taskAllocationId, string name, Guid tenantId)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var taskAllocation = await _context.TaskAllocations
|
|
.Include(t => t.WorkItem)
|
|
.ThenInclude(wi => wi!.WorkArea)
|
|
.ThenInclude(wa => wa!.Floor)
|
|
.ThenInclude(f => f!.Building)
|
|
.FirstOrDefaultAsync(t => t.Id == taskAllocationId &&
|
|
t.TenantId == tenantId &&
|
|
t.WorkItem != null &&
|
|
t.WorkItem.WorkArea != null &&
|
|
t.WorkItem.WorkArea.Floor != null &&
|
|
t.WorkItem.WorkArea.Floor.Building != null);
|
|
|
|
if (taskAllocation == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = taskAllocation.WorkItem!.WorkArea!.Floor!.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
var viewTaskRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewTask)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, viewTaskRoleTask, manageProjectsRoleTask);
|
|
|
|
var viewTaskRoleIds = viewTaskRoleTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var buildingName = taskAllocation.WorkItem.WorkArea.Floor.Building.Name;
|
|
var FloorName = taskAllocation.WorkItem.WorkArea.Floor.FloorName;
|
|
var AreaName = taskAllocation.WorkItem.WorkArea.AreaName;
|
|
|
|
var location = $"{buildingName} > {FloorName} > {AreaName}";
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er => (projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && viewTaskRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
employeeIds.Add(taskAllocation.AssignedBy);
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Task_Comment" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "TaskAllocationId", taskAllocationId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
var notificationFirebase = new Notification
|
|
{
|
|
Title = $"New Comment on Task - {project?.ProjectName}",
|
|
Body = $"{name} added a comment on Task at {location}."
|
|
};
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
public async Task SendApproveTaskMessageAsync(Guid taskAllocationId, string name, Guid tenantId)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var taskAllocation = await _context.TaskAllocations
|
|
.Include(t => t.WorkItem)
|
|
.ThenInclude(wi => wi!.WorkArea)
|
|
.ThenInclude(wa => wa!.Floor)
|
|
.ThenInclude(f => f!.Building)
|
|
.FirstOrDefaultAsync(t => t.Id == taskAllocationId &&
|
|
t.TenantId == tenantId &&
|
|
t.WorkItem != null &&
|
|
t.WorkItem.WorkArea != null &&
|
|
t.WorkItem.WorkArea.Floor != null &&
|
|
t.WorkItem.WorkArea.Floor.Building != null);
|
|
|
|
if (taskAllocation == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = taskAllocation.WorkItem!.WorkArea!.Floor!.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewTaskRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewTask)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
var teamMemberTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.TaskMembers
|
|
.Where(tm => tm.TaskAllocationId == taskAllocationId && tm.TenantId == tenantId)
|
|
.Select(tm => tm.EmployeeId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, teamMemberTask, viewTaskRoleTask, manageProjectsRoleTask);
|
|
|
|
var viewTaskRoleIds = viewTaskRoleTask.Result;
|
|
var teamMembers = teamMemberTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var buildingName = taskAllocation.WorkItem.WorkArea.Floor.Building.Name;
|
|
var FloorName = taskAllocation.WorkItem.WorkArea.Floor.FloorName;
|
|
var AreaName = taskAllocation.WorkItem.WorkArea.AreaName;
|
|
|
|
var location = $"{buildingName} > {FloorName} > {AreaName}";
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er => (projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && viewTaskRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
teamMembers.Add(taskAllocation.AssignedBy);
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Report_Task" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "TaskAllocationId", taskAllocationId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
|
|
var registrationTokensForNotificationTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForNotification = await dbContext.FCMTokenMappings.Where(ft => teamMembers.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
var notificationFirebase = new Notification
|
|
{
|
|
Title = $"Task Approved - {project?.ProjectName}",
|
|
Body = $"{name} approved your {taskAllocation.ReportedTask} of {taskAllocation.CompletedTask} tasks at {location}."
|
|
};
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
});
|
|
var registrationTokensForDataTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForData = await dbContext.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesOnlyDataAsync(registrationTokensForData, data);
|
|
});
|
|
|
|
await Task.WhenAll(registrationTokensForNotificationTask, registrationTokensForDataTask);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
|
|
// Project Controller
|
|
//Project Infra
|
|
public async Task SendModifyTaskMeaasgeAsync(List<Guid> workItemIds, string name, bool IsExist, Guid tenantId)
|
|
{
|
|
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var workItems = await _context.WorkItems
|
|
.Include(wi => wi.ActivityMaster)
|
|
.Include(wi => wi.WorkArea)
|
|
.ThenInclude(wa => wa!.Floor)
|
|
.ThenInclude(f => f!.Building)
|
|
.Where(wi => workItemIds.Contains(wi.Id) &&
|
|
wi.TenantId == tenantId &&
|
|
wi.ActivityMaster != null &&
|
|
wi.WorkArea != null &&
|
|
wi.WorkArea.Floor != null &&
|
|
wi.WorkArea.Floor.Building != null)
|
|
.ToListAsync();
|
|
|
|
if (!workItems.Any())
|
|
{
|
|
return;
|
|
}
|
|
|
|
var workItem = workItems.FirstOrDefault();
|
|
|
|
var projectId = workItem!.WorkArea!.Floor!.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewTaskRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewTask)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
var viewProjectInfraRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewProjectInfra)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, viewTaskRoleTask, manageProjectsRoleTask, viewProjectInfraRoleTask);
|
|
|
|
var viewTaskRoleIds = viewTaskRoleTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var viewProjectInfraRoleIds = viewProjectInfraRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var activityName = workItem.ActivityMaster!.ActivityName;
|
|
|
|
var buildingName = workItem.WorkArea.Floor.Building.Name;
|
|
var FloorName = workItem.WorkArea.Floor.FloorName;
|
|
var AreaName = workItem.WorkArea.AreaName;
|
|
|
|
var location = $"{buildingName} > {FloorName} > {AreaName}";
|
|
|
|
var buildingId = workItem.WorkArea.Floor.Building.Id;
|
|
var floorId = workItem.WorkArea.Floor.Id;
|
|
var areaId = workItem.WorkArea.Id;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er =>
|
|
(projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) &&
|
|
(viewTaskRoleIds.Contains(er.RoleId) || viewProjectInfraRoleIds.Contains(er.RoleId)))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
Notification notificationFirebase;
|
|
if (IsExist)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Task Updated - {project?.ProjectName}",
|
|
Body = $"{name} updated tasks {activityName} at {location}."
|
|
};
|
|
}
|
|
else
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"New Task Created - {project?.ProjectName}",
|
|
Body = $"{name} created tasks {activityName} at {location}."
|
|
};
|
|
}
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Task_Modified" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "BuildingId", buildingId.ToString() },
|
|
{ "FloorId", floorId.ToString() },
|
|
{ "AreaId", areaId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
public async Task SendModifyWorkAreaMeaasgeAsync(Guid workAreaId, string name, bool IsExist, Guid tenantId)
|
|
{
|
|
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var workArea = await _context.WorkAreas
|
|
.Include(wa => wa.Floor)
|
|
.ThenInclude(f => f!.Building)
|
|
.FirstOrDefaultAsync(wa => wa.Id == workAreaId &&
|
|
wa.TenantId == tenantId &&
|
|
wa.Floor != null &&
|
|
wa.Floor.Building != null);
|
|
|
|
if (workArea == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = workArea.Floor!.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewProjectInfraRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewProjectInfra)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, manageProjectsRoleTask, viewProjectInfraRoleTask);
|
|
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var viewProjectInfraRoleIds = viewProjectInfraRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var buildingName = workArea.Floor.Building.Name;
|
|
var FloorName = workArea.Floor.FloorName;
|
|
|
|
var location = $"{buildingName} > {FloorName}";
|
|
|
|
var buildingId = workArea.Floor.Building.Id;
|
|
var floorId = workArea.Floor.Id;
|
|
var areaName = workArea.AreaName;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er =>
|
|
(projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && viewProjectInfraRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
Notification notificationFirebase;
|
|
if (IsExist)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"WorkArea Updated - {project?.ProjectName}",
|
|
Body = $"{name} updated WorkArea \"{areaName}\" at {location}."
|
|
};
|
|
}
|
|
else
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"New WorkArea Created - {project?.ProjectName}",
|
|
Body = $"{name} created WorkArea \"{areaName}\" at {location}."
|
|
};
|
|
}
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "WorkArea_Modified" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "BuildingId", buildingId.ToString() },
|
|
{ "FloorId", floorId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
public async Task SendModifyFloorMeaasgeAsync(Guid floorId, string name, bool IsExist, Guid tenantId)
|
|
{
|
|
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var floor = await _context.Floor
|
|
.Include(f => f.Building)
|
|
.FirstOrDefaultAsync(f => f.Id == floorId &&
|
|
f.TenantId == tenantId &&
|
|
f.Building != null);
|
|
|
|
if (floor == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = floor.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewProjectInfraRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewProjectInfra)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, manageProjectsRoleTask, viewProjectInfraRoleTask);
|
|
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var viewProjectInfraRoleIds = viewProjectInfraRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var buildingName = floor.Building.Name;
|
|
var floorName = floor.FloorName;
|
|
|
|
var buildingId = floor.Building.Id;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er =>
|
|
(projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && viewProjectInfraRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
Notification notificationFirebase;
|
|
if (IsExist)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Floor Updated - {project?.ProjectName}",
|
|
Body = $"{name} updated Floor \"{floorName}\" at {buildingName}."
|
|
};
|
|
}
|
|
else
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"New Floor Created - {project?.ProjectName}",
|
|
Body = $"{name} created Floor \"{floorName}\" at {buildingName}."
|
|
};
|
|
}
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Floor_Modified" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "BuildingId", buildingId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
public async Task SendModifyBuildingMeaasgeAsync(Guid buildingId, string name, bool IsExist, Guid tenantId)
|
|
{
|
|
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var building = await _context.Buildings
|
|
.FirstOrDefaultAsync(b => b.Id == buildingId &&
|
|
b.TenantId == tenantId);
|
|
|
|
if (building == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = building.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewProjectInfraRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewProjectInfra)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, manageProjectsRoleTask, viewProjectInfraRoleTask);
|
|
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var viewProjectInfraRoleIds = viewProjectInfraRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er =>
|
|
(projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && viewProjectInfraRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
var buildingName = building.Name;
|
|
|
|
Notification notificationFirebase;
|
|
if (IsExist)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Building Updated - {project?.ProjectName}",
|
|
Body = $"{name} updated building \"{buildingName}\" in {project?.ProjectName}."
|
|
};
|
|
}
|
|
else
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"New Building Created - {project?.ProjectName}",
|
|
Body = $"\"{{name}} created a new building \"{buildingName}\" in {project?.ProjectName}."
|
|
};
|
|
}
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Building_Modified" },
|
|
{ "ProjectId", projectId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
|
|
public async Task SendDeleteTaskMeaasgeAsync(Guid workItemId, string name, Guid tenantId)
|
|
{
|
|
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var workItem = await _context.WorkItems
|
|
.Include(wi => wi.ActivityMaster)
|
|
.Include(wi => wi.WorkArea)
|
|
.ThenInclude(wa => wa!.Floor)
|
|
.ThenInclude(f => f!.Building)
|
|
.FirstOrDefaultAsync(wi => workItemId == wi.Id &&
|
|
wi.TenantId == tenantId &&
|
|
wi.ActivityMaster != null &&
|
|
wi.WorkArea != null &&
|
|
wi.WorkArea.Floor != null &&
|
|
wi.WorkArea.Floor.Building != null);
|
|
|
|
if (workItem != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var projectId = workItem!.WorkArea!.Floor!.Building!.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var viewTaskRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewTask)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
var viewProjectInfraRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewProjectInfra)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, viewTaskRoleTask, manageProjectsRoleTask, viewProjectInfraRoleTask);
|
|
|
|
var viewTaskRoleIds = viewTaskRoleTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var viewProjectInfraRoleIds = viewProjectInfraRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
var activityName = workItem.ActivityMaster!.ActivityName;
|
|
|
|
var buildingName = workItem.WorkArea.Floor.Building.Name;
|
|
var FloorName = workItem.WorkArea.Floor.FloorName;
|
|
var AreaName = workItem.WorkArea.AreaName;
|
|
|
|
var location = $"{buildingName} > {FloorName} > {AreaName}";
|
|
|
|
var buildingId = workItem.WorkArea.Floor.Building.Id;
|
|
var floorId = workItem.WorkArea.Floor.Id;
|
|
var areaId = workItem.WorkArea.Id;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er =>
|
|
(projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) &&
|
|
(viewTaskRoleIds.Contains(er.RoleId) || viewProjectInfraRoleIds.Contains(er.RoleId)))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
Notification notificationFirebase = new Notification
|
|
{
|
|
Title = $"Task Deleted - {project?.ProjectName}",
|
|
Body = $"{name} deleted tasks {activityName} at {location}."
|
|
};
|
|
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Task_Modified" },
|
|
{ "ProjectId", projectId.ToString() },
|
|
{ "BuildingId", buildingId.ToString() },
|
|
{ "FloorId", floorId.ToString() },
|
|
{ "AreaId", areaId.ToString() },
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
|
|
//Project Allocation
|
|
public async Task SendProjectAllocationMessageAsync(List<ProjectAllocation> projectAllocations, string name, Guid tenantId)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
foreach (var projectAllocation in projectAllocations)
|
|
{
|
|
|
|
var projectId = projectAllocation.ProjectId;
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == projectId && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var manageTeamRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageTeam)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, manageTeamRoleTask, manageProjectsRoleTask);
|
|
|
|
var manageTeamRoleIds = manageTeamRoleTask.Result;
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var project = projectTask.Result;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = project?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er =>
|
|
(projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)) && manageTeamRoleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
Notification notificationFirebase;
|
|
if (projectAllocation.IsActive)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Assigned to Project - {project?.ProjectName}",
|
|
Body = $"You have been assigned to the project \"{project?.ProjectName}\"."
|
|
};
|
|
}
|
|
else
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Removed from Project - {project?.ProjectName}",
|
|
Body = $"{name} has removed you from the project \"{project?.ProjectName}\"."
|
|
};
|
|
}
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Team_Modefied" },
|
|
{ "ProjectId", projectId.ToString() }
|
|
};
|
|
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotificationTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForNotification = await dbContext.FCMTokenMappings.Where(ft => projectAllocation.EmployeeId == ft.EmployeeId && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
});
|
|
var registrationTokensForDataTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForData = await dbContext.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesOnlyDataAsync(registrationTokensForData, data);
|
|
});
|
|
|
|
await Task.WhenAll(registrationTokensForNotificationTask, registrationTokensForDataTask);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
|
|
//Project Management
|
|
public async Task SendModifyProjectMessageAsync(Project project, string name, bool IsExist, Guid tenantId)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
|
|
var projectTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.ProjectAllocations
|
|
.Include(pa => pa.Project)
|
|
.Where(pa => pa.ProjectId == project.Id && pa.IsActive && pa.Project != null)
|
|
.GroupBy(pa => pa.ProjectId)
|
|
.Select(g => new
|
|
{
|
|
ProjectName = g.Select(pa => pa.Project!.Name).FirstOrDefault(),
|
|
EmployeeIds = g.Select(pa => pa.EmployeeId).Distinct().ToList()
|
|
}).FirstOrDefaultAsync();
|
|
});
|
|
|
|
var manageProjectsRoleTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
return await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
});
|
|
|
|
await Task.WhenAll(projectTask, manageProjectsRoleTask);
|
|
|
|
var manageProjectsRoleIds = manageProjectsRoleTask.Result;
|
|
var projectVM = projectTask.Result;
|
|
|
|
List<Guid> projectAssignedEmployeeIds = projectVM?.EmployeeIds ?? new List<Guid>();
|
|
|
|
var employeeIds = await _context.EmployeeRoleMappings
|
|
.Where(er =>
|
|
(projectAssignedEmployeeIds.Contains(er.EmployeeId) || manageProjectsRoleIds.Contains(er.RoleId)))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
|
|
Notification notificationFirebase;
|
|
if (IsExist)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Project Updated - {project.Name}",
|
|
Body = $"{name} updated the project \"{project.Name}\"."
|
|
};
|
|
}
|
|
else
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Project Created - {project.Name}",
|
|
Body = $"A new project \"{project.Name}\" has been created by {name}."
|
|
};
|
|
}
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Project_Modefied" },
|
|
{ "ProjectId", project.Id.ToString() }
|
|
};
|
|
|
|
// List of device registration tokens to send the message to
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
|
|
//Expenses Controller
|
|
public async Task SendExpenseMessageAsync(Expenses expenses, string name, Guid tenantId)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
try
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
var nextStatusIds = await _context.ExpensesStatusMapping.Where(sm => sm.StatusId == expenses.StatusId).Select(sm => sm.NextStatusId).ToListAsync();
|
|
|
|
var requriedPermissionIds = await _context.StatusPermissionMapping.Where(sp => nextStatusIds.Contains(sp.StatusId)).Select(sp => sp.PermissionId).ToListAsync();
|
|
requriedPermissionIds = requriedPermissionIds.Distinct().ToList();
|
|
|
|
|
|
|
|
var notificationEmployeeTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var roleIds = await dbContext.RolePermissionMappings
|
|
.Where(rp => requriedPermissionIds.Contains(rp.FeaturePermissionId))
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er =>
|
|
roleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
return employeeIds;
|
|
});
|
|
var dataEmployeeTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var roleIds = await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ExpenseViewAll)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er =>
|
|
roleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
return employeeIds;
|
|
});
|
|
|
|
await Task.WhenAll(notificationEmployeeTask, dataEmployeeTask);
|
|
|
|
var notificationEmployeeIds = notificationEmployeeTask.Result;
|
|
var dataEmployeeIds = dataEmployeeTask.Result;
|
|
|
|
Notification? notificationFirebase = null;
|
|
Notification? notificationCreatedBy = null;
|
|
if (expenses.StatusId == Review)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Expense Awaiting Your Review",
|
|
Body = $"An expense of amount \"{expenses.Amount}\" has been submitted by {name} and is awaiting your review."
|
|
};
|
|
}
|
|
else if (expenses.StatusId == Approve)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Expense Awaiting Your Approval",
|
|
Body = $"An expense of amount \"{expenses.Amount}\" has been reviewed by {name} and is awaiting your approval."
|
|
};
|
|
notificationCreatedBy = new Notification
|
|
{
|
|
Title = "Expense Reviewed",
|
|
Body = $"Your expense of amount \"{expenses.Amount}\" is reviewed by {name}."
|
|
};
|
|
}
|
|
else if (expenses.StatusId == ProcessPending)
|
|
{
|
|
notificationFirebase = new Notification
|
|
{
|
|
Title = $"Expense Awaiting Your Payment",
|
|
Body = $"Expense of amount \"{expenses.Amount}\" has been approved by {name}. Please complete the payment."
|
|
};
|
|
notificationCreatedBy = new Notification
|
|
{
|
|
Title = "Expense Approved",
|
|
Body = $"Your expense of amount \"{expenses.Amount}\" is approved by {name}."
|
|
};
|
|
}
|
|
else if (expenses.StatusId == Processed)
|
|
{
|
|
notificationCreatedBy = new Notification
|
|
{
|
|
Title = "Expense Paid",
|
|
Body = $"Your expense of amount \"{expenses.Amount}\" has been processed and paid by {name}."
|
|
};
|
|
}
|
|
else if (expenses.StatusId == RejectedByApprover || expenses.StatusId == RejectedByReviewer)
|
|
{
|
|
notificationCreatedBy = new Notification
|
|
{
|
|
Title = "Expense Rejected",
|
|
Body = $"Your expense of amount \"{expenses.Amount}\" has been rejected by {name}."
|
|
};
|
|
}
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Expenses_Modefied" },
|
|
{ "ExpenseId", expenses.Id.ToString() }
|
|
};
|
|
|
|
var registrationTokensForNotificationTask = Task.Run(async () =>
|
|
{
|
|
if (notificationFirebase != null)
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForNotification = await dbContext.FCMTokenMappings.Where(ft => notificationEmployeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notificationFirebase, data);
|
|
}
|
|
});
|
|
var registrationTokensForDataTask = Task.Run(async () =>
|
|
{
|
|
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForNotification = await dbContext.FCMTokenMappings.Where(ft => dataEmployeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesOnlyDataAsync(registrationTokensForNotification, data);
|
|
|
|
});
|
|
var registrationTokensForCreatedByTask = Task.Run(async () =>
|
|
{
|
|
if (notificationCreatedBy != null)
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var registrationTokensForemployee = await dbContext.FCMTokenMappings.Where(ft => ft.EmployeeId == expenses.CreatedById && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForemployee, notificationCreatedBy, data);
|
|
}
|
|
});
|
|
|
|
await Task.WhenAll(registrationTokensForNotificationTask, registrationTokensForDataTask, registrationTokensForCreatedByTask);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception occured while get data for sending notification");
|
|
}
|
|
}
|
|
|
|
// Directory Controller
|
|
public async Task SendContactAsync(List<Guid> bucketIds, Notification notification, Guid tenantId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
var assignedEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
return await _context.EmployeeBucketMappings.Where(eb => bucketIds.Contains(eb.BucketId)).Select(eb => eb.EmployeeId).ToListAsync();
|
|
});
|
|
var directoryAdminEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var roleIds = await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.DirectoryAdmin)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er =>
|
|
roleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
return employeeIds;
|
|
});
|
|
|
|
await Task.WhenAll(assignedEmployeeIdsTask, directoryAdminEmployeeIdsTask);
|
|
|
|
var assignedEmployeeIds = assignedEmployeeIdsTask.Result;
|
|
var directoryAdminEmployeeIds = directoryAdminEmployeeIdsTask.Result;
|
|
|
|
assignedEmployeeIds.AddRange(directoryAdminEmployeeIds);
|
|
|
|
assignedEmployeeIds = assignedEmployeeIds.Distinct().ToList();
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Contact_Modefied" }
|
|
};
|
|
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => assignedEmployeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notification, data);
|
|
}
|
|
public async Task SendContactNoteAsync(List<Guid> bucketIds, Notification notification, Guid tenantId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
var assignedEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
return await _context.EmployeeBucketMappings.Where(eb => bucketIds.Contains(eb.BucketId)).Select(eb => eb.EmployeeId).ToListAsync();
|
|
});
|
|
var directoryAdminEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var roleIds = await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.DirectoryAdmin)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er =>
|
|
roleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
return employeeIds;
|
|
});
|
|
|
|
await Task.WhenAll(assignedEmployeeIdsTask, directoryAdminEmployeeIdsTask);
|
|
|
|
var assignedEmployeeIds = assignedEmployeeIdsTask.Result;
|
|
var directoryAdminEmployeeIds = directoryAdminEmployeeIdsTask.Result;
|
|
|
|
assignedEmployeeIds.AddRange(directoryAdminEmployeeIds);
|
|
|
|
assignedEmployeeIds = assignedEmployeeIds.Distinct().ToList();
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Contact_Note_Modefied" }
|
|
};
|
|
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => assignedEmployeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notification, data);
|
|
}
|
|
public async Task SendBucketAsync(Guid bucketId, Notification notification, Guid tenantId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
var assignedEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
return await _context.EmployeeBucketMappings.Where(eb => bucketId == eb.BucketId).Select(eb => eb.EmployeeId).ToListAsync();
|
|
});
|
|
var directoryAdminEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var roleIds = await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.DirectoryAdmin)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er =>
|
|
roleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
return employeeIds;
|
|
});
|
|
|
|
await Task.WhenAll(assignedEmployeeIdsTask, directoryAdminEmployeeIdsTask);
|
|
|
|
var assignedEmployeeIds = assignedEmployeeIdsTask.Result;
|
|
var directoryAdminEmployeeIds = directoryAdminEmployeeIdsTask.Result;
|
|
|
|
assignedEmployeeIds.AddRange(directoryAdminEmployeeIds);
|
|
|
|
assignedEmployeeIds = assignedEmployeeIds.Distinct().ToList();
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Bucket_Modefied" }
|
|
};
|
|
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => assignedEmployeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notification, data);
|
|
}
|
|
public async Task SendAssignBucketAsync(List<Guid> employeeIds, Notification notification, Guid tenantId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Bucket_Assigned" }
|
|
};
|
|
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => employeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notification, data);
|
|
}
|
|
|
|
//Document Controller
|
|
public async Task SendEmployeeDocumentMessageAsync(Guid employeeId, Notification notification, Guid tenantId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Employee_Document_Modefied" }
|
|
};
|
|
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => ft.EmployeeId == employeeId && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notification, data);
|
|
}
|
|
public async Task SendProjectDocumentMessageAsync(Guid projectId, Notification notification, Guid tenantId)
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
|
|
var assignedEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var _context = await _dbContextFactory.CreateDbContextAsync();
|
|
return await _context.ProjectAllocations.Where(pa => projectId == pa.ProjectId).Select(pa => pa.EmployeeId).ToListAsync();
|
|
});
|
|
var manageProjectEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var roleIds = await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ManageProject)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er =>
|
|
roleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
return employeeIds;
|
|
});
|
|
var viewDocumentEmployeeIdsTask = Task.Run(async () =>
|
|
{
|
|
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
|
|
var roleIds = await dbContext.RolePermissionMappings
|
|
.Where(rp => rp.FeaturePermissionId == PermissionsMaster.ViewDocument)
|
|
.Select(rp => rp.ApplicationRoleId).ToListAsync();
|
|
var employeeIds = await dbContext.EmployeeRoleMappings
|
|
.Where(er =>
|
|
roleIds.Contains(er.RoleId))
|
|
.Select(er => er.EmployeeId)
|
|
.ToListAsync();
|
|
return employeeIds;
|
|
});
|
|
|
|
await Task.WhenAll(assignedEmployeeIdsTask, manageProjectEmployeeIdsTask, viewDocumentEmployeeIdsTask);
|
|
|
|
var assignedEmployeeIds = assignedEmployeeIdsTask.Result;
|
|
var manageProjectEmployeeIds = manageProjectEmployeeIdsTask.Result;
|
|
var viewDocumentEmployeeIds = viewDocumentEmployeeIdsTask.Result;
|
|
|
|
assignedEmployeeIds.AddRange(manageProjectEmployeeIds);
|
|
|
|
var finalEmployeeIds = assignedEmployeeIds.Intersect(viewDocumentEmployeeIds).ToList();
|
|
|
|
var data = new Dictionary<string, string>()
|
|
{
|
|
{ "Keyword", "Project_Document_Modefied" }
|
|
};
|
|
|
|
var registrationTokensForNotification = await _context.FCMTokenMappings.Where(ft => finalEmployeeIds.Contains(ft.EmployeeId) && ft.ExpiredAt >= DateTime.UtcNow).Select(ft => ft.FcmToken).ToListAsync();
|
|
|
|
await SendMessageToMultipleDevicesWithDataAsync(registrationTokensForNotification, notification, data);
|
|
}
|
|
|
|
#region =================================================================== Helper Functions ===================================================================
|
|
|
|
public async Task SendMessageToMultipleDevicesWithDataAsync(List<string> registrationTokens, Notification notificationFirebase, Dictionary<string, string> data)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
try
|
|
{
|
|
registrationTokens = registrationTokens.Distinct().ToList();
|
|
var message = new MulticastMessage()
|
|
{
|
|
Tokens = registrationTokens,
|
|
Data = data,
|
|
Notification = notificationFirebase
|
|
};
|
|
// Send the multicast message
|
|
var response = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
|
|
|
|
_logger.LogInfo("{SuccessCount} messages were sent successfully.", response.SuccessCount);
|
|
|
|
if (response.FailureCount > 0)
|
|
{
|
|
var failedTokens = new List<string>();
|
|
for (int i = 0; i < response.Responses.Count; i++)
|
|
{
|
|
if (!response.Responses[i].IsSuccess)
|
|
{
|
|
failedTokens.Add(registrationTokens[i]);
|
|
}
|
|
}
|
|
_logger.LogInfo("List of tokens that caused failures: " + string.Join(", ", failedTokens));
|
|
}
|
|
}
|
|
catch (FirebaseMessagingException ex)
|
|
{
|
|
// Log the specific Firebase error.
|
|
_logger.LogError(ex, "Error sending push notification");
|
|
|
|
// Check for specific error codes that indicate an invalid or unregistered token.
|
|
if (ex.MessagingErrorCode == MessagingErrorCode.Unregistered ||
|
|
ex.MessagingErrorCode == MessagingErrorCode.InvalidArgument)
|
|
{
|
|
_logger.LogWarning("FCM token is invalid and should be deleted from the database");
|
|
|
|
// TODO: Implement the logic here to remove the invalid token from your database.
|
|
// Example: await YourTokenService.DeleteTokenAsync(loginDto.DeviceToken);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception Occured while sending notification to firebase");
|
|
}
|
|
|
|
}
|
|
public async Task SendMessageToMultipleDevicesOnlyDataAsync(List<string> registrationTokens, Dictionary<string, string> data)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
try
|
|
{
|
|
registrationTokens = registrationTokens.Distinct().ToList();
|
|
var message = new MulticastMessage()
|
|
{
|
|
Tokens = registrationTokens,
|
|
Data = data
|
|
};
|
|
// Send the multicast message
|
|
var response = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
|
|
|
|
_logger.LogInfo("{SuccessCount} messages were sent successfully.", response.SuccessCount);
|
|
|
|
if (response.FailureCount > 0)
|
|
{
|
|
var failedTokens = new List<string>();
|
|
for (int i = 0; i < response.Responses.Count; i++)
|
|
{
|
|
if (!response.Responses[i].IsSuccess)
|
|
{
|
|
failedTokens.Add(registrationTokens[i]);
|
|
}
|
|
}
|
|
_logger.LogInfo("List of tokens that caused failures: " + string.Join(", ", failedTokens));
|
|
}
|
|
}
|
|
catch (FirebaseMessagingException ex)
|
|
{
|
|
// Log the specific Firebase error.
|
|
_logger.LogError(ex, "Error sending push notification");
|
|
|
|
// Check for specific error codes that indicate an invalid or unregistered token.
|
|
if (ex.MessagingErrorCode == MessagingErrorCode.Unregistered ||
|
|
ex.MessagingErrorCode == MessagingErrorCode.InvalidArgument)
|
|
{
|
|
_logger.LogWarning("FCM token is invalid and should be deleted from the database");
|
|
|
|
// TODO: Implement the logic here to remove the invalid token from your database.
|
|
// Example: await YourTokenService.DeleteTokenAsync(loginDto.DeviceToken);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Exception Occured while sending notification to firebase");
|
|
}
|
|
|
|
}
|
|
public async Task SendMessageToMultipleDevicesAsync(List<string> registrationTokens, Notification notificationFirebase)
|
|
{
|
|
using var scope = _serviceScopeFactory.CreateScope();
|
|
var _logger = scope.ServiceProvider.GetRequiredService<ILoggingService>();
|
|
try
|
|
{
|
|
registrationTokens = registrationTokens.Distinct().ToList();
|
|
var message = new MulticastMessage()
|
|
{
|
|
Tokens = registrationTokens,
|
|
Notification = notificationFirebase
|
|
};
|
|
// Send the multicast message
|
|
var response = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
|
|
_logger.LogInfo("{SuccessCount} messages were sent successfully.", response.SuccessCount);
|
|
|
|
if (response.FailureCount > 0)
|
|
{
|
|
var failedTokens = new List<string>();
|
|
for (int i = 0; i < response.Responses.Count; i++)
|
|
{
|
|
if (!response.Responses[i].IsSuccess)
|
|
{
|
|
failedTokens.Add(registrationTokens[i]);
|
|
}
|
|
}
|
|
_logger.LogInfo("List of tokens that caused failures: " + string.Join(", ", failedTokens));
|
|
}
|
|
}
|
|
catch (FirebaseMessagingException ex)
|
|
{
|
|
// Log the specific Firebase error.
|
|
_logger.LogError(ex, "Error sending push notification");
|
|
|
|
// Check for specific error codes that indicate an invalid or unregistered token.
|
|
if (ex.MessagingErrorCode == MessagingErrorCode.Unregistered ||
|
|
ex.MessagingErrorCode == MessagingErrorCode.InvalidArgument)
|
|
{
|
|
_logger.LogWarning("FCM token is invalid and should be deleted from the database");
|
|
|
|
// TODO: Implement the logic here to remove the invalid token from your database.
|
|
// Example: await YourTokenService.DeleteTokenAsync(loginDto.DeviceToken);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|