Added the firebase notification in directory controller

This commit is contained in:
ashutosh.nehete 2025-09-12 16:31:39 +05:30
parent 5717bb6dac
commit a88446ceb5
3 changed files with 470 additions and 10 deletions

View File

@ -1,4 +1,5 @@
using AutoMapper; using AutoMapper;
using FirebaseAdmin.Messaging;
using Marco.Pms.DataAccess.Data; using Marco.Pms.DataAccess.Data;
using Marco.Pms.Helpers.Utility; using Marco.Pms.Helpers.Utility;
using Marco.Pms.Model.Directory; using Marco.Pms.Model.Directory;
@ -119,15 +120,18 @@ namespace Marco.Pms.Services.Service
// --- Advanced Filtering from 'filter' parameter --- // --- Advanced Filtering from 'filter' parameter ---
ContactFilterDto? contactFilter = TryDeserializeContactFilter(filter); ContactFilterDto? contactFilter = TryDeserializeContactFilter(filter);
if (contactFilter?.BucketIds?.Any() ?? false) if (contactFilter != null)
{ {
// Note: Permission filtering is already applied. Here we further restrict by the user's filter choice. if (contactFilter.BucketIds?.Any() ?? false)
contactQuery = contactQuery.Where(c => dbContext.ContactBucketMappings.Any(cbm => {
cbm.ContactId == c.Id && contactFilter.BucketIds.Contains(cbm.BucketId))); // Note: Permission filtering is already applied. Here we further restrict by the user's filter choice.
} contactQuery = contactQuery.Where(c => dbContext.ContactBucketMappings.Any(cbm =>
if (contactFilter?.CategoryIds?.Any() ?? false) cbm.ContactId == c.Id && contactFilter.BucketIds.Contains(cbm.BucketId)));
{ }
contactQuery = contactQuery.Where(c => c.ContactCategoryId.HasValue && contactFilter.CategoryIds.Contains(c.ContactCategoryId.Value)); if (contactFilter.CategoryIds?.Any() ?? false)
{
contactQuery = contactQuery.Where(c => c.ContactCategoryId.HasValue && contactFilter.CategoryIds.Contains(c.ContactCategoryId.Value));
}
} }
// --- Standard Filtering --- // --- Standard Filtering ---
@ -935,6 +939,7 @@ namespace Marco.Pms.Services.Service
/// <returns>An ApiResponse containing the newly created contact's view model or an error.</returns> /// <returns>An ApiResponse containing the newly created contact's view model or an error.</returns>
public async Task<ApiResponse<object>> CreateContactAsync(CreateContactDto createContact, Guid tenantId, Employee loggedInEmployee) public async Task<ApiResponse<object>> CreateContactAsync(CreateContactDto createContact, Guid tenantId, Employee loggedInEmployee)
{ {
using var scope = _serviceScopeFactory.CreateScope();
Guid loggedInEmployeeId = loggedInEmployee.Id; Guid loggedInEmployeeId = loggedInEmployee.Id;
if (string.IsNullOrWhiteSpace(createContact.Name) || if (string.IsNullOrWhiteSpace(createContact.Name) ||
@ -1007,6 +1012,25 @@ namespace Marco.Pms.Services.Service
contactVM.BucketIds = contactBucketMappings.Select(cb => cb.BucketId).ToList(); contactVM.BucketIds = contactBucketMappings.Select(cb => cb.BucketId).ToList();
contactVM.ProjectIds = projectMappings.Select(cp => cp.ProjectId).ToList(); contactVM.ProjectIds = projectMappings.Select(cp => cp.ProjectId).ToList();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
var notification = new Notification
{
Title = "New Contact Created",
Body = $"New Contact \"{contact.Name}\" is created by {name} in your bucket"
};
await _firebase.SendContactAsync(contactVM.BucketIds, notification, tenantId);
});
return ApiResponse<object>.SuccessResponse(contactVM, "Contact created successfully.", 201); return ApiResponse<object>.SuccessResponse(contactVM, "Contact created successfully.", 201);
} }
catch (Exception ex) catch (Exception ex)
@ -1022,6 +1046,7 @@ namespace Marco.Pms.Services.Service
public async Task<ApiResponse<object>> UpdateContactAsync(Guid id, UpdateContactDto updateContact, Guid tenantId, Employee loggedInEmployee) public async Task<ApiResponse<object>> UpdateContactAsync(Guid id, UpdateContactDto updateContact, Guid tenantId, Employee loggedInEmployee)
{ {
using var scope = _serviceScopeFactory.CreateScope();
if (updateContact == null) if (updateContact == null)
{ {
_logger.LogWarning("Employee {EmployeeId} sent empty payload for updating contact.", loggedInEmployee.Id); _logger.LogWarning("Employee {EmployeeId} sent empty payload for updating contact.", loggedInEmployee.Id);
@ -1455,6 +1480,28 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("Contact {ContactId} successfully updated by employee {EmployeeId}.", contact.Id, loggedInEmployee.Id); _logger.LogInfo("Contact {ContactId} successfully updated by employee {EmployeeId}.", contact.Id, loggedInEmployee.Id);
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
if (contactVM.BucketIds?.Any() ?? false)
{
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
var notification = new Notification
{
Title = $"Contact Updated - \"{contact.Name}\"",
Body = $"Contact \"{contact.Name}\" is updated by {name} in your bucket"
};
await _firebase.SendContactAsync(contactVM.BucketIds, notification, tenantId);
}
});
return ApiResponse<object>.SuccessResponse(contactVM, "Contact Updated Successfully", 200); return ApiResponse<object>.SuccessResponse(contactVM, "Contact Updated Successfully", 200);
} }
@ -1471,6 +1518,15 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("Contact ID is empty", "Contact ID is empty", 400); return ApiResponse<object>.ErrorResponse("Contact ID is empty", "Contact ID is empty", 400);
} }
var bucketIds = await _context.ContactBucketMappings.Where(cb => cb.ContactId == id).Select(cb => cb.BucketId).ToListAsync();
var hasContactAccess = await _context.EmployeeBucketMappings.AnyAsync(eb => bucketIds.Contains(eb.BucketId) && eb.EmployeeId == loggedInEmployee.Id);
if (hasContactAccess)
{
_logger.LogWarning("Employee {EmployeeId} does not have permission to delete contact {ContactId}",
loggedInEmployee.Id, id);
return ApiResponse<object>.ErrorResponse("Unauthorized", "You do not have permission", 403);
}
// Try to find the contact for the given tenant // Try to find the contact for the given tenant
Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == id && c.TenantId == tenantId); Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == id && c.TenantId == tenantId);
@ -1505,10 +1561,45 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("Contact ID {ContactId} has been {(DeletedOrActivated)} by Employee ID {EmployeeId}.", id, active ? "activated" : "deleted", loggedInEmployee.Id); _logger.LogInfo("Contact ID {ContactId} has been {(DeletedOrActivated)} by Employee ID {EmployeeId}.", id, active ? "activated" : "deleted", loggedInEmployee.Id);
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
if (bucketIds.Any())
{
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
Notification notification;
if (active)
{
notification = new Notification
{
Title = $"Contact restored - \"{contact.Name}\"",
Body = $"Contact \"{contact.Name}\" is restored by {name} in your bucket"
};
}
else
{
notification = new Notification
{
Title = $"Contact Deleted - \"{contact.Name}\"",
Body = $"Contact \"{contact.Name}\" is deleted by {name} in your bucket"
};
}
await _firebase.SendContactAsync(bucketIds, notification, tenantId);
}
});
return ApiResponse<object>.SuccessResponse(new { }, active ? "Contact is activated successfully" : "Contact is deleted successfully", 200); return ApiResponse<object>.SuccessResponse(new { }, active ? "Contact is activated successfully" : "Contact is deleted successfully", 200);
} }
#endregion #endregion
#endregion #endregion
@ -1929,6 +2020,14 @@ namespace Marco.Pms.Services.Service
try try
{ {
var bucketIds = await _context.ContactBucketMappings.Where(cb => cb.ContactId == noteDto.ContactId).Select(cb => cb.BucketId).ToListAsync();
var hasContactAccess = await _context.EmployeeBucketMappings.AnyAsync(eb => bucketIds.Contains(eb.BucketId) && eb.EmployeeId == loggedInEmployee.Id);
if (hasContactAccess)
{
_logger.LogWarning("Employee {EmployeeId} does not have permission to delete contact {ContactId}",
loggedInEmployee.Id, noteDto.ContactId);
return ApiResponse<object>.ErrorResponse("Unauthorized", "You do not have permission", 403);
}
// Check if the contact exists and is active for this tenant // Check if the contact exists and is active for this tenant
Contact? contact = await _context.Contacts Contact? contact = await _context.Contacts
.AsNoTracking() // optimization for read-only query .AsNoTracking() // optimization for read-only query
@ -1959,6 +2058,27 @@ namespace Marco.Pms.Services.Service
"Employee {EmployeeId} successfully added a note (NoteId: {NoteId}) to Contact {ContactId} for Tenant {TenantId}.", "Employee {EmployeeId} successfully added a note (NoteId: {NoteId}) to Contact {ContactId} for Tenant {TenantId}.",
loggedInEmployee.Id, note.Id, contact.Id, tenantId); loggedInEmployee.Id, note.Id, contact.Id, tenantId);
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
var notification = new Notification
{
Title = $"New note added at Contact - \"{contact.Name}\"",
Body = $"New note added at Contact \"{contact.Name}\" by {name} in your bucket"
};
await _firebase.SendContactNoteAsync(bucketIds, notification, tenantId);
});
return ApiResponse<object>.SuccessResponse(noteVM, "Note added successfully.", 200); return ApiResponse<object>.SuccessResponse(noteVM, "Note added successfully.", 200);
} }
catch (Exception ex) catch (Exception ex)
@ -1991,6 +2111,15 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("Invalid or empty payload", "Invalid or empty payload", 400); return ApiResponse<object>.ErrorResponse("Invalid or empty payload", "Invalid or empty payload", 400);
} }
var bucketIds = await _context.ContactBucketMappings.Where(cb => cb.ContactId == noteDto.ContactId).Select(cb => cb.BucketId).ToListAsync();
var hasContactAccess = await _context.EmployeeBucketMappings.AnyAsync(eb => bucketIds.Contains(eb.BucketId) && eb.EmployeeId == loggedInEmployee.Id);
if (hasContactAccess)
{
_logger.LogWarning("Employee {EmployeeId} does not have permission to delete contact {ContactId}",
loggedInEmployee.Id, noteDto.ContactId);
return ApiResponse<object>.ErrorResponse("Unauthorized", "You do not have permission", 403);
}
// Check if the contact belongs to this tenant // Check if the contact belongs to this tenant
Contact? contact = await _context.Contacts Contact? contact = await _context.Contacts
.AsNoTracking() .AsNoTracking()
@ -2061,6 +2190,27 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("Employee {EmployeeId} successfully updated Note {NoteId} for Contact {ContactId} at {UpdatedAt}", _logger.LogInfo("Employee {EmployeeId} successfully updated Note {NoteId} for Contact {ContactId} at {UpdatedAt}",
loggedInEmployee.Id, noteVM.Id, contact.Id, noteVM.UpdatedAt); loggedInEmployee.Id, noteVM.Id, contact.Id, noteVM.UpdatedAt);
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
var notification = new Notification
{
Title = $"Note updated at Contact - \"{contact.Name}\"",
Body = $"Note updated at Contact \"{contact.Name}\" by {name} in your bucket"
};
await _firebase.SendContactNoteAsync(bucketIds, notification, tenantId);
});
return ApiResponse<object>.SuccessResponse(noteVM, "Note updated successfully", 200); return ApiResponse<object>.SuccessResponse(noteVM, "Note updated successfully", 200);
} }
catch (DbUpdateException ex) catch (DbUpdateException ex)
@ -2103,6 +2253,28 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("Note not found", "Note not found", 404); return ApiResponse<object>.ErrorResponse("Note not found", "Note not found", 404);
} }
var bucketIds = await _context.ContactBucketMappings.Where(cb => cb.ContactId == note.ContactId).Select(cb => cb.BucketId).ToListAsync();
var hasContactAccess = await _context.EmployeeBucketMappings.AnyAsync(eb => bucketIds.Contains(eb.BucketId) && eb.EmployeeId == loggedInEmployee.Id);
if (hasContactAccess)
{
_logger.LogWarning("Employee {EmployeeId} does not have permission to delete contact {ContactId}",
loggedInEmployee.Id, note.ContactId);
return ApiResponse<object>.ErrorResponse("Unauthorized", "You do not have permission", 403);
}
// Check if the contact belongs to this tenant
Contact? contact = await _context.Contacts
.AsNoTracking()
.FirstOrDefaultAsync(c => c.Id == note.ContactId && c.TenantId == tenantId);
if (contact == null)
{
_logger.LogWarning("Employee {EmployeeId} attempted to update note {NoteId} for Contact {ContactId}, but the contact was not found in Tenant {TenantId}.",
loggedInEmployee.Id, note.Id, note.ContactId, tenantId);
return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
}
// Capture old state for audit logging // Capture old state for audit logging
var oldObject = _updateLogsHelper.EntityToBsonDocument(note); var oldObject = _updateLogsHelper.EntityToBsonDocument(note);
@ -2146,6 +2318,38 @@ namespace Marco.Pms.Services.Service
loggedInEmployee.Id, id, currentTime); loggedInEmployee.Id, id, currentTime);
} }
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
Notification notification;
if (active)
{
notification = new Notification
{
Title = $"Note restored at Contact - \"{contact.Name}\"",
Body = $"Note restored at Contact \"{contact.Name}\" by {name} in your bucket"
};
}
else
{
notification = new Notification
{
Title = $"Note deleted at Contact - \"{contact.Name}\"",
Body = $"Note deleted at Contact \"{contact.Name}\" by {name} in your bucket"
};
}
await _firebase.SendContactNoteAsync(bucketIds, notification, tenantId);
});
return ApiResponse<object>.SuccessResponse(new { }, return ApiResponse<object>.SuccessResponse(new { },
active ? "Note restored successfully" : "Note deleted successfully", active ? "Note restored successfully" : "Note deleted successfully",
200); 200);
@ -2264,6 +2468,7 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("Fetched {BucketCount} buckets for Employee {EmployeeId} successfully", bucketVMs.Count, loggedInEmployee.Id); _logger.LogInfo("Fetched {BucketCount} buckets for Employee {EmployeeId} successfully", bucketVMs.Count, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(bucketVMs, $"{bucketVMs.Count} buckets fetched successfully", 200); return ApiResponse<object>.SuccessResponse(bucketVMs, $"{bucketVMs.Count} buckets fetched successfully", 200);
} }
public async Task<ApiResponse<object>> CreateBucketAsync(CreateBucketDto bucketDto, Guid tenantId, Employee loggedInEmployee) public async Task<ApiResponse<object>> CreateBucketAsync(CreateBucketDto bucketDto, Guid tenantId, Employee loggedInEmployee)
@ -2337,6 +2542,27 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("Employee {EmployeeId} successfully created bucket {BucketId}", loggedInEmployee.Id, newBucket.Id); _logger.LogInfo("Employee {EmployeeId} successfully created bucket {BucketId}", loggedInEmployee.Id, newBucket.Id);
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
var notification = new Notification
{
Title = "New Bucket created",
Body = $"New Bucket created \"{newBucket.Name}\" by {name}"
};
await _firebase.SendBucketAsync(newBucket.Id, notification, tenantId);
});
return ApiResponse<object>.SuccessResponse(bucketVM, "Bucket created successfully", 200); return ApiResponse<object>.SuccessResponse(bucketVM, "Bucket created successfully", 200);
} }
catch (Exception ex) catch (Exception ex)
@ -2449,6 +2675,27 @@ namespace Marco.Pms.Services.Service
_logger.LogInfo("Employee ID {LoggedInEmployeeId} successfully updated bucket ID {BucketId}.", loggedInEmployee.Id, bucket.Id); _logger.LogInfo("Employee ID {LoggedInEmployeeId} successfully updated bucket ID {BucketId}.", loggedInEmployee.Id, bucket.Id);
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
var notification = new Notification
{
Title = $"Bucket updated - \"{bucket.Name}\"",
Body = $"Bucket updated \"{bucket.Name}\" by {name}"
};
await _firebase.SendBucketAsync(bucket.Id, notification, tenantId);
});
return ApiResponse<object>.SuccessResponse(bucketVM, "Bucket updated successfully", 200); return ApiResponse<object>.SuccessResponse(bucketVM, "Bucket updated successfully", 200);
} }
catch (Exception ex) catch (Exception ex)
@ -2519,6 +2766,9 @@ namespace Marco.Pms.Services.Service
int assignedEmployeesCount = 0; int assignedEmployeesCount = 0;
int removedEmployeesCount = 0; int removedEmployeesCount = 0;
List<Guid> assignedEmployeeIds = new List<Guid>();
List<Guid> removedEmployeeIds = new List<Guid>();
// Process each assignment request // Process each assignment request
foreach (var assignBucket in assignBuckets) foreach (var assignBucket in assignBuckets)
{ {
@ -2541,6 +2791,7 @@ namespace Marco.Pms.Services.Service
}; };
_context.EmployeeBucketMappings.Add(newMapping); _context.EmployeeBucketMappings.Add(newMapping);
assignedEmployeesCount++; assignedEmployeesCount++;
assignedEmployeeIds.Add(assignBucket.EmployeeId);
} }
} }
else else
@ -2549,6 +2800,7 @@ namespace Marco.Pms.Services.Service
var existingMapping = employeeBuckets.FirstOrDefault(eb => eb.EmployeeId == assignBucket.EmployeeId); var existingMapping = employeeBuckets.FirstOrDefault(eb => eb.EmployeeId == assignBucket.EmployeeId);
if (existingMapping != null && bucket.CreatedByID != assignBucket.EmployeeId) if (existingMapping != null && bucket.CreatedByID != assignBucket.EmployeeId)
{ {
removedEmployeeIds.Add(existingMapping.EmployeeId);
_context.EmployeeBucketMappings.Remove(existingMapping); _context.EmployeeBucketMappings.Remove(existingMapping);
removedEmployeesCount++; removedEmployeesCount++;
} }
@ -2607,7 +2859,41 @@ namespace Marco.Pms.Services.Service
{ {
_logger.LogInfo("Employee {EmployeeId} removed {Count} employees from bucket {BucketId}.", loggedInEmployee.Id, removedEmployeesCount, bucketId); _logger.LogInfo("Employee {EmployeeId} removed {Count} employees from bucket {BucketId}.", loggedInEmployee.Id, removedEmployeesCount, bucketId);
} }
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
if (assignedEmployeeIds.Any())
{
var notification = new Notification
{
Title = "You have assigned to Bucket",
Body = $"You have assigned to bucket \"{bucket.Name}\" by {name}"
};
await _firebase.SendAssignBucketAsync(assignedEmployeeIds, notification, tenantId);
}
if (removedEmployeeIds.Any())
{
var notification = new Notification
{
Title = "You have removed from Bucket",
Body = $"You have removed from bucket \"{bucket.Name}\" by {name}"
};
await _firebase.SendAssignBucketAsync(removedEmployeeIds, notification, tenantId);
}
});
return ApiResponse<object>.SuccessResponse(bucketVm, "Bucket details updated successfully", 200); return ApiResponse<object>.SuccessResponse(bucketVm, "Bucket details updated successfully", 200);
} }
public async Task<ApiResponse<object>> DeleteBucketAsync(Guid id, Guid tenantId, Employee loggedInEmployee) public async Task<ApiResponse<object>> DeleteBucketAsync(Guid id, Guid tenantId, Employee loggedInEmployee)
@ -2720,6 +3006,27 @@ namespace Marco.Pms.Services.Service
UpdatedAt = DateTime.UtcNow UpdatedAt = DateTime.UtcNow
}, bucketCollection); }, bucketCollection);
using var scope = _serviceScopeFactory.CreateScope();
_ = Task.Run(async () =>
{
// --- Push Notification Section ---
// This section attempts to send a test push notification to the user's device.
// It's designed to fail gracefully and handle invalid Firebase Cloud Messaging (FCM) tokens.
var _firebase = scope.ServiceProvider.GetRequiredService<IFirebaseService>();
var name = $"{loggedInEmployee.FirstName} {loggedInEmployee.LastName}";
var notification = new Notification
{
Title = $"Bucket deleted - \"{bucket.Name}\"",
Body = $"Bucket deleted \"{bucket.Name}\" by {name}"
};
await _firebase.SendBucketAsync(bucket.Id, notification, tenantId);
});
return ApiResponse<object>.SuccessResponse(new { }, "Bucket deleted successfully", 200); return ApiResponse<object>.SuccessResponse(new { }, "Bucket deleted successfully", 200);
} }
catch (Exception ex) catch (Exception ex)

View File

@ -31,6 +31,7 @@ namespace Marco.Pms.Services.Service
_serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory)); _serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory));
} }
// Auth Controller
public async Task SendLoginOnAnotherDeviceMessageAsync(Guid employeeId, string fcmToken, Guid tenentId) public async Task SendLoginOnAnotherDeviceMessageAsync(Guid employeeId, string fcmToken, Guid tenentId)
{ {
await using var _context = await _dbContextFactory.CreateDbContextAsync(); await using var _context = await _dbContextFactory.CreateDbContextAsync();
@ -1622,6 +1623,152 @@ namespace Marco.Pms.Services.Service
} }
} }
// 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);
}
#region =================================================================== Helper Functions =================================================================== #region =================================================================== Helper Functions ===================================================================
public async Task SendMessageToMultipleDevicesWithDataAsync(List<string> registrationTokens, Notification notificationFirebase, Dictionary<string, string> data) public async Task SendMessageToMultipleDevicesWithDataAsync(List<string> registrationTokens, Notification notificationFirebase, Dictionary<string, string> data)

View File

@ -1,4 +1,5 @@
using Marco.Pms.Model.Dtos.Attendance; using FirebaseAdmin.Messaging;
using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Expenses; using Marco.Pms.Model.Expenses;
using Marco.Pms.Model.Projects; using Marco.Pms.Model.Projects;
@ -22,5 +23,10 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task SendProjectAllocationMessageAsync(List<ProjectAllocation> projectAllocations, string name, Guid tenantId); Task SendProjectAllocationMessageAsync(List<ProjectAllocation> projectAllocations, string name, Guid tenantId);
Task SendModifyProjectMessageAsync(Project project, string name, bool IsExist, Guid tenantId); Task SendModifyProjectMessageAsync(Project project, string name, bool IsExist, Guid tenantId);
Task SendExpenseMessageAsync(Expenses expenses, string name, Guid tenantId); Task SendExpenseMessageAsync(Expenses expenses, string name, Guid tenantId);
Task SendContactAsync(List<Guid> bucketIds, Notification notification, Guid tenantId);
Task SendContactNoteAsync(List<Guid> bucketIds, Notification notification, Guid tenantId);
Task SendBucketAsync(Guid bucketId, Notification notification, Guid tenantId);
Task SendAssignBucketAsync(List<Guid> employeeIds, Notification notification, Guid tenantId);
} }
} }