117 lines
4.9 KiB
C#

using Marco.Pms.Model.MongoDBModels.Expenses;
using Marco.Pms.Model.Utilities;
using Microsoft.Extensions.Configuration;
using MongoDB.Driver;
namespace Marco.Pms.Helpers.CacheHelper
{
public class ExpenseCache
{
private readonly IMongoCollection<ExpenseDetailsMongoDB> _collection;
public ExpenseCache(IConfiguration configuration)
{
var connectionString = configuration["MongoDB:ConnectionString"];
var mongoUrl = new MongoUrl(connectionString);
var client = new MongoClient(mongoUrl); // Your MongoDB connection string
var mongoDB = client.GetDatabase(mongoUrl.DatabaseName); // Your MongoDB Database name
_collection = mongoDB.GetCollection<ExpenseDetailsMongoDB>("Expenses");
}
public async Task AddExpenseToCacheAsync(ExpenseDetailsMongoDB expense)
{
await _collection.InsertOneAsync(expense);
await InitializeCollectionAsync();
}
public async Task AddExpensesListToCacheAsync(List<ExpenseDetailsMongoDB> expenses)
{
// 1. Add a guard clause to avoid an unnecessary database call for an empty list.
if (expenses == null || !expenses.Any())
{
return;
}
// 2. Perform the insert operation. This is the only responsibility of this method.
await _collection.InsertManyAsync(expenses);
await InitializeCollectionAsync();
}
public async Task<(int totalPages, long totalCount, List<ExpenseDetailsMongoDB> expenseList)> GetExpenseListFromCacheAsync(Guid tenantId, Guid loggedInEmployeeId, bool viewAll,
bool viewSelf, int pageNumber, int pageSize, ExpensesFilter? expenseFilter)
{
var filterBuilder = Builders<ExpenseDetailsMongoDB>.Filter;
var filter = filterBuilder.Empty;
// Permission-based filter
if (!viewAll && viewSelf)
{
filter &= filterBuilder.Eq(e => e.CreatedById, loggedInEmployeeId.ToString());
}
// Apply filters
if (expenseFilter != null)
{
if (expenseFilter.StartDate.HasValue && expenseFilter.EndDate.HasValue)
{
filter &= filterBuilder.Gte(e => e.CreatedAt, expenseFilter.StartDate.Value.Date)
& filterBuilder.Lte(e => e.CreatedAt, expenseFilter.EndDate.Value.Date.AddDays(1).AddTicks(-1));
}
if (expenseFilter.ProjectIds?.Any() == true)
{
filter &= filterBuilder.In(e => e.ProjectId, expenseFilter.ProjectIds.Select(p => p.ToString()).ToList());
}
if (expenseFilter.StatusIds?.Any() == true)
{
filter &= filterBuilder.In(e => e.StatusId, expenseFilter.StatusIds.Select(p => p.ToString()).ToList());
}
if (expenseFilter.PaidById?.Any() == true)
{
filter &= filterBuilder.In(e => e.PaidById, expenseFilter.PaidById.Select(p => p.ToString()).ToList());
}
if (expenseFilter.CreatedByIds?.Any() == true && viewAll)
{
filter &= filterBuilder.In(e => e.CreatedById, expenseFilter.CreatedByIds.Select(p => p.ToString()).ToList());
}
}
// Total count
var totalCount = await _collection.CountDocumentsAsync(filter);
var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
// Fetch paginated data
var expenses = await _collection
.Find(filter)
.Skip((pageNumber - 1) * pageSize)
.Limit(pageSize)
.SortByDescending(e => e.CreatedAt)
.ToListAsync();
return (totalPages, totalCount, expenses);
}
public async Task<ExpenseDetailsMongoDB> GetExpenseDetailsByIdAsync(Guid id, Guid tenantId)
{
var filter = Builders<ExpenseDetailsMongoDB>.Filter.And(
Builders<ExpenseDetailsMongoDB>.Filter.Eq(e => e.Id, id.ToString()),
Builders<ExpenseDetailsMongoDB>.Filter.Eq(e => e.TenantId, tenantId.ToString())
);
var expense = await _collection.Find(filter).FirstOrDefaultAsync();
return expense;
}
private async Task InitializeCollectionAsync()
{
var indexKeys = Builders<ExpenseDetailsMongoDB>.IndexKeys.Ascending(x => x.ExpireAt);
var indexOptions = new CreateIndexOptions
{
ExpireAfter = TimeSpan.Zero // required for fixed expiration time
};
var indexModel = new CreateIndexModel<ExpenseDetailsMongoDB>(indexKeys, indexOptions);
await _collection.Indexes.CreateOneAsync(indexModel);
}
}
}