Generator Changes at 9/27/2025 8:46:36 AM

This commit is contained in:
generator
2025-09-27 08:46:36 +03:30
parent fd82e3edcf
commit fd8614f72e
261 changed files with 6333 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
name: Push nuget and docker image Actions Workflow
on:
push:
branches:
- stage
jobs:
Deploy:
runs-on: windows
steps:
- name: Checkout
uses: https://git.afrino.co/actions/checkout@v3
- name: Setup dotnet
uses: https://git.afrino.co/actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- name: Remove Package Source
run: dotnet nuget remove source MegaBizdEx
continue-on-error: true
- name: Add Package Source
run: dotnet nuget add source --name MegaBizdEx --username systemuser --password BHMkDaU3uXP6euR http://88.198.47.16:7000/api/packages/MegaBizdEx/nuget/index.json --store-password-in-clear-text
- name: Install dependencies
run: dotnet restore ".\src\CMSMicroservice.Protobuf\CMSMicroservice.Protobuf.csproj"
- name: Build
run: dotnet build ".\src\CMSMicroservice.Protobuf\CMSMicroservice.Protobuf.csproj" --configuration Release --no-restore
- name: Test
run: dotnet test ".\src\CMSMicroservice.Protobuf\CMSMicroservice.Protobuf.csproj" --no-restore --verbosity normal
- name: Pack
run: dotnet pack ".\src\CMSMicroservice.Protobuf\CMSMicroservice.Protobuf.csproj" --no-build --configuration Release
- name: Push To Gitea Packages
run: dotnet nuget push **/*.nupkg --source http://88.198.47.16:7000/api/packages/megabizdex/nuget/index.json --api-key 49c6424b31442f3aaad8d5ce73401143264f8471 --skip-duplicate
- name: Build Docker Image
run: docker build ./src -t cmsapi:latest -f src/CMSMicroservice.WebApi/Dockerfile
- name: Log Out From Registry
run: docker logout git.afrino.co
- name: Log In To Registry
run: docker login git.afrino.co -u systemuser -p sZSA7PTiv3pUSQZ
- name: Tag Docker Image
run: docker image tag cmsapi:latest git.afrino.co/megabizdex/cmsapi:latest
- name: Push Docker Image
run: docker image push git.afrino.co/megabizdex/cmsapi:latest
- name: Deploy (Up) Services
run: docker-compose up -d

26
src/.dockerignore Normal file
View File

@@ -0,0 +1,26 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

45
src/CMS.sln Normal file
View File

@@ -0,0 +1,45 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{43A1942F-306D-4937-8907-B9888A5449CF}") = "CMSMicroservice.Domain", "CMSMicroservice.Domain\CMSMicroservice.Domain.csproj", "{426E097F-8C77-44B2-BF9D-4280B295B366}"
EndProject
Project("{43A1942F-306D-4937-8907-B9888A5449CF}") = "CMSMicroservice.Application", "CMSMicroservice.Application\CMSMicroservice.Application.csproj", "{5A05B9B0-D6BB-46EB-BE8C-EEAB6F0EAC55}"
EndProject
Project("{43A1942F-306D-4937-8907-B9888A5449CF}") = "CMSMicroservice.Infrastructure", "CMSMicroservice.Infrastructure\CMSMicroservice.Infrastructure.csproj", "{A583B3B2-EAFB-45B7-BAA3-C17662714713}"
EndProject
Project("{43A1942F-306D-4937-8907-B9888A5449CF}") = "CMSMicroservice.WebApi", "CMSMicroservice.WebApi\CMSMicroservice.WebApi.csproj", "{0A56701B-A4EA-441F-A5A6-7EDD89572F9D}"
EndProject
Project("{43A1942F-306D-4937-8907-B9888A5449CF}") = "CMSMicroservice.Protobuf", "CMSMicroservice.Protobuf\CMSMicroservice.Protobuf.csproj", "{AC4961A7-941F-4E42-9208-B48CB352361C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{426E097F-8C77-44B2-BF9D-4280B295B366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{426E097F-8C77-44B2-BF9D-4280B295B366}.Debug|Any CPU.Build.0 = Debug|Any CPU
{426E097F-8C77-44B2-BF9D-4280B295B366}.Release|Any CPU.ActiveCfg = Release|Any CPU
{426E097F-8C77-44B2-BF9D-4280B295B366}.Release|Any CPU.Build.0 = Release|Any CPU
{5A05B9B0-D6BB-46EB-BE8C-EEAB6F0EAC55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A05B9B0-D6BB-46EB-BE8C-EEAB6F0EAC55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A05B9B0-D6BB-46EB-BE8C-EEAB6F0EAC55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A05B9B0-D6BB-46EB-BE8C-EEAB6F0EAC55}.Release|Any CPU.Build.0 = Release|Any CPU
{A583B3B2-EAFB-45B7-BAA3-C17662714713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A583B3B2-EAFB-45B7-BAA3-C17662714713}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A583B3B2-EAFB-45B7-BAA3-C17662714713}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A583B3B2-EAFB-45B7-BAA3-C17662714713}.Release|Any CPU.Build.0 = Release|Any CPU
{0A56701B-A4EA-441F-A5A6-7EDD89572F9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A56701B-A4EA-441F-A5A6-7EDD89572F9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A56701B-A4EA-441F-A5A6-7EDD89572F9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A56701B-A4EA-441F-A5A6-7EDD89572F9D}.Release|Any CPU.Build.0 = Release|Any CPU
{AC4961A7-941F-4E42-9208-B48CB352361C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC4961A7-941F-4E42-9208-B48CB352361C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC4961A7-941F-4E42-9208-B48CB352361C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC4961A7-941F-4E42-9208-B48CB352361C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.2.2" />
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CMSMicroservice.Domain\CMSMicroservice.Domain.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using MediatR.Pipeline;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.Common.Behaviours;
public class LoggingBehaviour<TRequest> : IRequestPreProcessor<TRequest> where TRequest : notnull
{
private readonly ILogger _logger;
private readonly ICurrentUserService _currentUserService;
public LoggingBehaviour(ILogger<TRequest> logger, ICurrentUserService currentUserService)
{
_logger = logger;
_currentUserService = currentUserService;
}
public async Task Process(TRequest request, CancellationToken cancellationToken)
{
var requestName = typeof(TRequest).Name;
var userId = _currentUserService.UserId ?? string.Empty;
_logger.LogInformation("Request: {Name} {@UserId} {@Request}",
requestName, userId, request);
}
}

View File

@@ -0,0 +1,43 @@
using System.Diagnostics;
using MediatR;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.Common.Behaviours;
public class PerformanceBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly Stopwatch _timer;
private readonly ILogger<TRequest> _logger;
private readonly ICurrentUserService _currentUserService;
public PerformanceBehaviour(ILogger<TRequest> logger, ICurrentUserService currentUserService)
{
_timer = new Stopwatch();
_logger = logger;
_currentUserService = currentUserService;
}
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
_timer.Start();
var response = await next();
_timer.Stop();
var elapsedMilliseconds = _timer.ElapsedMilliseconds;
if (elapsedMilliseconds > 500)
{
var requestName = typeof(TRequest).Name;
var userId = _currentUserService.UserId ?? string.Empty;
_logger.LogWarning("Long Running Request: {Name} ({ElapsedMilliseconds} milliseconds) {@UserId} {@Request}",
requestName, elapsedMilliseconds, userId, request);
}
return response;
}
}

View File

@@ -0,0 +1,31 @@
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.Common.Behaviours;
public class UnhandledExceptionBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly ILogger<TRequest> _logger;
public UnhandledExceptionBehaviour(ILogger<TRequest> logger)
{
_logger = logger;
}
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
try
{
return await next();
}
catch (Exception ex)
{
var requestName = typeof(TRequest).Name;
_logger.LogError(ex, "Request: Unhandled Exception for Request {Name} {@Request}", requestName, request);
throw;
}
}
}

View File

@@ -0,0 +1,37 @@
using ValidationException = CMSMicroservice.Application.Common.Exceptions.ValidationException;
namespace CMSMicroservice.Application.Common.Behaviours;
public class ValidationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly IEnumerable<IValidator<TRequest>> _validators;
public ValidationBehaviour(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
if (_validators.Any())
{
var context = new ValidationContext<TRequest>(request);
var validationResults = await Task.WhenAll(
_validators.Select(v =>
v.ValidateAsync(context, cancellationToken)));
var failures = validationResults
.Where(r => r.Errors.Any())
.SelectMany(r => r.Errors)
.ToList();
if (failures.Any())
throw new ValidationException(failures);
}
return await next();
}
}

View File

@@ -0,0 +1,29 @@
namespace CMSMicroservice.Application.Common.Exceptions;
public class DuplicateException : Exception
{
public DuplicateException()
: base()
{
}
public DuplicateException(string message)
: base(message)
{
}
public DuplicateException(string message, Exception innerException)
: base(message, innerException)
{
}
public DuplicateException(string name, object key)
: base($"Entity \"{name}\" ({key}) already exists.")
{
}
public DuplicateException(string name, string field, object? key)
: base($"Entity \"{name}\" field \"{field}\" ({key}) already exists.")
{
}
}

View File

@@ -0,0 +1,8 @@
namespace CMSMicroservice.Application.Common.Exceptions;
public class ForbiddenAccessException : Exception
{
public ForbiddenAccessException() : base()
{
}
}

View File

@@ -0,0 +1,24 @@
namespace CMSMicroservice.Application.Common.Exceptions;
public class NotFoundException : Exception
{
public NotFoundException()
: base()
{
}
public NotFoundException(string message)
: base(message)
{
}
public NotFoundException(string message, Exception innerException)
: base(message, innerException)
{
}
public NotFoundException(string name, object key)
: base($"Entity \"{name}\" ({key}) was not found.")
{
}
}

View File

@@ -0,0 +1,22 @@
using FluentValidation.Results;
namespace CMSMicroservice.Application.Common.Exceptions;
public class ValidationException : Exception
{
public ValidationException()
: base("One or more validation failures have occurred.")
{
Errors = new Dictionary<string, string[]>();
}
public ValidationException(IEnumerable<ValidationFailure> failures)
: this()
{
Errors = failures
.GroupBy(e => e.PropertyName, e => e.ErrorMessage)
.ToDictionary(failureGroup => failureGroup.Key, failureGroup => failureGroup.ToArray());
}
public IDictionary<string, string[]> Errors { get; }
}

View File

@@ -0,0 +1,30 @@
namespace CMSMicroservice.Application.Common.Extensions;
public static class MetaDataExtensions
{
public static async Task<MetaData> GetMetaData<T>(this IQueryable<T> source, PaginationState? paginationState,
CancellationToken cancellationToken)
{
if (paginationState is null)
return new MetaData
{
TotalCount = await source.CountAsync(cancellationToken)
};
var pageSize = paginationState.PageSize > 0 ? paginationState.PageSize : PaginationDefaults.PageSize;
var pageNumber = paginationState.PageNumber > 0 ? paginationState.PageNumber : PaginationDefaults.PageNumber;
var totalCount = await source.CountAsync(cancellationToken);
var totalPageCount = (int)Math.Ceiling(totalCount / (double)pageSize);
var metaData = new MetaData
{
CurrentPage = pageNumber,
HasNext = pageNumber < totalPageCount,
HasPrevious = pageNumber > 1,
PageSize = pageSize,
TotalCount = totalCount,
TotalPage = totalPageCount
};
return metaData;
}
}

View File

@@ -0,0 +1,25 @@
namespace CMSMicroservice.Application.Common.Extensions;
public static class PaginationStateExtensions
{
public static IQueryable<TSource> PaginatedListAsync<TSource>(this IQueryable<TSource> source,
PaginationState? paginationState)
{
if (paginationState is null)
return source;
var pageSize = paginationState.PageSize > 0 ? paginationState.PageSize : PaginationDefaults.PageSize;
var pageNumber = paginationState.PageNumber > 0 ? paginationState.PageNumber : PaginationDefaults.PageNumber;
var paginationSkip = pageSize * (pageNumber - 1);
return source.Skip(paginationSkip).Take(pageSize);
}
}
public static class PaginationDefaults
{
public const int PageSize = 10;
public const int PageNumber = 1;
public const int Skip = 0;
public const int Take = PageSize;
}

View File

@@ -0,0 +1,23 @@
using System.Linq.Dynamic.Core;
using CMSMicroservice.Domain.Common;
namespace CMSMicroservice.Application.Common.Extensions;
public static class SortByExtensions
{
public static IQueryable<TSource> ApplyOrder<TSource>(this IQueryable<TSource> source,
string? sortBy) where TSource : BaseAuditableEntity
{
// default sort approach
if (sortBy is null or "")
{
source = source.OrderByDescending(p => p.Created);
return source;
}
// sort using dynamic linq
source = source.OrderBy(sortBy);
return source;
}
}

View File

@@ -0,0 +1,12 @@
namespace CMSMicroservice.Application.Common.Interfaces;
public interface IApplicationDbContext
{
DbSet<User> Users { get; }
DbSet<UserAddress> UserAddresss { get; }
DbSet<Package> Packages { get; }
DbSet<UserOrder> UserOrders { get; }
DbSet<Role> Roles { get; }
DbSet<UserRole> UserRoles { get; }
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}

View File

@@ -0,0 +1,6 @@
namespace CMSMicroservice.Application.Common.Interfaces;
public interface ICurrentUserService
{
string? UserId { get; }
}

View File

@@ -0,0 +1,10 @@
namespace CMSMicroservice.Application.Common.Mappings;
public class PackageProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
//config.NewConfig<Source,Destination>()
// .Map(dest => dest.FullName, src => $"{src.Firstname} {src.Lastname}");
}
}

View File

@@ -0,0 +1,10 @@
namespace CMSMicroservice.Application.Common.Mappings;
public class RoleProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
//config.NewConfig<Source,Destination>()
// .Map(dest => dest.FullName, src => $"{src.Firstname} {src.Lastname}");
}
}

View File

@@ -0,0 +1,10 @@
namespace CMSMicroservice.Application.Common.Mappings;
public class UserAddressProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
//config.NewConfig<Source,Destination>()
// .Map(dest => dest.FullName, src => $"{src.Firstname} {src.Lastname}");
}
}

View File

@@ -0,0 +1,10 @@
namespace CMSMicroservice.Application.Common.Mappings;
public class UserOrderProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
//config.NewConfig<Source,Destination>()
// .Map(dest => dest.FullName, src => $"{src.Firstname} {src.Lastname}");
}
}

View File

@@ -0,0 +1,10 @@
namespace CMSMicroservice.Application.Common.Mappings;
public class UserProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
//config.NewConfig<Source,Destination>()
// .Map(dest => dest.FullName, src => $"{src.Firstname} {src.Lastname}");
}
}

View File

@@ -0,0 +1,10 @@
namespace CMSMicroservice.Application.Common.Mappings;
public class UserRoleProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
//config.NewConfig<Source,Destination>()
// .Map(dest => dest.FullName, src => $"{src.Firstname} {src.Lastname}");
}
}

View File

@@ -0,0 +1,22 @@
namespace CMSMicroservice.Application.Common.Models;
public class MetaData
{
//صفحه جاری
public long CurrentPage { get; set; }
//تعداد کل صفحات
public long TotalPage { get; set; }
//تعداد در هر صفحه
public long PageSize { get; set; }
//تعداد کل آیتم‌ها
public long TotalCount { get; set; }
//قبلی دارد؟
public bool HasPrevious { get; set; }
//بعدی دارد؟
public bool HasNext { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace CMSMicroservice.Application.Common.Models;
public class PaginationState
{
//شماره صفحه
public int PageNumber { get; set; }
//اندازه صفحه
public int PageSize { get; set; }
}

View File

@@ -0,0 +1,31 @@
using System.Reflection;
using CMSMicroservice.Application.Common.Behaviours;
using MapsterMapper;
namespace Microsoft.Extensions.DependencyInjection;
public static class ConfigureServices
{
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
services.AddMapping();
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddMediatR(AppDomain.CurrentDomain.GetAssemblies());
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(UnhandledExceptionBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(PerformanceBehaviour<,>));
return services;
}
private static IServiceCollection AddMapping(this IServiceCollection services)
{
var typeAdapterConfig = TypeAdapterConfig.GlobalSettings;
// scans the assembly and gets the IRegister, adding the registration to the TypeAdapterConfig
typeAdapterConfig.Scan(Assembly.GetExecutingAssembly());
// register the mapper as Singleton service for my application
var mapperConfig = new Mapper(typeAdapterConfig);
services.AddSingleton<IMapper>(mapperConfig);
return services;
}
}

View File

@@ -0,0 +1,15 @@
global using MediatR;
global using FluentValidation;
global using Mapster;
global using CMSMicroservice.Domain.Entities;
global using CMSMicroservice.Application.Common.Interfaces;
global using System.Threading;
global using System.Threading.Tasks;
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using Microsoft.EntityFrameworkCore;
global using CMSMicroservice.Application.Common.Exceptions;
global using CMSMicroservice.Application.Common.Extensions;
global using CMSMicroservice.Application.Common.Models;

View File

@@ -0,0 +1,13 @@
namespace CMSMicroservice.Application.PackageCQ.Commands.CreateNewPackage;
public record CreateNewPackageCommand : IRequest<CreateNewPackageResponseDto>
{
//عنوان
public string Title { get; init; }
//توضیحات
public string Description { get; init; }
//آدرس تصویر
public string ImagePath { get; init; }
//قیمت
public long Price { get; init; }
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.PackageCQ.Commands.CreateNewPackage;
public class CreateNewPackageCommandHandler : IRequestHandler<CreateNewPackageCommand, CreateNewPackageResponseDto>
{
private readonly IApplicationDbContext _context;
public CreateNewPackageCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<CreateNewPackageResponseDto> Handle(CreateNewPackageCommand request,
CancellationToken cancellationToken)
{
var entity = request.Adapt<Package>();
await _context.Packages.AddAsync(entity, cancellationToken);
entity.AddDomainEvent(new CreateNewPackageEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return entity.Adapt<CreateNewPackageResponseDto>();
}
}

View File

@@ -0,0 +1,22 @@
namespace CMSMicroservice.Application.PackageCQ.Commands.CreateNewPackage;
public class CreateNewPackageCommandValidator : AbstractValidator<CreateNewPackageCommand>
{
public CreateNewPackageCommandValidator()
{
RuleFor(model => model.Title)
.NotEmpty();
RuleFor(model => model.Description)
.NotEmpty();
RuleFor(model => model.ImagePath)
.NotEmpty();
RuleFor(model => model.Price)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<CreateNewPackageCommand>.CreateWithOptions((CreateNewPackageCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.PackageCQ.Commands.CreateNewPackage;
public class CreateNewPackageResponseDto
{
//شناسه
public long Id { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.PackageCQ.Commands.DeletePackage;
public record DeletePackageCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.PackageCQ.Commands.DeletePackage;
public class DeletePackageCommandHandler : IRequestHandler<DeletePackageCommand, Unit>
{
private readonly IApplicationDbContext _context;
public DeletePackageCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(DeletePackageCommand request, CancellationToken cancellationToken)
{
var entity = await _context.Packages
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(Package), request.Id);
entity.IsDeleted = true;
_context.Packages.Update(entity);
entity.AddDomainEvent(new DeletePackageEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.PackageCQ.Commands.DeletePackage;
public class DeletePackageCommandValidator : AbstractValidator<DeletePackageCommand>
{
public DeletePackageCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeletePackageCommand>.CreateWithOptions((DeletePackageCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,15 @@
namespace CMSMicroservice.Application.PackageCQ.Commands.UpdatePackage;
public record UpdatePackageCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
//عنوان
public string Title { get; init; }
//توضیحات
public string Description { get; init; }
//آدرس تصویر
public string ImagePath { get; init; }
//قیمت
public long Price { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.PackageCQ.Commands.UpdatePackage;
public class UpdatePackageCommandHandler : IRequestHandler<UpdatePackageCommand, Unit>
{
private readonly IApplicationDbContext _context;
public UpdatePackageCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(UpdatePackageCommand request, CancellationToken cancellationToken)
{
var entity = await _context.Packages
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(Package), request.Id);
request.Adapt(entity);
_context.Packages.Update(entity);
entity.AddDomainEvent(new UpdatePackageEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,24 @@
namespace CMSMicroservice.Application.PackageCQ.Commands.UpdatePackage;
public class UpdatePackageCommandValidator : AbstractValidator<UpdatePackageCommand>
{
public UpdatePackageCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
RuleFor(model => model.Title)
.NotEmpty();
RuleFor(model => model.Description)
.NotEmpty();
RuleFor(model => model.ImagePath)
.NotEmpty();
RuleFor(model => model.Price)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<UpdatePackageCommand>.CreateWithOptions((UpdatePackageCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.PackageCQ.EventHandlers;
public class CreateNewPackageEventHandler : INotificationHandler<CreateNewPackageEvent>
{
private readonly ILogger<CreateNewPackageEventHandler> _logger;
public CreateNewPackageEventHandler(ILogger<CreateNewPackageEventHandler> logger)
{
_logger = logger;
}
public Task Handle(CreateNewPackageEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.PackageCQ.EventHandlers;
public class DeletePackageEventHandler : INotificationHandler<DeletePackageEvent>
{
private readonly ILogger<DeletePackageEventHandler> _logger;
public DeletePackageEventHandler(ILogger<DeletePackageEventHandler> logger)
{
_logger = logger;
}
public Task Handle(DeletePackageEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.PackageCQ.EventHandlers;
public class UpdatePackageEventHandler : INotificationHandler<UpdatePackageEvent>
{
private readonly ILogger<UpdatePackageEventHandler> _logger;
public UpdatePackageEventHandler(ILogger<UpdatePackageEventHandler> logger)
{
_logger = logger;
}
public Task Handle(UpdatePackageEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,23 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetAllPackageByFilter;
public record GetAllPackageByFilterQuery : IRequest<GetAllPackageByFilterResponseDto>
{
//موقعیت صفحه بندی
public PaginationState? PaginationState { get; init; }
//مرتب سازی بر اساس
public string? SortBy { get; init; }
//فیلتر
public GetAllPackageByFilterFilter? Filter { get; init; }
}public class GetAllPackageByFilterFilter
{
//شناسه
public long? Id { get; set; }
//عنوان
public string? Title { get; set; }
//توضیحات
public string? Description { get; set; }
//آدرس تصویر
public string? ImagePath { get; set; }
//قیمت
public long? Price { get; set; }
}

View File

@@ -0,0 +1,34 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetAllPackageByFilter;
public class GetAllPackageByFilterQueryHandler : IRequestHandler<GetAllPackageByFilterQuery, GetAllPackageByFilterResponseDto>
{
private readonly IApplicationDbContext _context;
public GetAllPackageByFilterQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetAllPackageByFilterResponseDto> Handle(GetAllPackageByFilterQuery request, CancellationToken cancellationToken)
{
var query = _context.Packages
.ApplyOrder(sortBy: request.SortBy)
.AsNoTracking()
.AsQueryable();
if (request.Filter is not null)
{
query = query
.Where(x => request.Filter.Id == null || x.Id == request.Filter.Id)
.Where(x => request.Filter.Title == null || x.Title.Contains(request.Filter.Title))
.Where(x => request.Filter.Description == null || x.Description.Contains(request.Filter.Description))
.Where(x => request.Filter.ImagePath == null || x.ImagePath.Contains(request.Filter.ImagePath))
.Where(x => request.Filter.Price == null || x.Price == request.Filter.Price)
;
}
return new GetAllPackageByFilterResponseDto
{
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
.ProjectToType<GetAllPackageByFilterResponseModel>().ToListAsync(cancellationToken)
};
}
}

View File

@@ -0,0 +1,14 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetAllPackageByFilter;
public class GetAllPackageByFilterQueryValidator : AbstractValidator<GetAllPackageByFilterQuery>
{
public GetAllPackageByFilterQueryValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllPackageByFilterQuery>.CreateWithOptions((GetAllPackageByFilterQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,21 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetAllPackageByFilter;
public class GetAllPackageByFilterResponseDto
{
//متادیتا
public MetaData MetaData { get; set; }
//مدل خروجی
public List<GetAllPackageByFilterResponseModel>? Models { get; set; }
}public class GetAllPackageByFilterResponseModel
{
//شناسه
public long Id { get; set; }
//عنوان
public string Title { get; set; }
//توضیحات
public string Description { get; set; }
//آدرس تصویر
public string ImagePath { get; set; }
//قیمت
public long Price { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetPackage;
public record GetPackageQuery : IRequest<GetPackageResponseDto>
{
//شناسه
public long Id { get; init; }
}

View File

@@ -0,0 +1,22 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetPackage;
public class GetPackageQueryHandler : IRequestHandler<GetPackageQuery, GetPackageResponseDto>
{
private readonly IApplicationDbContext _context;
public GetPackageQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetPackageResponseDto> Handle(GetPackageQuery request,
CancellationToken cancellationToken)
{
var response = await _context.Packages
.AsNoTracking()
.Where(x => x.Id == request.Id)
.ProjectToType<GetPackageResponseDto>()
.FirstOrDefaultAsync(cancellationToken);
return response ?? throw new NotFoundException(nameof(Package), request.Id);
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetPackage;
public class GetPackageQueryValidator : AbstractValidator<GetPackageQuery>
{
public GetPackageQueryValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetPackageQuery>.CreateWithOptions((GetPackageQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,15 @@
namespace CMSMicroservice.Application.PackageCQ.Queries.GetPackage;
public class GetPackageResponseDto
{
//شناسه
public long Id { get; set; }
//عنوان
public string Title { get; set; }
//توضیحات
public string Description { get; set; }
//آدرس تصویر
public string ImagePath { get; set; }
//قیمت
public long Price { get; set; }
}

View File

@@ -0,0 +1,9 @@
namespace CMSMicroservice.Application.RoleCQ.Commands.CreateNewRole;
public record CreateNewRoleCommand : IRequest<CreateNewRoleResponseDto>
{
//نام لاتین
public string Name { get; init; }
//عنوان
public string Title { get; init; }
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.RoleCQ.Commands.CreateNewRole;
public class CreateNewRoleCommandHandler : IRequestHandler<CreateNewRoleCommand, CreateNewRoleResponseDto>
{
private readonly IApplicationDbContext _context;
public CreateNewRoleCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<CreateNewRoleResponseDto> Handle(CreateNewRoleCommand request,
CancellationToken cancellationToken)
{
var entity = request.Adapt<Role>();
await _context.Roles.AddAsync(entity, cancellationToken);
entity.AddDomainEvent(new CreateNewRoleEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return entity.Adapt<CreateNewRoleResponseDto>();
}
}

View File

@@ -0,0 +1,18 @@
namespace CMSMicroservice.Application.RoleCQ.Commands.CreateNewRole;
public class CreateNewRoleCommandValidator : AbstractValidator<CreateNewRoleCommand>
{
public CreateNewRoleCommandValidator()
{
RuleFor(model => model.Name)
.NotEmpty();
RuleFor(model => model.Title)
.NotEmpty();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<CreateNewRoleCommand>.CreateWithOptions((CreateNewRoleCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.RoleCQ.Commands.CreateNewRole;
public class CreateNewRoleResponseDto
{
//شناسه
public long Id { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.RoleCQ.Commands.DeleteRole;
public record DeleteRoleCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.RoleCQ.Commands.DeleteRole;
public class DeleteRoleCommandHandler : IRequestHandler<DeleteRoleCommand, Unit>
{
private readonly IApplicationDbContext _context;
public DeleteRoleCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(DeleteRoleCommand request, CancellationToken cancellationToken)
{
var entity = await _context.Roles
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(Role), request.Id);
entity.IsDeleted = true;
_context.Roles.Update(entity);
entity.AddDomainEvent(new DeleteRoleEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.RoleCQ.Commands.DeleteRole;
public class DeleteRoleCommandValidator : AbstractValidator<DeleteRoleCommand>
{
public DeleteRoleCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteRoleCommand>.CreateWithOptions((DeleteRoleCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,11 @@
namespace CMSMicroservice.Application.RoleCQ.Commands.UpdateRole;
public record UpdateRoleCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
//نام لاتین
public string Name { get; init; }
//عنوان
public string Title { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.RoleCQ.Commands.UpdateRole;
public class UpdateRoleCommandHandler : IRequestHandler<UpdateRoleCommand, Unit>
{
private readonly IApplicationDbContext _context;
public UpdateRoleCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(UpdateRoleCommand request, CancellationToken cancellationToken)
{
var entity = await _context.Roles
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(Role), request.Id);
request.Adapt(entity);
_context.Roles.Update(entity);
entity.AddDomainEvent(new UpdateRoleEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,20 @@
namespace CMSMicroservice.Application.RoleCQ.Commands.UpdateRole;
public class UpdateRoleCommandValidator : AbstractValidator<UpdateRoleCommand>
{
public UpdateRoleCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
RuleFor(model => model.Name)
.NotEmpty();
RuleFor(model => model.Title)
.NotEmpty();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<UpdateRoleCommand>.CreateWithOptions((UpdateRoleCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.RoleCQ.EventHandlers;
public class CreateNewRoleEventHandler : INotificationHandler<CreateNewRoleEvent>
{
private readonly ILogger<CreateNewRoleEventHandler> _logger;
public CreateNewRoleEventHandler(ILogger<CreateNewRoleEventHandler> logger)
{
_logger = logger;
}
public Task Handle(CreateNewRoleEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.RoleCQ.EventHandlers;
public class DeleteRoleEventHandler : INotificationHandler<DeleteRoleEvent>
{
private readonly ILogger<DeleteRoleEventHandler> _logger;
public DeleteRoleEventHandler(ILogger<DeleteRoleEventHandler> logger)
{
_logger = logger;
}
public Task Handle(DeleteRoleEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.RoleCQ.EventHandlers;
public class UpdateRoleEventHandler : INotificationHandler<UpdateRoleEvent>
{
private readonly ILogger<UpdateRoleEventHandler> _logger;
public UpdateRoleEventHandler(ILogger<UpdateRoleEventHandler> logger)
{
_logger = logger;
}
public Task Handle(UpdateRoleEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,19 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetAllRoleByFilter;
public record GetAllRoleByFilterQuery : IRequest<GetAllRoleByFilterResponseDto>
{
//موقعیت صفحه بندی
public PaginationState? PaginationState { get; init; }
//مرتب سازی بر اساس
public string? SortBy { get; init; }
//فیلتر
public GetAllRoleByFilterFilter? Filter { get; init; }
}public class GetAllRoleByFilterFilter
{
//شناسه
public long? Id { get; set; }
//نام لاتین
public string? Name { get; set; }
//عنوان
public string? Title { get; set; }
}

View File

@@ -0,0 +1,32 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetAllRoleByFilter;
public class GetAllRoleByFilterQueryHandler : IRequestHandler<GetAllRoleByFilterQuery, GetAllRoleByFilterResponseDto>
{
private readonly IApplicationDbContext _context;
public GetAllRoleByFilterQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetAllRoleByFilterResponseDto> Handle(GetAllRoleByFilterQuery request, CancellationToken cancellationToken)
{
var query = _context.Roles
.ApplyOrder(sortBy: request.SortBy)
.AsNoTracking()
.AsQueryable();
if (request.Filter is not null)
{
query = query
.Where(x => request.Filter.Id == null || x.Id == request.Filter.Id)
.Where(x => request.Filter.Name == null || x.Name.Contains(request.Filter.Name))
.Where(x => request.Filter.Title == null || x.Title.Contains(request.Filter.Title))
;
}
return new GetAllRoleByFilterResponseDto
{
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
.ProjectToType<GetAllRoleByFilterResponseModel>().ToListAsync(cancellationToken)
};
}
}

View File

@@ -0,0 +1,14 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetAllRoleByFilter;
public class GetAllRoleByFilterQueryValidator : AbstractValidator<GetAllRoleByFilterQuery>
{
public GetAllRoleByFilterQueryValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllRoleByFilterQuery>.CreateWithOptions((GetAllRoleByFilterQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,17 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetAllRoleByFilter;
public class GetAllRoleByFilterResponseDto
{
//متادیتا
public MetaData MetaData { get; set; }
//مدل خروجی
public List<GetAllRoleByFilterResponseModel>? Models { get; set; }
}public class GetAllRoleByFilterResponseModel
{
//شناسه
public long Id { get; set; }
//نام لاتین
public string Name { get; set; }
//عنوان
public string Title { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetRole;
public record GetRoleQuery : IRequest<GetRoleResponseDto>
{
//شناسه
public long Id { get; init; }
}

View File

@@ -0,0 +1,22 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetRole;
public class GetRoleQueryHandler : IRequestHandler<GetRoleQuery, GetRoleResponseDto>
{
private readonly IApplicationDbContext _context;
public GetRoleQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetRoleResponseDto> Handle(GetRoleQuery request,
CancellationToken cancellationToken)
{
var response = await _context.Roles
.AsNoTracking()
.Where(x => x.Id == request.Id)
.ProjectToType<GetRoleResponseDto>()
.FirstOrDefaultAsync(cancellationToken);
return response ?? throw new NotFoundException(nameof(Role), request.Id);
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetRole;
public class GetRoleQueryValidator : AbstractValidator<GetRoleQuery>
{
public GetRoleQueryValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetRoleQuery>.CreateWithOptions((GetRoleQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,11 @@
namespace CMSMicroservice.Application.RoleCQ.Queries.GetRole;
public class GetRoleResponseDto
{
//شناسه
public long Id { get; set; }
//نام لاتین
public string Name { get; set; }
//عنوان
public string Title { get; set; }
}

View File

@@ -0,0 +1,17 @@
namespace CMSMicroservice.Application.UserAddressCQ.Commands.CreateNewUserAddress;
public record CreateNewUserAddressCommand : IRequest<CreateNewUserAddressResponseDto>
{
//شناسه کاربر
public long UserId { get; init; }
//عنوان
public string Title { get; init; }
//آدرس
public string Address { get; init; }
//کدپستی
public string PostalCode { get; init; }
//پیشفرض؟
public bool IsDefault { get; init; }
//شناسه شهر
public long CityId { get; init; }
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserAddressCQ.Commands.CreateNewUserAddress;
public class CreateNewUserAddressCommandHandler : IRequestHandler<CreateNewUserAddressCommand, CreateNewUserAddressResponseDto>
{
private readonly IApplicationDbContext _context;
public CreateNewUserAddressCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<CreateNewUserAddressResponseDto> Handle(CreateNewUserAddressCommand request,
CancellationToken cancellationToken)
{
var entity = request.Adapt<UserAddress>();
await _context.UserAddresss.AddAsync(entity, cancellationToken);
entity.AddDomainEvent(new CreateNewUserAddressEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return entity.Adapt<CreateNewUserAddressResponseDto>();
}
}

View File

@@ -0,0 +1,26 @@
namespace CMSMicroservice.Application.UserAddressCQ.Commands.CreateNewUserAddress;
public class CreateNewUserAddressCommandValidator : AbstractValidator<CreateNewUserAddressCommand>
{
public CreateNewUserAddressCommandValidator()
{
RuleFor(model => model.UserId)
.NotNull();
RuleFor(model => model.Title)
.NotEmpty();
RuleFor(model => model.Address)
.NotEmpty();
RuleFor(model => model.PostalCode)
.NotEmpty();
RuleFor(model => model.IsDefault)
.NotNull();
RuleFor(model => model.CityId)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<CreateNewUserAddressCommand>.CreateWithOptions((CreateNewUserAddressCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserAddressCQ.Commands.CreateNewUserAddress;
public class CreateNewUserAddressResponseDto
{
//شناسه
public long Id { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserAddressCQ.Commands.DeleteUserAddress;
public record DeleteUserAddressCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserAddressCQ.Commands.DeleteUserAddress;
public class DeleteUserAddressCommandHandler : IRequestHandler<DeleteUserAddressCommand, Unit>
{
private readonly IApplicationDbContext _context;
public DeleteUserAddressCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(DeleteUserAddressCommand request, CancellationToken cancellationToken)
{
var entity = await _context.UserAddresss
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(UserAddress), request.Id);
entity.IsDeleted = true;
_context.UserAddresss.Update(entity);
entity.AddDomainEvent(new DeleteUserAddressEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.UserAddressCQ.Commands.DeleteUserAddress;
public class DeleteUserAddressCommandValidator : AbstractValidator<DeleteUserAddressCommand>
{
public DeleteUserAddressCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserAddressCommand>.CreateWithOptions((DeleteUserAddressCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,19 @@
namespace CMSMicroservice.Application.UserAddressCQ.Commands.UpdateUserAddress;
public record UpdateUserAddressCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
//شناسه کاربر
public long UserId { get; init; }
//عنوان
public string Title { get; init; }
//آدرس
public string Address { get; init; }
//کدپستی
public string PostalCode { get; init; }
//پیشفرض؟
public bool IsDefault { get; init; }
//شناسه شهر
public long CityId { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserAddressCQ.Commands.UpdateUserAddress;
public class UpdateUserAddressCommandHandler : IRequestHandler<UpdateUserAddressCommand, Unit>
{
private readonly IApplicationDbContext _context;
public UpdateUserAddressCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(UpdateUserAddressCommand request, CancellationToken cancellationToken)
{
var entity = await _context.UserAddresss
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(UserAddress), request.Id);
request.Adapt(entity);
_context.UserAddresss.Update(entity);
entity.AddDomainEvent(new UpdateUserAddressEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,28 @@
namespace CMSMicroservice.Application.UserAddressCQ.Commands.UpdateUserAddress;
public class UpdateUserAddressCommandValidator : AbstractValidator<UpdateUserAddressCommand>
{
public UpdateUserAddressCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
RuleFor(model => model.UserId)
.NotNull();
RuleFor(model => model.Title)
.NotEmpty();
RuleFor(model => model.Address)
.NotEmpty();
RuleFor(model => model.PostalCode)
.NotEmpty();
RuleFor(model => model.IsDefault)
.NotNull();
RuleFor(model => model.CityId)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<UpdateUserAddressCommand>.CreateWithOptions((UpdateUserAddressCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserAddressCQ.EventHandlers;
public class CreateNewUserAddressEventHandler : INotificationHandler<CreateNewUserAddressEvent>
{
private readonly ILogger<CreateNewUserAddressEventHandler> _logger;
public CreateNewUserAddressEventHandler(ILogger<CreateNewUserAddressEventHandler> logger)
{
_logger = logger;
}
public Task Handle(CreateNewUserAddressEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserAddressCQ.EventHandlers;
public class DeleteUserAddressEventHandler : INotificationHandler<DeleteUserAddressEvent>
{
private readonly ILogger<DeleteUserAddressEventHandler> _logger;
public DeleteUserAddressEventHandler(ILogger<DeleteUserAddressEventHandler> logger)
{
_logger = logger;
}
public Task Handle(DeleteUserAddressEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.UserAddressCQ.EventHandlers;
public class UpdateUserAddressEventHandler : INotificationHandler<UpdateUserAddressEvent>
{
private readonly ILogger<UpdateUserAddressEventHandler> _logger;
public UpdateUserAddressEventHandler(ILogger<UpdateUserAddressEventHandler> logger)
{
_logger = logger;
}
public Task Handle(UpdateUserAddressEvent notification, CancellationToken cancellationToken)
{
_logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().Name);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,27 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetAllUserAddressByFilter;
public record GetAllUserAddressByFilterQuery : IRequest<GetAllUserAddressByFilterResponseDto>
{
//موقعیت صفحه بندی
public PaginationState? PaginationState { get; init; }
//مرتب سازی بر اساس
public string? SortBy { get; init; }
//فیلتر
public GetAllUserAddressByFilterFilter? Filter { get; init; }
}public class GetAllUserAddressByFilterFilter
{
//شناسه
public long? Id { get; set; }
//شناسه کاربر
public long? UserId { get; set; }
//عنوان
public string? Title { get; set; }
//آدرس
public string? Address { get; set; }
//کدپستی
public string? PostalCode { get; set; }
//پیشفرض؟
public bool? IsDefault { get; set; }
//شناسه شهر
public long? CityId { get; set; }
}

View File

@@ -0,0 +1,36 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetAllUserAddressByFilter;
public class GetAllUserAddressByFilterQueryHandler : IRequestHandler<GetAllUserAddressByFilterQuery, GetAllUserAddressByFilterResponseDto>
{
private readonly IApplicationDbContext _context;
public GetAllUserAddressByFilterQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetAllUserAddressByFilterResponseDto> Handle(GetAllUserAddressByFilterQuery request, CancellationToken cancellationToken)
{
var query = _context.UserAddresss
.ApplyOrder(sortBy: request.SortBy)
.AsNoTracking()
.AsQueryable();
if (request.Filter is not null)
{
query = query
.Where(x => request.Filter.Id == null || x.Id == request.Filter.Id)
.Where(x => request.Filter.UserId == null || x.UserId == request.Filter.UserId)
.Where(x => request.Filter.Title == null || x.Title.Contains(request.Filter.Title))
.Where(x => request.Filter.Address == null || x.Address.Contains(request.Filter.Address))
.Where(x => request.Filter.PostalCode == null || x.PostalCode.Contains(request.Filter.PostalCode))
.Where(x => request.Filter.IsDefault == null || x.IsDefault == request.Filter.IsDefault)
.Where(x => request.Filter.CityId == null || x.CityId == request.Filter.CityId)
;
}
return new GetAllUserAddressByFilterResponseDto
{
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
.ProjectToType<GetAllUserAddressByFilterResponseModel>().ToListAsync(cancellationToken)
};
}
}

View File

@@ -0,0 +1,14 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetAllUserAddressByFilter;
public class GetAllUserAddressByFilterQueryValidator : AbstractValidator<GetAllUserAddressByFilterQuery>
{
public GetAllUserAddressByFilterQueryValidator()
{
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetAllUserAddressByFilterQuery>.CreateWithOptions((GetAllUserAddressByFilterQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,25 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetAllUserAddressByFilter;
public class GetAllUserAddressByFilterResponseDto
{
//متادیتا
public MetaData MetaData { get; set; }
//مدل خروجی
public List<GetAllUserAddressByFilterResponseModel>? Models { get; set; }
}public class GetAllUserAddressByFilterResponseModel
{
//شناسه
public long Id { get; set; }
//شناسه کاربر
public long UserId { get; set; }
//عنوان
public string Title { get; set; }
//آدرس
public string Address { get; set; }
//کدپستی
public string PostalCode { get; set; }
//پیشفرض؟
public bool IsDefault { get; set; }
//شناسه شهر
public long CityId { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetUserAddress;
public record GetUserAddressQuery : IRequest<GetUserAddressResponseDto>
{
//شناسه
public long Id { get; init; }
}

View File

@@ -0,0 +1,22 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetUserAddress;
public class GetUserAddressQueryHandler : IRequestHandler<GetUserAddressQuery, GetUserAddressResponseDto>
{
private readonly IApplicationDbContext _context;
public GetUserAddressQueryHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<GetUserAddressResponseDto> Handle(GetUserAddressQuery request,
CancellationToken cancellationToken)
{
var response = await _context.UserAddresss
.AsNoTracking()
.Where(x => x.Id == request.Id)
.ProjectToType<GetUserAddressResponseDto>()
.FirstOrDefaultAsync(cancellationToken);
return response ?? throw new NotFoundException(nameof(UserAddress), request.Id);
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetUserAddress;
public class GetUserAddressQueryValidator : AbstractValidator<GetUserAddressQuery>
{
public GetUserAddressQueryValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<GetUserAddressQuery>.CreateWithOptions((GetUserAddressQuery)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,19 @@
namespace CMSMicroservice.Application.UserAddressCQ.Queries.GetUserAddress;
public class GetUserAddressResponseDto
{
//شناسه
public long Id { get; set; }
//شناسه کاربر
public long UserId { get; set; }
//عنوان
public string Title { get; set; }
//آدرس
public string Address { get; set; }
//کدپستی
public string PostalCode { get; set; }
//پیشفرض؟
public bool IsDefault { get; set; }
//شناسه شهر
public long CityId { get; set; }
}

View File

@@ -0,0 +1,17 @@
namespace CMSMicroservice.Application.UserCQ.Commands.CreateNewUser;
public record CreateNewUserCommand : IRequest<CreateNewUserResponseDto>
{
//نام
public string? FirstName { get; init; }
//نام خانوادگی
public string? LastName { get; init; }
//شماره موبایل
public string Mobile { get; init; }
//کد ملی
public string? NationalCode { get; init; }
//آدرس آواتار
public string? AvatarPath { get; init; }
//شناسه والد
public long? ParentId { get; init; }
}

View File

@@ -0,0 +1,21 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserCQ.Commands.CreateNewUser;
public class CreateNewUserCommandHandler : IRequestHandler<CreateNewUserCommand, CreateNewUserResponseDto>
{
private readonly IApplicationDbContext _context;
public CreateNewUserCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<CreateNewUserResponseDto> Handle(CreateNewUserCommand request,
CancellationToken cancellationToken)
{
var entity = request.Adapt<User>();
await _context.Users.AddAsync(entity, cancellationToken);
entity.AddDomainEvent(new CreateNewUserEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return entity.Adapt<CreateNewUserResponseDto>();
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.UserCQ.Commands.CreateNewUser;
public class CreateNewUserCommandValidator : AbstractValidator<CreateNewUserCommand>
{
public CreateNewUserCommandValidator()
{
RuleFor(model => model.Mobile)
.NotEmpty();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<CreateNewUserCommand>.CreateWithOptions((CreateNewUserCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserCQ.Commands.CreateNewUser;
public class CreateNewUserResponseDto
{
//شناسه
public long Id { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace CMSMicroservice.Application.UserCQ.Commands.DeleteUser;
public record DeleteUserCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserCQ.Commands.DeleteUser;
public class DeleteUserCommandHandler : IRequestHandler<DeleteUserCommand, Unit>
{
private readonly IApplicationDbContext _context;
public DeleteUserCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(DeleteUserCommand request, CancellationToken cancellationToken)
{
var entity = await _context.Users
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(User), request.Id);
entity.IsDeleted = true;
_context.Users.Update(entity);
entity.AddDomainEvent(new DeleteUserEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,16 @@
namespace CMSMicroservice.Application.UserCQ.Commands.DeleteUser;
public class DeleteUserCommandValidator : AbstractValidator<DeleteUserCommand>
{
public DeleteUserCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<DeleteUserCommand>.CreateWithOptions((DeleteUserCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

View File

@@ -0,0 +1,19 @@
namespace CMSMicroservice.Application.UserCQ.Commands.UpdateUser;
public record UpdateUserCommand : IRequest<Unit>
{
//شناسه
public long Id { get; init; }
//نام
public string? FirstName { get; init; }
//نام خانوادگی
public string? LastName { get; init; }
//شماره موبایل
public string Mobile { get; init; }
//کد ملی
public string? NationalCode { get; init; }
//آدرس آواتار
public string? AvatarPath { get; init; }
//شناسه والد
public long? ParentId { get; init; }
}

View File

@@ -0,0 +1,22 @@
using CMSMicroservice.Domain.Events;
namespace CMSMicroservice.Application.UserCQ.Commands.UpdateUser;
public class UpdateUserCommandHandler : IRequestHandler<UpdateUserCommand, Unit>
{
private readonly IApplicationDbContext _context;
public UpdateUserCommandHandler(IApplicationDbContext context)
{
_context = context;
}
public async Task<Unit> Handle(UpdateUserCommand request, CancellationToken cancellationToken)
{
var entity = await _context.Users
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken) ?? throw new NotFoundException(nameof(User), request.Id);
request.Adapt(entity);
_context.Users.Update(entity);
entity.AddDomainEvent(new UpdateUserEvent(entity));
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;
}
}

View File

@@ -0,0 +1,18 @@
namespace CMSMicroservice.Application.UserCQ.Commands.UpdateUser;
public class UpdateUserCommandValidator : AbstractValidator<UpdateUserCommand>
{
public UpdateUserCommandValidator()
{
RuleFor(model => model.Id)
.NotNull();
RuleFor(model => model.Mobile)
.NotEmpty();
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<UpdateUserCommand>.CreateWithOptions((UpdateUserCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

Some files were not shown because too many files have changed in this diff Show More