From 28f28c4799842a609cf46d361a3d0b006b4a688a Mon Sep 17 00:00:00 2001 From: "hualin.zhu" <neo.js.cn@gmail.com> Date: Thu, 10 Aug 2023 20:48:28 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8Refactoring=20Specification=20Query?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuditTrailsWithPaginationQuery.cs | 38 ++---------- .../Specification/AuditTrailAdvancedFilter.cs | 17 +++++ .../AuditTrailAdvancedSpecification.cs | 23 +++++++ .../Commands/Create/CreateCustomerCommand.cs | 1 + .../Commands/Update/UpdateCustomerCommand.cs | 1 + .../Features/Customers/DTOs/CustomerDto.cs | 1 + .../Queries/Export/ExportCustomersQuery.cs | 6 +- .../Queries/GetAll/GetAllCustomersQuery.cs | 60 +++++++++--------- .../Queries/GetById/GetCustomerByIdQuery.cs | 62 +++++++++---------- .../Pagination/CustomersPaginationQuery.cs | 45 ++------------ .../Specification/CustomerAdvancedFilter.cs | 19 ++++++ .../Specification/CustomerAdvancedSpec.cs | 23 +++++++ .../Queries/Specification/CustomerByIdSpec.cs | 9 +++ .../DocumentsWithPaginationQuery.cs | 27 ++------ .../Specification/AdvancedDocumentsFilter.cs | 13 ++++ .../AdvancedDocumentsSpecification.cs | 16 +++++ .../KeyValuesWithPaginationQuery.cs | 17 ++--- .../Specification/KeyValueAdvancedFilter.cs | 7 +++ .../KeyValueAdvancedSpecification.cs | 11 ++++ .../LogsWithPaginationQuery.cs | 34 ++-------- .../Specification/LoggerAdvancedFilter.cs | 14 +++++ .../LoggerAdvancedSpecification.cs | 22 +++++++ .../Queries/Export/ExportProductsQuery.cs | 16 +---- .../Pagination/ProductsPaginationQuery.cs | 13 +--- .../ExportProductSpecification.cs | 29 --------- .../Specification/ProductAdvancedFilter.cs | 12 ++++ .../ProductAdvancedSpecification.cs | 30 +++++++++ .../SearchProductSpecification.cs | 31 ---------- .../Pages/Customers/Customers.razor | 1 + .../Pages/Documents/Documents.razor | 1 + .../Pages/SystemManagement/AuditTrails.razor | 1 + .../Pages/SystemManagement/Logs.razor | 1 + 32 files changed, 313 insertions(+), 288 deletions(-) create mode 100644 src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedFilter.cs create mode 100644 src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedSpecification.cs create mode 100644 src/Application/Features/Customers/Queries/Specification/CustomerAdvancedFilter.cs create mode 100644 src/Application/Features/Customers/Queries/Specification/CustomerAdvancedSpec.cs create mode 100644 src/Application/Features/Customers/Queries/Specification/CustomerByIdSpec.cs create mode 100644 src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsFilter.cs create mode 100644 src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsSpecification.cs create mode 100644 src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedFilter.cs create mode 100644 src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedSpecification.cs create mode 100644 src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedFilter.cs create mode 100644 src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedSpecification.cs delete mode 100644 src/Application/Features/Products/Queries/Specification/ExportProductSpecification.cs create mode 100644 src/Application/Features/Products/Queries/Specification/ProductAdvancedFilter.cs create mode 100644 src/Application/Features/Products/Queries/Specification/ProductAdvancedSpecification.cs delete mode 100644 src/Application/Features/Products/Queries/Specification/SearchProductSpecification.cs diff --git a/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs b/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs index 45f9f0548..3356c0a46 100644 --- a/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs +++ b/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs @@ -3,18 +3,16 @@ using CleanArchitecture.Blazor.Application.Features.AuditTrails.Caching; using CleanArchitecture.Blazor.Application.Features.AuditTrails.DTOs; -using CleanArchitecture.Blazor.Domain.Enums; +using CleanArchitecture.Blazor.Application.Features.AuditTrails.Queries.Specification; namespace CleanArchitecture.Blazor.Application.Features.AuditTrails.Queries.PaginationQuery; -public class AuditTrailsWithPaginationQuery : PaginationFilter, ICacheableRequest<PaginatedData<AuditTrailDto>> +public class AuditTrailsWithPaginationQuery : AuditTrailAdvancedFilter, ICacheableRequest<PaginatedData<AuditTrailDto>> { - public AuditType? AuditType { get; set; } - public AuditTrailListView ListView { get; set; } = AuditTrailListView.All; + public string CacheKey => AuditTrailsCacheKey.GetPaginationCacheKey($"{this}"); - public UserProfile? CurrentUser { get; set; } public MemoryCacheEntryOptions? Options => AuditTrailsCacheKey.MemoryCacheEntryOptions; - public AuditTrailsQuerySpec Specification => new AuditTrailsQuerySpec(this); + public AuditTrailAdvancedSpecification Specification => new AuditTrailAdvancedSpecification(this); public override string ToString() { return @@ -49,32 +47,4 @@ public async Task<PaginatedData<AuditTrailDto>> Handle(AuditTrailsWithPagination } } -public enum AuditTrailListView -{ - [Description("All")] All, - [Description("My Change Histories")] My, - [Description("Created Toady")] CreatedToday, - [Description("View of the last 30 days")] - Last30days -} -public class AuditTrailsQuerySpec : Specification<AuditTrail> -{ - public AuditTrailsQuerySpec(AuditTrailsWithPaginationQuery request) - { - var today = DateTime.Now.Date; - var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", - CultureInfo.CurrentCulture); - var last30day = Convert.ToDateTime( - today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - - Query.Where(p => p.AuditType==request.AuditType, request.AuditType is not null) - .Where(p => p.UserId == request.CurrentUser.UserId, request.ListView == AuditTrailListView.My && request.CurrentUser is not null) - .Where(p => p.DateTime.Date == DateTime.Now.Date, request.ListView == AuditTrailListView.CreatedToday) - .Where(p => p.DateTime >= last30day, request.ListView == AuditTrailListView.Last30days) - .Where(x => x.TableName.Contains(request.Keyword) , !string.IsNullOrEmpty(request.Keyword)); - } -} \ No newline at end of file diff --git a/src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedFilter.cs b/src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedFilter.cs new file mode 100644 index 000000000..4953f652b --- /dev/null +++ b/src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedFilter.cs @@ -0,0 +1,17 @@ +using CleanArchitecture.Blazor.Domain.Enums; + +namespace CleanArchitecture.Blazor.Application.Features.AuditTrails.Queries.Specification; +public enum AuditTrailListView +{ + [Description("All")] All, + [Description("My Change Histories")] My, + [Description("Created Toady")] CreatedToday, + [Description("View of the last 30 days")] + Last30days +} +public class AuditTrailAdvancedFilter : PaginationFilter +{ + public AuditType? AuditType { get; set; } + public AuditTrailListView ListView { get; set; } = AuditTrailListView.All; + public UserProfile? CurrentUser { get; set; } +} diff --git a/src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedSpecification.cs b/src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedSpecification.cs new file mode 100644 index 000000000..2108106d0 --- /dev/null +++ b/src/Application/Features/AuditTrails/Queries/Specification/AuditTrailAdvancedSpecification.cs @@ -0,0 +1,23 @@ +namespace CleanArchitecture.Blazor.Application.Features.AuditTrails.Queries.Specification; + +public class AuditTrailAdvancedSpecification : Specification<AuditTrail> +{ + public AuditTrailAdvancedSpecification(AuditTrailAdvancedFilter filter) + { + var today = DateTime.Now.Date; + var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", + CultureInfo.CurrentCulture); + var last30day = Convert.ToDateTime( + today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + + Query.Where(p => p.AuditType == filter.AuditType, filter.AuditType is not null) + .Where(p => p.UserId == filter.CurrentUser.UserId, filter.ListView == AuditTrailListView.My && filter.CurrentUser is not null) + .Where(p => p.DateTime.Date == DateTime.Now.Date, filter.ListView == AuditTrailListView.CreatedToday) + .Where(p => p.DateTime >= last30day, filter.ListView == AuditTrailListView.Last30days) + .Where(x => x.TableName.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword)); + + } +} \ No newline at end of file diff --git a/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs b/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs index 79c7dddb9..17f61a1ee 100644 --- a/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs +++ b/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs @@ -1,5 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; using CleanArchitecture.Blazor.Application.Features.Customers.Caching; diff --git a/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs b/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs index 2fd391010..eafb6dc24 100644 --- a/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs +++ b/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs @@ -1,5 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; using CleanArchitecture.Blazor.Application.Features.Customers.Caching; diff --git a/src/Application/Features/Customers/DTOs/CustomerDto.cs b/src/Application/Features/Customers/DTOs/CustomerDto.cs index 3e2b86e81..15785e31c 100644 --- a/src/Application/Features/Customers/DTOs/CustomerDto.cs +++ b/src/Application/Features/Customers/DTOs/CustomerDto.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel; namespace CleanArchitecture.Blazor.Application.Features.Customers.DTOs; [Description("Customers")] diff --git a/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs b/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs index 575b636be..a9d36a098 100644 --- a/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs +++ b/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs @@ -1,19 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. - using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Pagination; +using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Specification; namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.Export; -public class ExportCustomersQuery : BaseFilter, IRequest<Result<byte[]>> +public class ExportCustomersQuery : CustomerAdvancedFilter, IRequest<Result<byte[]>> { public string OrderBy { get; set; } = "Id"; public string SortDirection { get; set; } = "Descending"; public CustomerListView ListView { get; set; } = CustomerListView.All; public UserProfile? CurrentUser { get; set; } - public CustomersExportSpecification Specification => new CustomersExportSpecification(this); + public CustomerAdvancedPaginationSpec Specification => new CustomerAdvancedPaginationSpec(this); } public class ExportCustomersQueryHandler : diff --git a/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs b/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs index 4fa5d6465..f3fb34a0b 100644 --- a/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs +++ b/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs @@ -6,39 +6,39 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.GetAll; - public class GetAllCustomersQuery : ICacheableRequest<IEnumerable<CustomerDto>> +public class GetAllCustomersQuery : ICacheableRequest<IEnumerable<CustomerDto>> +{ + public string CacheKey => CustomerCacheKey.GetAllCacheKey; + public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; +} + +public class GetAllCustomersQueryHandler : + IRequestHandler<GetAllCustomersQuery, IEnumerable<CustomerDto>> +{ + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer<GetAllCustomersQueryHandler> _localizer; + + public GetAllCustomersQueryHandler( + IApplicationDbContext context, + IMapper mapper, + IStringLocalizer<GetAllCustomersQueryHandler> localizer + ) { - public string CacheKey => CustomerCacheKey.GetAllCacheKey; - public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; + _context = context; + _mapper = mapper; + _localizer = localizer; } - - public class GetAllCustomersQueryHandler : - IRequestHandler<GetAllCustomersQuery, IEnumerable<CustomerDto>> + + public async Task<IEnumerable<CustomerDto>> Handle(GetAllCustomersQuery request, CancellationToken cancellationToken) { - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - private readonly IStringLocalizer<GetAllCustomersQueryHandler> _localizer; - - public GetAllCustomersQueryHandler( - IApplicationDbContext context, - IMapper mapper, - IStringLocalizer<GetAllCustomersQueryHandler> localizer - ) - { - _context = context; - _mapper = mapper; - _localizer = localizer; - } - - public async Task<IEnumerable<CustomerDto>> Handle(GetAllCustomersQuery request, CancellationToken cancellationToken) - { - // TODO: Implement GetAllCustomersQueryHandler method - var data = await _context.Customers - .ProjectTo<CustomerDto>(_mapper.ConfigurationProvider) - .AsNoTracking() - .ToListAsync(cancellationToken); - return data; - } + // TODO: Implement GetAllCustomersQueryHandler method + var data = await _context.Customers + .ProjectTo<CustomerDto>(_mapper.ConfigurationProvider) + .AsNoTracking() + .ToListAsync(cancellationToken); + return data; } +} diff --git a/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs b/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs index 53484ee7a..0805b328d 100644 --- a/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs +++ b/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs @@ -6,39 +6,37 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.GetById; - public class GetCustomerByIdQuery : ICacheableRequest<CustomerDto> - { - public required int Id { get; set; } - public string CacheKey => CustomerCacheKey.GetByIdCacheKey($"{Id}"); - public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; - } - - public class GetCustomerByIdQueryHandler : - IRequestHandler<GetCustomerByIdQuery, CustomerDto> - { - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - private readonly IStringLocalizer<GetCustomerByIdQueryHandler> _localizer; +public class GetCustomerByIdQuery : ICacheableRequest<CustomerDto> +{ + public required int Id { get; set; } + public string CacheKey => CustomerCacheKey.GetByIdCacheKey($"{Id}"); + public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; +} - public GetCustomerByIdQueryHandler( - IApplicationDbContext context, - IMapper mapper, - IStringLocalizer<GetCustomerByIdQueryHandler> localizer - ) - { - _context = context; - _mapper = mapper; - _localizer = localizer; - } +public class GetCustomerByIdQueryHandler : + IRequestHandler<GetCustomerByIdQuery, CustomerDto> +{ + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer<GetCustomerByIdQueryHandler> _localizer; - public async Task<CustomerDto> Handle(GetCustomerByIdQuery request, CancellationToken cancellationToken) - { - // TODO: Implement GetCustomerByIdQueryHandler method - var data = await _context.Customers.Where(x => x.Id == request.Id) - .ProjectTo<CustomerDto>(_mapper.ConfigurationProvider) - .FirstAsync(cancellationToken) ?? throw new NotFoundException($"Customer with id: [{request.Id}] not found.");; - return data; - } + public GetCustomerByIdQueryHandler( + IApplicationDbContext context, + IMapper mapper, + IStringLocalizer<GetCustomerByIdQueryHandler> localizer + ) + { + _context = context; + _mapper = mapper; + _localizer = localizer; } - + public async Task<CustomerDto> Handle(GetCustomerByIdQuery request, CancellationToken cancellationToken) + { + // TODO: Implement GetCustomerByIdQueryHandler method + var data = await _context.Customers.ApplySpecification(new CustomerByIdSpec(request.Id)) + .ProjectTo<CustomerDto>(_mapper.ConfigurationProvider) + .FirstAsync(cancellationToken) ?? throw new NotFoundException($"Customer with id: [{request.Id}] not found.");; + return data; + } +} diff --git a/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs b/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs index 385771e34..c327c3f3d 100644 --- a/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs +++ b/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs @@ -3,20 +3,19 @@ using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; using CleanArchitecture.Blazor.Application.Features.Customers.Caching; +using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Specification; namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.Pagination; -public class CustomersWithPaginationQuery : PaginationFilter, ICacheableRequest<PaginatedData<CustomerDto>> +public class CustomersWithPaginationQuery : CustomerAdvancedFilter, ICacheableRequest<PaginatedData<CustomerDto>> { - public CustomerListView ListView { get; set; } = CustomerListView.All; - public UserProfile? CurrentUser { get; set; } public override string ToString() { return $"Listview:{ListView}, Search:{Keyword}, {OrderBy}, {SortDirection}, {PageNumber}, {PageSize}"; } public string CacheKey => CustomerCacheKey.GetPaginationCacheKey($"{this}"); public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; - public CustomersPaginationSpecification Specification => new CustomersPaginationSpecification(this); + public CustomerAdvancedPaginationSpec Specification => new CustomerAdvancedPaginationSpec(this); } public class CustomersWithPaginationQueryHandler : @@ -41,41 +40,7 @@ public async Task<PaginatedData<CustomerDto>> Handle(CustomersWithPaginationQuer { // TODO: Implement CustomersWithPaginationQueryHandler method var data = await _context.Customers.OrderBy($"{request.OrderBy} {request.SortDirection}") - .ProjectToPaginatedDataAsync<Customer, CustomerDto>(request.Specification, request.PageNumber, request.PageSize, _mapper.ConfigurationProvider, cancellationToken); - return data; + .ProjectToPaginatedDataAsync<Customer, CustomerDto>(request.Specification, request.PageNumber, request.PageSize, _mapper.ConfigurationProvider, cancellationToken); + return data; } -} - -public class CustomersPaginationSpecification : Specification<Customer> -{ - public CustomersPaginationSpecification(CustomersWithPaginationQuery query) - { - var today = DateTime.Now.Date; - var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", - CultureInfo.CurrentCulture); - var last30day = Convert.ToDateTime( - today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - - Query.Where(q => q.Name != null) - .Where(q => q.Name!.Contains(query.Keyword) || q.Description!.Contains(query.Keyword), !string.IsNullOrEmpty(query.Keyword)) - .Where(q => q.CreatedBy == query.CurrentUser.UserId, query.ListView == CustomerListView.My && query.CurrentUser is not null) - .Where(q => q.Created >= start && q.Created <= end, query.ListView == CustomerListView.CreatedToday) - .Where(q => q.Created >= last30day, query.ListView == CustomerListView.Created30Days); - - } -} - -public enum CustomerListView -{ - [Description("All")] - All, - [Description("My")] - My, - [Description("Created Toady")] - CreatedToday, - [Description("Created within the last 30 days")] - Created30Days } \ No newline at end of file diff --git a/src/Application/Features/Customers/Queries/Specification/CustomerAdvancedFilter.cs b/src/Application/Features/Customers/Queries/Specification/CustomerAdvancedFilter.cs new file mode 100644 index 000000000..47936fbd9 --- /dev/null +++ b/src/Application/Features/Customers/Queries/Specification/CustomerAdvancedFilter.cs @@ -0,0 +1,19 @@ +namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.Specification; + +public enum CustomerListView +{ + [Description("All")] + All, + [Description("My")] + My, + [Description("Created Toady")] + CreatedToday, + [Description("Created within the last 30 days")] + Created30Days +} + +public class CustomerAdvancedFilter: PaginationFilter +{ + public CustomerListView ListView { get; set; } = CustomerListView.All; + public UserProfile? CurrentUser { get; set; } +} \ No newline at end of file diff --git a/src/Application/Features/Customers/Queries/Specification/CustomerAdvancedSpec.cs b/src/Application/Features/Customers/Queries/Specification/CustomerAdvancedSpec.cs new file mode 100644 index 000000000..7ece24ff8 --- /dev/null +++ b/src/Application/Features/Customers/Queries/Specification/CustomerAdvancedSpec.cs @@ -0,0 +1,23 @@ +namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.Specification; + +public class CustomerAdvancedPaginationSpec : Specification<Customer> +{ + public CustomerAdvancedPaginationSpec(CustomerAdvancedFilter filter) + { + var today = DateTime.Now.Date; + var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", + CultureInfo.CurrentCulture); + var last30day = Convert.ToDateTime( + today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + + Query.Where(q => q.Name != null) + .Where(q => q.Name!.Contains(filter.Keyword) || q.Description!.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword)) + .Where(q => q.CreatedBy == filter.CurrentUser.UserId, filter.ListView == CustomerListView.My && filter.CurrentUser is not null) + .Where(q => q.Created >= start && q.Created <= end, filter.ListView == CustomerListView.CreatedToday) + .Where(q => q.Created >= last30day, filter.ListView == CustomerListView.Created30Days); + + } +} \ No newline at end of file diff --git a/src/Application/Features/Customers/Queries/Specification/CustomerByIdSpec.cs b/src/Application/Features/Customers/Queries/Specification/CustomerByIdSpec.cs new file mode 100644 index 000000000..61be0bd9a --- /dev/null +++ b/src/Application/Features/Customers/Queries/Specification/CustomerByIdSpec.cs @@ -0,0 +1,9 @@ +namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.Specification; + +public class CustomerByIdSpec : Specification<Customer> +{ + public CustomerByIdSpec(int id) + { + Query.Where(q => q.Id == id); + } +} \ No newline at end of file diff --git a/src/Application/Features/Documents/Queries/PaginationQuery/DocumentsWithPaginationQuery.cs b/src/Application/Features/Documents/Queries/PaginationQuery/DocumentsWithPaginationQuery.cs index cc1f25c4d..9276d9762 100644 --- a/src/Application/Features/Documents/Queries/PaginationQuery/DocumentsWithPaginationQuery.cs +++ b/src/Application/Features/Documents/Queries/PaginationQuery/DocumentsWithPaginationQuery.cs @@ -3,13 +3,13 @@ using CleanArchitecture.Blazor.Application.Features.Documents.Caching; using CleanArchitecture.Blazor.Application.Features.Documents.DTOs; +using CleanArchitecture.Blazor.Application.Features.Documents.Queries.Specification; namespace CleanArchitecture.Blazor.Application.Features.Documents.Queries.PaginationQuery; -public class DocumentsWithPaginationQuery : PaginationFilter, ICacheableRequest<PaginatedData<DocumentDto>> +public class DocumentsWithPaginationQuery : AdvancedDocumentsFilter, ICacheableRequest<PaginatedData<DocumentDto>> { - public DocumentListView ListView { get; set; } = DocumentListView.All; - public required UserProfile CurrentUser { get; set; } + public string CacheKey => DocumentCacheKey.GetPaginationCacheKey($"{this}"); public MemoryCacheEntryOptions? Options => DocumentCacheKey.MemoryCacheEntryOptions; @@ -19,7 +19,7 @@ public override string ToString() $"CurrentUserId:{CurrentUser?.UserId},ListView:{ListView},Search:{Keyword},OrderBy:{OrderBy} {SortDirection},{PageNumber},{PageSize}"; } - public DocumentsQuerySpec Specification=>new DocumentsQuerySpec(this); + public AdvancedDocumentsSpecification Specification =>new AdvancedDocumentsSpecification(this); } public class DocumentsQueryHandler : IRequestHandler<DocumentsWithPaginationQuery, PaginatedData<DocumentDto>> @@ -47,24 +47,5 @@ public async Task<PaginatedData<DocumentDto>> Handle(DocumentsWithPaginationQuer } -public class DocumentsQuerySpec : Specification<Document> -{ - public DocumentsQuerySpec(DocumentsWithPaginationQuery request) - { - Query.Where(p => - (p.CreatedBy == request.CurrentUser.UserId && p.IsPublic == false) || - (p.IsPublic == true && p.TenantId == request.CurrentUser.TenantId), request.ListView == DocumentListView.All) - .Where(p => - p.CreatedBy == request.CurrentUser.UserId && p.TenantId == request.CurrentUser.TenantId, request.ListView == DocumentListView.My) - .Where(p => p.Created.Value.Date == DateTime.Now.Date, request.ListView == DocumentListView.CreatedToday) - .Where(x => x.Title.Contains(request.Keyword) || x.Description.Contains(request.Keyword) || x.Content.Contains(request.Keyword), !string.IsNullOrEmpty(request.Keyword)); - } -} -public enum DocumentListView -{ - [Description("All")] All, - [Description("My Document")] My, - [Description("Created Toady")] CreatedToday -} \ No newline at end of file diff --git a/src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsFilter.cs b/src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsFilter.cs new file mode 100644 index 000000000..b3eaf9318 --- /dev/null +++ b/src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsFilter.cs @@ -0,0 +1,13 @@ +namespace CleanArchitecture.Blazor.Application.Features.Documents.Queries.Specification; + +public enum DocumentListView +{ + [Description("All")] All, + [Description("My Document")] My, + [Description("Created Toady")] CreatedToday +} +public class AdvancedDocumentsFilter: PaginationFilter +{ + public DocumentListView ListView { get; set; } = DocumentListView.All; + public required UserProfile CurrentUser { get; set; } +} diff --git a/src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsSpecification.cs b/src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsSpecification.cs new file mode 100644 index 000000000..05a667259 --- /dev/null +++ b/src/Application/Features/Documents/Queries/Specification/AdvancedDocumentsSpecification.cs @@ -0,0 +1,16 @@ +namespace CleanArchitecture.Blazor.Application.Features.Documents.Queries.Specification; + +public class AdvancedDocumentsSpecification : Specification<Document> +{ + public AdvancedDocumentsSpecification(AdvancedDocumentsFilter filter) + { + Query.Where(p => + (p.CreatedBy == filter.CurrentUser.UserId && p.IsPublic == false) || + (p.IsPublic == true && p.TenantId == filter.CurrentUser.TenantId), filter.ListView == DocumentListView.All) + .Where(p => + p.CreatedBy == filter.CurrentUser.UserId && p.TenantId == filter.CurrentUser.TenantId, filter.ListView == DocumentListView.My) + .Where(p => p.Created.Value.Date == DateTime.Now.Date, filter.ListView == DocumentListView.CreatedToday) + .Where(x => x.Title.Contains(filter.Keyword) || x.Description.Contains(filter.Keyword) || x.Content.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword)); + + } +} diff --git a/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs b/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs index 7dfa7f6aa..fa66c22a4 100644 --- a/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs +++ b/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs @@ -3,20 +3,20 @@ using CleanArchitecture.Blazor.Application.Features.KeyValues.Caching; using CleanArchitecture.Blazor.Application.Features.KeyValues.DTOs; -using CleanArchitecture.Blazor.Domain.Enums; +using CleanArchitecture.Blazor.Application.Features.KeyValues.Queries.Specification; namespace CleanArchitecture.Blazor.Application.Features.KeyValues.Queries.PaginationQuery; -public class KeyValuesWithPaginationQuery : PaginationFilter, ICacheableRequest<PaginatedData<KeyValueDto>> +public class KeyValuesWithPaginationQuery : KeyValueAdvancedFilter, ICacheableRequest<PaginatedData<KeyValueDto>> { - public Picklist? Picklist { get; set; } + public string CacheKey => $"{nameof(KeyValuesWithPaginationQuery)},{this}"; public MemoryCacheEntryOptions? Options => KeyValueCacheKey.MemoryCacheEntryOptions; public override string ToString() { return $"Picklist:{Picklist},Search:{Keyword},OrderBy:{OrderBy} {SortDirection},{PageNumber},{PageSize}"; } - public KeyValuesQuerySpec Specification => new KeyValuesQuerySpec(this); + public KeyValueAdvancedSpecification Specification => new KeyValueAdvancedSpecification(this); } public class KeyValuesQueryHandler : IRequestHandler<KeyValuesWithPaginationQuery, PaginatedData<KeyValueDto>> @@ -42,12 +42,3 @@ public async Task<PaginatedData<KeyValueDto>> Handle(KeyValuesWithPaginationQuer return data; } } -public class KeyValuesQuerySpec : Specification<KeyValue> -{ - public KeyValuesQuerySpec(KeyValuesWithPaginationQuery request) - { - Query.Where(p => p.Name== request.Picklist, request.Picklist is not null) - .Where(x => x.Description.Contains(request.Keyword) || x.Text.Contains(request.Keyword) || x.Value.Contains(request.Keyword), !string.IsNullOrEmpty(request.Keyword)); - - } -} \ No newline at end of file diff --git a/src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedFilter.cs b/src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedFilter.cs new file mode 100644 index 000000000..1260b5aa3 --- /dev/null +++ b/src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedFilter.cs @@ -0,0 +1,7 @@ +using CleanArchitecture.Blazor.Domain.Enums; + +namespace CleanArchitecture.Blazor.Application.Features.KeyValues.Queries.Specification; +public class KeyValueAdvancedFilter: PaginationFilter +{ + public Picklist? Picklist { get; set; } +} diff --git a/src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedSpecification.cs b/src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedSpecification.cs new file mode 100644 index 000000000..85eaf3594 --- /dev/null +++ b/src/Application/Features/KeyValues/Queries/Specification/KeyValueAdvancedSpecification.cs @@ -0,0 +1,11 @@ +namespace CleanArchitecture.Blazor.Application.Features.KeyValues.Queries.Specification; + +public class KeyValueAdvancedSpecification : Specification<KeyValue> +{ + public KeyValueAdvancedSpecification(KeyValueAdvancedFilter filter) + { + Query.Where(p => p.Name == filter.Picklist, filter.Picklist is not null) + .Where(x => x.Description.Contains(filter.Keyword) || x.Text.Contains(filter.Keyword) || x.Value.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword)); + + } +} diff --git a/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs b/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs index ad9579c06..705ea3b20 100644 --- a/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs +++ b/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs @@ -3,21 +3,21 @@ using CleanArchitecture.Blazor.Application.Features.Loggers.Caching; using CleanArchitecture.Blazor.Application.Features.Loggers.DTOs; +using CleanArchitecture.Blazor.Application.Features.Loggers.Queries.Specification; using CleanArchitecture.Blazor.Domain.Entities.Logger; namespace CleanArchitecture.Blazor.Application.Features.Loggers.Queries.PaginationQuery; -public class LogsWithPaginationQuery : PaginationFilter, ICacheableRequest<PaginatedData<LogDto>> +public class LogsWithPaginationQuery : LoggerAdvancedFilter, ICacheableRequest<PaginatedData<LogDto>> { - public LogLevel? Level { get; set; } - public LogListView ListView { get; set; } = LogListView.All; + public string CacheKey => LogsCacheKey.GetPaginationCacheKey($"{this}"); public MemoryCacheEntryOptions? Options => LogsCacheKey.MemoryCacheEntryOptions; public override string ToString() { return $"Listview:{ListView},{Level},Search:{Keyword},OrderBy:{OrderBy} {SortDirection},{PageNumber},{PageSize}"; } - public LogsQuerySpec Specification => new LogsQuerySpec(this); + public LoggerAdvancedSpecification Specification => new LoggerAdvancedSpecification(this); } public class LogsQueryHandler : IRequestHandler<LogsWithPaginationQuery, PaginatedData<LogDto>> @@ -43,29 +43,5 @@ public async Task<PaginatedData<LogDto>> Handle(LogsWithPaginationQuery request, } } -public class LogsQuerySpec : Specification<Logger> -{ - public LogsQuerySpec(LogsWithPaginationQuery request) - { - var today = DateTime.Now.Date; - var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", - CultureInfo.CurrentCulture); - var last30days = - Convert.ToDateTime(today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - Query.Where(p => p.TimeStamp.Date == DateTime.Now.Date, request.ListView == LogListView.CreatedToday) - .Where(p => p.TimeStamp >= last30days, request.ListView == LogListView.Last30days) - .Where(p => p.Level== request.Level.ToString(), request.Level is not null) - .Where(x => x.Message.Contains(request.Keyword) || x.Exception.Contains(request.Keyword) || x.UserName.Contains(request.Keyword), !string.IsNullOrEmpty(request.Keyword)); - } -} -public enum LogListView -{ - [Description("All")] All, - [Description("Created Toady")] CreatedToday, - [Description("View of the last 30 days")] - Last30days -} \ No newline at end of file + diff --git a/src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedFilter.cs b/src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedFilter.cs new file mode 100644 index 000000000..f70fa05d9 --- /dev/null +++ b/src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedFilter.cs @@ -0,0 +1,14 @@ +namespace CleanArchitecture.Blazor.Application.Features.Loggers.Queries.Specification; +public enum LogListView +{ + [Description("All")] All, + [Description("Created Toady")] CreatedToday, + [Description("View of the last 30 days")] + Last30days +} + +public class LoggerAdvancedFilter : PaginationFilter +{ + public LogLevel? Level { get; set; } + public LogListView ListView { get; set; } = LogListView.All; +} diff --git a/src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedSpecification.cs b/src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedSpecification.cs new file mode 100644 index 000000000..4b520a769 --- /dev/null +++ b/src/Application/Features/Loggers/Queries/Specification/LoggerAdvancedSpecification.cs @@ -0,0 +1,22 @@ +using CleanArchitecture.Blazor.Domain.Entities.Logger; + +namespace CleanArchitecture.Blazor.Application.Features.Loggers.Queries.Specification; + +public class LoggerAdvancedSpecification : Specification<Logger> +{ + public LoggerAdvancedSpecification(LoggerAdvancedFilter filter) + { + var today = DateTime.Now.Date; + var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", + CultureInfo.CurrentCulture); + var last30days = + Convert.ToDateTime(today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + Query.Where(p => p.TimeStamp.Date == DateTime.Now.Date, filter.ListView == LogListView.CreatedToday) + .Where(p => p.TimeStamp >= last30days, filter.ListView == LogListView.Last30days) + .Where(p => p.Level == filter.Level.ToString(), filter.Level is not null) + .Where(x => x.Message.Contains(filter.Keyword) || x.Exception.Contains(filter.Keyword) || x.UserName.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword)); + } +} \ No newline at end of file diff --git a/src/Application/Features/Products/Queries/Export/ExportProductsQuery.cs b/src/Application/Features/Products/Queries/Export/ExportProductsQuery.cs index a825f6fd1..e0fc457a9 100644 --- a/src/Application/Features/Products/Queries/Export/ExportProductsQuery.cs +++ b/src/Application/Features/Products/Queries/Export/ExportProductsQuery.cs @@ -9,22 +9,10 @@ namespace CleanArchitecture.Blazor.Application.Features.Products.Queries.Export; -public class ExportProductsQuery : IRequest<Result<byte[]>> +public class ExportProductsQuery : ProductAdvancedFilter, IRequest<Result<byte[]>> { - public string? Name { get; set; } - public string? Brand { get; set; } - public string? Unit { get; set; } - public decimal? MaxPrice { get; set; } - public decimal? MinPrice { get; set; } - public string? Keyword { get; set; } - - public string? OrderBy { get; set; } - public string? SortDirection { get; set; } - public ProductListView ListView { get; set; } = ProductListView.All; //<-- When the user selects a different ListView, - public UserProfile? CurrentUser { get; set; } // <-- This CurrentUser property gets its value from the information of - public ExportType ExportType { get; set; } - public ExportProductSpecification Specification => new ExportProductSpecification(this); + public ProductAdvancedSpecification Specification => new ProductAdvancedSpecification(this); } public class ExportProductsQueryHandler : diff --git a/src/Application/Features/Products/Queries/Pagination/ProductsPaginationQuery.cs b/src/Application/Features/Products/Queries/Pagination/ProductsPaginationQuery.cs index 3ccebe65e..75916b524 100644 --- a/src/Application/Features/Products/Queries/Pagination/ProductsPaginationQuery.cs +++ b/src/Application/Features/Products/Queries/Pagination/ProductsPaginationQuery.cs @@ -8,16 +8,9 @@ namespace CleanArchitecture.Blazor.Application.Features.Products.Queries.Pagination; -public class ProductsWithPaginationQuery : PaginationFilter, ICacheableRequest<PaginatedData<ProductDto>> +public class ProductsWithPaginationQuery : ProductAdvancedFilter, ICacheableRequest<PaginatedData<ProductDto>> { - public string? Name { get; set; } - public string? Brand { get; set; } - public string? Unit { get; set; } - public decimal? MaxPrice { get; set; } - public decimal? MinPrice { get; set; } - public string? Keyword { get; set; } - public ProductListView ListView { get; set; } = ProductListView.All; //<-- When the user selects a different ListView, - public UserProfile? CurrentUser { get; set; } // <-- This CurrentUser property gets its value from the information of + public string CacheKey => ProductCacheKey.GetPaginationCacheKey($"{this}"); @@ -30,7 +23,7 @@ public override string ToString() $"CurrentUser:{CurrentUser?.UserId},ListView:{ListView},Search:{Keyword},Name:{Name},Brand:{Brand},Unit:{Unit},MinPrice:{MinPrice},MaxPrice:{MaxPrice},SortDirection:{SortDirection},OrderBy:{OrderBy},{ PageNumber},{PageSize}"; } - public SearchProductSpecification Specification => new SearchProductSpecification(this); + public ProductAdvancedSpecification Specification => new ProductAdvancedSpecification(this); } public class ProductsWithPaginationQueryHandler : diff --git a/src/Application/Features/Products/Queries/Specification/ExportProductSpecification.cs b/src/Application/Features/Products/Queries/Specification/ExportProductSpecification.cs deleted file mode 100644 index 0bb25af6a..000000000 --- a/src/Application/Features/Products/Queries/Specification/ExportProductSpecification.cs +++ /dev/null @@ -1,29 +0,0 @@ -using CleanArchitecture.Blazor.Application.Features.Products.Queries.Export; - -namespace CleanArchitecture.Blazor.Application.Features.Products.Queries.Specification; - -public class ExportProductSpecification : Specification<Product> -{ - public ExportProductSpecification(ExportProductsQuery query) - { - var today = DateTime.Now.Date; - var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", - CultureInfo.CurrentCulture); - var last30day = Convert.ToDateTime( - today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - Query.Where(q => q.Name != null) - .Where(x => x.Name!.Contains(query.Keyword) || x.Description!.Contains(query.Keyword) || - x.Brand!.Contains(query.Keyword), !string.IsNullOrEmpty(query.Keyword)) - .Where(x => x.Name!.Contains(query.Name), !string.IsNullOrEmpty(query.Name)) - .Where(x => x.Unit == query.Unit, !string.IsNullOrEmpty(query.Unit)) - .Where(x => x.Brand == query.Brand, !string.IsNullOrEmpty(query.Brand)) - .Where(x => x.Price <= query.MaxPrice, !string.IsNullOrEmpty(query.Brand)) - .Where(x => x.Price >= query.MinPrice, query.MinPrice is not null) - .Where(product => product.CreatedBy == query.CurrentUser.UserId, query.ListView == ProductListView.My) - .Where(product => product.Created >= start && product.Created <= end, query.ListView == ProductListView.CreatedToday) - .Where(product => product.Created >= last30day, query.ListView == ProductListView.Created30Days); - } -} diff --git a/src/Application/Features/Products/Queries/Specification/ProductAdvancedFilter.cs b/src/Application/Features/Products/Queries/Specification/ProductAdvancedFilter.cs new file mode 100644 index 000000000..5e8e51b82 --- /dev/null +++ b/src/Application/Features/Products/Queries/Specification/ProductAdvancedFilter.cs @@ -0,0 +1,12 @@ +namespace CleanArchitecture.Blazor.Application.Features.Products.Queries.Specification; +public class ProductAdvancedFilter : PaginationFilter +{ + public string? Name { get; set; } + public string? Brand { get; set; } + public string? Unit { get; set; } + public decimal? MaxPrice { get; set; } + public decimal? MinPrice { get; set; } + public string? Keyword { get; set; } + public ProductListView ListView { get; set; } = ProductListView.All; //<-- When the user selects a different ListView, + public UserProfile? CurrentUser { get; set; } // <-- This CurrentUser property gets its value from the information of +} diff --git a/src/Application/Features/Products/Queries/Specification/ProductAdvancedSpecification.cs b/src/Application/Features/Products/Queries/Specification/ProductAdvancedSpecification.cs new file mode 100644 index 000000000..a303590ba --- /dev/null +++ b/src/Application/Features/Products/Queries/Specification/ProductAdvancedSpecification.cs @@ -0,0 +1,30 @@ + +namespace CleanArchitecture.Blazor.Application.Features.Products.Queries.Specification; + +public class ProductAdvancedSpecification : Specification<Product> +{ + public ProductAdvancedSpecification(ProductAdvancedFilter filter) + { + var today = DateTime.Now.Date; + var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", + CultureInfo.CurrentCulture); + var last30day = Convert.ToDateTime( + today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", + CultureInfo.CurrentCulture); + Query.Where(x => x.Name != null) + .Where(x => x.Name!.Contains(filter.Keyword) || x.Description!.Contains(filter.Keyword) || + x.Brand!.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword)) + .Where(x => x.Name!.Contains(filter.Name), !string.IsNullOrEmpty(filter.Name)) + .Where(x => x.Unit == filter.Unit, !string.IsNullOrEmpty(filter.Unit)) + .Where(x => x.Brand == filter.Brand, !string.IsNullOrEmpty(filter.Brand)) + .Where(x => x.Price <= filter.MaxPrice, !string.IsNullOrEmpty(filter.Brand)) + .Where(x => x.Price >= filter.MinPrice, filter.MinPrice is not null) + .Where(x => x.CreatedBy == filter.CurrentUser.UserId, filter.ListView == ProductListView.My) + .Where(x => x.Created >= start && x.Created <= end, filter.ListView == ProductListView.CreatedToday) + .Where(x => x.Created >= last30day, filter.ListView == ProductListView.Created30Days); + + + } +} diff --git a/src/Application/Features/Products/Queries/Specification/SearchProductSpecification.cs b/src/Application/Features/Products/Queries/Specification/SearchProductSpecification.cs deleted file mode 100644 index 64136e135..000000000 --- a/src/Application/Features/Products/Queries/Specification/SearchProductSpecification.cs +++ /dev/null @@ -1,31 +0,0 @@ -using CleanArchitecture.Blazor.Application.Features.Products.Queries.Pagination; - -namespace CleanArchitecture.Blazor.Application.Features.Products.Queries.Specification; - -public class SearchProductSpecification : Specification<Product> -{ - public SearchProductSpecification(ProductsWithPaginationQuery query) - { - var today = DateTime.Now.Date; - var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", - CultureInfo.CurrentCulture); - var last30day = Convert.ToDateTime( - today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", - CultureInfo.CurrentCulture); - Query.Where(q => q.Name != null) - .Where(x => x.Name!.Contains(query.Keyword) || x.Description!.Contains(query.Keyword) || - x.Brand!.Contains(query.Keyword), !string.IsNullOrEmpty(query.Keyword)) - .Where(x => x.Name!.Contains(query.Name), !string.IsNullOrEmpty(query.Name)) - .Where(x => x.Unit == query.Unit, !string.IsNullOrEmpty(query.Unit)) - .Where(x => x.Brand == query.Brand, !string.IsNullOrEmpty(query.Brand)) - .Where(x => x.Price <= query.MaxPrice, !string.IsNullOrEmpty(query.Brand)) - .Where(x => x.Price >= query.MinPrice, query.MinPrice is not null) - .Where(product => product.CreatedBy == query.CurrentUser.UserId, query.ListView == ProductListView.My) - .Where(product => product.Created >= start && product.Created <= end, query.ListView == ProductListView.CreatedToday) - .Where(product => product.Created >= last30day, query.ListView == ProductListView.Created30Days); - - - } -} diff --git a/src/Blazor.Server.UI/Pages/Customers/Customers.razor b/src/Blazor.Server.UI/Pages/Customers/Customers.razor index f4e5134e7..c929a51fd 100644 --- a/src/Blazor.Server.UI/Pages/Customers/Customers.razor +++ b/src/Blazor.Server.UI/Pages/Customers/Customers.razor @@ -7,6 +7,7 @@ @using CleanArchitecture.Blazor.Application.Features.Customers.Commands.Import @using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Export @using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Pagination +@using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Specification @using CleanArchitecture.Blazor.Application.Features.Customers.Commands.AddEdit @inherits FluxorComponent diff --git a/src/Blazor.Server.UI/Pages/Documents/Documents.razor b/src/Blazor.Server.UI/Pages/Documents/Documents.razor index a6ffb1d42..caec33d5c 100644 --- a/src/Blazor.Server.UI/Pages/Documents/Documents.razor +++ b/src/Blazor.Server.UI/Pages/Documents/Documents.razor @@ -11,6 +11,7 @@ @using CleanArchitecture.Blazor.Application.Features.Documents.Commands.AddEdit @using CleanArchitecture.Blazor.Application.Features.Documents.Queries.GetFileStream @using CleanArchitecture.Blazor.Application.Features.Documents.Queries.PaginationQuery +@using CleanArchitecture.Blazor.Application.Features.Documents.Queries.Specification; @using CleanArchitecture.Blazor.Application.Features.Fluxor; @using CleanArchitecture.Blazor.Infrastructure.Hubs diff --git a/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor b/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor index ea7f32842..bff3f93c7 100644 --- a/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor +++ b/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor @@ -2,6 +2,7 @@ @using CleanArchitecture.Blazor.Application.Features.AuditTrails.DTOs @using CleanArchitecture.Blazor.Application.Features.AuditTrails.Queries.PaginationQuery @using CleanArchitecture.Blazor.Application.Features.AuditTrails.Caching +@using CleanArchitecture.Blazor.Application.Features.AuditTrails.Queries.Specification; @inherits FluxorComponent @attribute [Authorize(Policy = Permissions.AuditTrails.View)] diff --git a/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor b/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor index f45a11366..4d723bebf 100644 --- a/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor +++ b/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor @@ -5,6 +5,7 @@ @using CleanArchitecture.Blazor.Application.Constants.User @using CleanArchitecture.Blazor.Application.Features.Loggers.Commands.Clear @using CleanArchitecture.Blazor.Application.Features.Loggers.Queries.PaginationQuery +@using CleanArchitecture.Blazor.Application.Features.Loggers.Queries.Specification; @using FluentEmail.Core @using Severity = MudBlazor.Severity