using Marco.Pms.Model.Filters; using System.Linq.Dynamic.Core; namespace Marco.Pms.Services.Extensions { /// /// Enterprise-grade extension methods for applying dynamic filters and sorting to IQueryable sources. /// public static class QueryableExtensions { public static IQueryable ApplyCustomFilters(this IQueryable query, AdvanceFilter filter) { // 1. Apply Advanced Filters (Arithmetic/Logic) if (filter.AdvanceFilters != null && filter.AdvanceFilters.Any()) { foreach (var advanceFilter in filter.AdvanceFilters) { if (string.IsNullOrWhiteSpace(advanceFilter.Column)) continue; string op = advanceFilter.Opration.ToLower().Trim(); string predicate = ""; // Map your custom strings to Dynamic LINQ operators switch (op) { case "greater than": predicate = $"{advanceFilter.Column} > @0"; break; case "less than": predicate = $"{advanceFilter.Column} < @0"; break; case "equal to": predicate = $"{advanceFilter.Column} == @0"; break; case "not equal": predicate = $"{advanceFilter.Column} != @0"; break; case "greater or equal": predicate = $"{advanceFilter.Column} >= @0"; break; case "smaller or equal": predicate = $"{advanceFilter.Column} <= @0"; break; default: continue; } if (!string.IsNullOrEmpty(predicate)) { // Dynamic LINQ handles type conversion (string "100" to int 100) automatically query = query.Where(predicate, advanceFilter.Value); } } } // 2. Apply Sorting if (filter.SortFilters != null && filter.SortFilters.Any()) { // Build a comma-separated sort string: "Column1 desc, Column2 asc" var sortExpressions = new List(); foreach (var sort in filter.SortFilters) { string direction = sort.SortDescending ? "desc" : "asc"; sortExpressions.Add($"{sort.Column} {direction}"); } query = query.OrderBy(string.Join(", ", sortExpressions)); } return query; } public static IQueryable ApplySearchFilters(this IQueryable query, List searchFilters) { // 1. Apply Search Filters (Contains/Text search) if (searchFilters.Any()) { foreach (var search in searchFilters) { if (string.IsNullOrWhiteSpace(search.Column) || string.IsNullOrWhiteSpace(search.Value)) continue; // Generates: x.Column.Contains("Value") // Case insensitive logic can be handled here if needed query = query.Where($"{search.Column}.Contains(@0)", search.Value); } } return query; } public static IQueryable ApplyGroupByFilters(this IQueryable query, string groupByColumn) { query.GroupBy(groupByColumn).Select("new (Key, ToList() as Items)"); // Reshape to { Key: "Value", Items: [...] } return query; } } }