feat(FaqInActions) , feat(FaqManagementPage) , feat(FaqController)

subProduct
Amir Hossein Khademi 2024-08-07 16:15:53 +03:30
parent 5524cb4e43
commit 19f1f29548
45 changed files with 588 additions and 264 deletions

View File

@ -0,0 +1,56 @@
namespace Netina.Api.Controllers;
public class FaqController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Faq")
.MapGroup("api/faq");
group.MapGet("/slug", GetFaqBySlugAsync)
.WithDisplayName("GetFaqBySlug")
.WithDescription("Get faq by slug , you have to send page slug")
.HasApiVersion(1.0);
group.MapGet("", GetFaqsAsync)
.WithDisplayName("GetFaqs")
.WithDescription("Get All Faqs ")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer")
.RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
group.MapPost("", CreateFaqAsync)
.WithDisplayName("Create Faq")
.WithDescription("Create Faq , you can create new faq or create update your faq ")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer")
.RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
group.MapPut("", UpdateFaqAsync)
.WithDisplayName("Update FaqAsync")
.WithDescription("Update Faq , you can create new faq or create update your faq ")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer")
.RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteFaqAsync)
.WithDisplayName("DeleteFaq")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFaq))
.HasApiVersion(1.0);
}
private async Task<IResult> DeleteFaqAsync([FromRoute]Guid id,[FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteFaqCommand(Id:id), cancellationToken));
private async Task<IResult> GetFaqsAsync([FromQuery]int page, [FromQuery] int? count ,[FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetFaqsQuery(Count: count ?? 0 , Page:page), cancellationToken));
private async Task<IResult> CreateFaqAsync([FromBody] CreateFaqCommand request,[FromServices]IMediator mediator , CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
private async Task<IResult> UpdateFaqAsync([FromBody] UpdateFaqCommand request, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
private async Task<IResult> GetFaqBySlugAsync([FromQuery] string slug, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetFaqQuery(null, slug), cancellationToken));
}

View File

@ -78,13 +78,14 @@ public class SeedController : ICarterModule
var baseCat = await mediator.Send(new CreateProductCategoryCommand("دسته بندی نشده", "محصولات دسته بندی نشده", var baseCat = await mediator.Send(new CreateProductCategoryCommand("دسته بندی نشده", "محصولات دسته بندی نشده",
true, true,
default, default,
new List<StorageFileSDto>()),cancellationToken); new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()),cancellationToken);
categories.Add(0,baseCat); categories.Add(0,baseCat);
foreach (var requestDto in request) foreach (var requestDto in request)
{ {
var lDto = await mediator.Send(new CreateProductCategoryCommand(requestDto.Name,requestDto.Description,true,default, var lDto = await mediator.Send(new CreateProductCategoryCommand(requestDto.Name,requestDto.Description,true,default,
new List<StorageFileSDto>(),new Dictionary<string, string>(),new Dictionary<string, string>()), cancellationToken);
new List<StorageFileSDto>()), cancellationToken);
categories.Add(requestDto.BaseCategoryId,lDto); categories.Add(requestDto.BaseCategoryId,lDto);
} }
@ -97,13 +98,18 @@ public class SeedController : ICarterModule
if (key != "kKAYskyG8xPxKnJrHkuYxub4Ao2bnz7AOmNtwDT0RaqzaG7ZvbvaP29tCrC8wJ823RczJFXOIQT2bDOec4F38A==") if (key != "kKAYskyG8xPxKnJrHkuYxub4Ao2bnz7AOmNtwDT0RaqzaG7ZvbvaP29tCrC8wJ823RczJFXOIQT2bDOec4F38A==")
throw new AppException("Key is not valid", ApiResultStatusCode.UnAuthorized); throw new AppException("Key is not valid", ApiResultStatusCode.UnAuthorized);
Dictionary<int, Guid> brands = new Dictionary<int, Guid>(); Dictionary<int, Guid> brands = new Dictionary<int, Guid>();
var baseBrand = await mediator.Send(new CreateBrandCommand("بدون برند","NoBrand", "محصولات بدون برند", false,string.Empty, var baseBrand = await mediator.Send(new CreateBrandCommand("بدون برند","NoBrand",
new List<StorageFileSDto>()), cancellationToken); "محصولات بدون برند",
false,
string.Empty,
new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()), cancellationToken);
brands.Add(0, baseBrand); brands.Add(0, baseBrand);
foreach (var requestDto in request) foreach (var requestDto in request)
{ {
var sDto = await mediator.Send(new CreateBrandCommand(requestDto.Name,string.Empty, requestDto.Description, false, var sDto = await mediator.Send(new CreateBrandCommand(requestDto.Name,string.Empty, requestDto.Description, false,
string.Empty, new List<StorageFileSDto>()), cancellationToken); string.Empty, new List<StorageFileSDto>(),new Dictionary<string, string>(),new Dictionary<string, string>()), cancellationToken);
brands.Add(requestDto.BaseBrandId,sDto); brands.Add(requestDto.BaseBrandId,sDto);
} }

View File

@ -39,7 +39,9 @@ public class ExceptionHandlerMiddleware
catch (BaseApiException exception) catch (BaseApiException exception)
{ {
_logger.LogError(exception, exception.Message); _logger.LogError(exception, exception.Message);
httpStatusCode = exception.HttpStatusCode; httpStatusCode = exception.ApiStatusCode == ApiResultStatusCode.NotFound ? HttpStatusCode.NotFound :
exception.ApiStatusCode == ApiResultStatusCode.BadRequest ?
HttpStatusCode.BadRequest : exception.HttpStatusCode;
apiStatusCode = exception.ApiStatusCode; apiStatusCode = exception.ApiStatusCode;
if (_env.IsDevelopment()) if (_env.IsDevelopment())

View File

@ -1,8 +1,23 @@
namespace Netina.Domain.CommandQueries.Commands; namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateBrandCommand(string PersianName,string EnglishName, string Description , bool HasSpecialPage , string PageUrl, List<StorageFileSDto> Files) : IRequest<Guid>; public sealed record CreateBrandCommand(string PersianName,
string EnglishName,
string Description ,
bool HasSpecialPage ,
string PageUrl,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<Guid>;
public sealed record UpdateBrandCommand(Guid Id,string PersianName, string EnglishName, string Description, bool HasSpecialPage, string PageUrl, List<StorageFileSDto> Files) : IRequest<bool>; public sealed record UpdateBrandCommand(Guid Id,
string PersianName,
string EnglishName,
string Description,
bool HasSpecialPage,
string PageUrl,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record DeleteBrandCommand(Guid Id) : IRequest<bool>; public sealed record DeleteBrandCommand(Guid Id) : IRequest<bool>;

View File

@ -0,0 +1,15 @@
namespace Netina.Domain.CommandQueries.Commands;
public record CreateFaqCommand(
Dictionary<string, string> Faqs,
string Slug,
string Title) : IRequest<bool>;
public record DeleteFaqCommand(Guid Id) : IRequest<bool>;
public record UpdateFaqCommand(
Guid Id,
Dictionary<string, string> Faqs,
string Slug,
string Title) : IRequest<bool>;

View File

@ -5,7 +5,9 @@ public sealed record CreateProductCategoryCommand(
string Description, string Description,
bool IsMain, bool IsMain,
Guid ParentId, Guid ParentId,
List<StorageFileSDto> Files) : IRequest<Guid>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<Guid>;
public sealed record UpdateProductCategoryCommand( public sealed record UpdateProductCategoryCommand(
Guid Id, Guid Id,
@ -13,6 +15,8 @@ public sealed record UpdateProductCategoryCommand(
string Description, string Description,
bool IsMain, bool IsMain,
Guid ParentId, Guid ParentId,
List<StorageFileSDto> Files) : IRequest<bool>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record DeleteProductCategoryCommand(Guid Id) : IRequest<bool>; public sealed record DeleteProductCategoryCommand(Guid Id) : IRequest<bool>;

View File

@ -18,7 +18,9 @@ Guid BrandId,
Guid CategoryId, Guid CategoryId,
DiscountSDto SpecialOffer, DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications, List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files):IRequest<ProductLDto>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<ProductLDto>;
public sealed record UpdateProductCommand( public sealed record UpdateProductCommand(
Guid Id, Guid Id,
@ -39,9 +41,12 @@ public sealed record UpdateProductCommand(
Guid CategoryId, Guid CategoryId,
DiscountSDto SpecialOffer, DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications, List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files) : IRequest<bool>; List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record ChangeProductDisplayedCommand(Guid Id, bool BeDisplayed) : IRequest<bool>; public sealed record ChangeProductDisplayedCommand(Guid Id, bool BeDisplayed) : IRequest<bool>;
public sealed record ChangeProductCostCommand(Guid Id, double Cost) : IRequest<bool>; public sealed record ChangeProductCostCommand(Guid Id, double Cost) : IRequest<bool>;
public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>; public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>;

View File

@ -0,0 +1,4 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetFaqQuery(Guid? Id,string? Slug) : IRequest<BaseFaq>;
public record GetFaqsQuery(int Page , int Count = 0) : IRequest<List<BaseFaq>>;

View File

@ -6,6 +6,7 @@ public class BrandLDto : BaseDto<BrandLDto,Brand>
public string EnglishName { get; set; } = string.Empty; public string EnglishName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty; public string Description { get; set; } = string.Empty;
public bool HasSpecialPage { get; set; } public bool HasSpecialPage { get; set; }
public string Slug { get; set; } = string.Empty;
public string PageUrl { get; set; } = string.Empty; public string PageUrl { get; set; } = string.Empty;
public string HeaderFileName { get; set; } = string.Empty; public string HeaderFileName { get; set; } = string.Empty;
public List<StorageFileSDto> Files { get; internal set; } = new(); public List<StorageFileSDto> Files { get; internal set; } = new();

View File

@ -6,6 +6,7 @@ public class ProductCategoryLDto : BaseDto<ProductCategoryLDto, ProductCategory>
public string Description { get; set; } = string.Empty; public string Description { get; set; } = string.Empty;
public Guid ParentId { get; set; } public Guid ParentId { get; set; }
public string ParentName { get; set; } = string.Empty; public string ParentName { get; set; } = string.Empty;
public string Slug { get; set; } = string.Empty;
public bool IsMain { get; set; } public bool IsMain { get; set; }
public List<ProductCategorySDto> Children { get; set; } = new(); public List<ProductCategorySDto> Children { get; set; } = new();
public List<StorageFileSDto> Files { get; internal set; } = new(); public List<StorageFileSDto> Files { get; internal set; } = new();

View File

@ -5,6 +5,7 @@ public class BrandSDto : BaseDto<BrandSDto , Brand>
public string PersianName { get; set; } = string.Empty; public string PersianName { get; set; } = string.Empty;
public string EnglishName { get; set; } = string.Empty; public string EnglishName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty; public string Description { get; set; } = string.Empty;
public string Slug { get; set; } = string.Empty;
public bool HasSpecialPage { get; set; } public bool HasSpecialPage { get; set; }
public string PageUrl { get; set; } = string.Empty; public string PageUrl { get; set; } = string.Empty;
public string HeaderFileName { get; set; } = string.Empty; public string HeaderFileName { get; set; } = string.Empty;

View File

@ -1,10 +1,13 @@
namespace Netina.Domain.Entities.Brands; using Microsoft.EntityFrameworkCore;
namespace Netina.Domain.Entities.Brands;
[AdaptTwoWays("[name]LDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)] [AdaptTwoWays("[name]LDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)]
[AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget)] [AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget)]
[AdaptTo("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)] [AdaptTo("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)]
[GenerateMapper] [GenerateMapper]
[Index(nameof(Slug), IsUnique = true)]
public partial class Brand : ApiEntity public partial class Brand : ApiEntity
{ {
public Brand() public Brand()

View File

@ -6,6 +6,9 @@
[AdaptTo("TorobProductResponseDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)] [AdaptTo("TorobProductResponseDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)]
//[AdaptTo("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)] //[AdaptTo("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)]
[GenerateMapper] [GenerateMapper]
[Index(nameof(Slug), IsUnique = true)]
public partial class Product : ApiEntity public partial class Product : ApiEntity
{ {
public Product() public Product()

View File

@ -0,0 +1,13 @@
namespace Netina.Domain.Extensions;
public static class BrandExtension
{
public static string GetWebSiteUrl(this Brand product)
=> $"/brands/{product.Id}/{product.Slug}";
public static string GetWebSiteUrl(this BrandSDto product)
=> $"/brands/{product.Id}/{product.Slug}";
public static string GetWebSiteUrl(this BrandLDto product)
=> $"/brands/{product.Id}/{product.Slug}";
}

View File

@ -0,0 +1,13 @@
namespace Netina.Domain.Extensions;
public static class ProductCategoryExtension
{
public static string GetWebSiteUrl(this ProductCategory product)
=> $"/categories/{product.Id}/{product.Slug}";
public static string GetWebSiteUrl(this ProductCategorySDto product)
=> $"/categories/{product.Id}/{product.Slug}";
public static string GetWebSiteUrl(this ProductCategoryLDto product)
=> $"/categories/{product.Id}/{product.Slug}";
}

View File

@ -0,0 +1,13 @@
namespace Netina.Domain.Extensions;
public static class ProductExtension
{
public static string GetWebSiteUrl(this Product product)
=> $"/products/{product.Id}/{product.Slug}";
public static string GetWebSiteUrl(this ProductSDto product)
=> $"/products/{product.Id}/{product.Slug}";
public static string GetWebSiteUrl(this ProductLDto product)
=> $"/products/{product.Id}/{product.Slug}";
}

View File

@ -0,0 +1,8 @@
namespace Netina.Domain.MartenEntities.Faqs;
public class BaseFaq : MartenEntity
{
public Dictionary<string, string> Faqs { get; set; } = new();
public string Slug { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
}

View File

@ -1,7 +0,0 @@
namespace Netina.Domain.MartenEntities.Pages;
[PageClassDisplay("FAQPage", "صفحه سوالات متداول")]
public class FAQPage
{
public Dictionary<string, string> Faqs { get; set; } = new Dictionary<string, string>();
}

View File

@ -11,6 +11,13 @@ public static class ApplicationClaims
Value = ApplicationPermission.ManageDashboard, Value = ApplicationPermission.ManageDashboard,
}; };
public static ClaimDto ManageFaq { get; } = new ClaimDto
{
Title = "مدیریت سوالات متداول",
Type = CustomClaimType.Permission,
Value = ApplicationPermission.ManageFaq,
};
public static ClaimDto ManageBlogs { get; } = new ClaimDto public static ClaimDto ManageBlogs { get; } = new ClaimDto
{ {
Title = "مدیریت بلاگ ها", Title = "مدیریت بلاگ ها",
@ -278,7 +285,8 @@ public static class ApplicationClaims
ManageUsers, ManageUsers,
ViewUsers, ViewUsers,
ManageFiles, ManageFiles,
ViewFiles ViewFiles,
ManageFaq
}; };
public static List<Claim> AllClaims = new List<Claim> public static List<Claim> AllClaims = new List<Claim>
@ -319,7 +327,8 @@ public static class ApplicationClaims
ManageUsers.GetClaim, ManageUsers.GetClaim,
ViewUsers.GetClaim, ViewUsers.GetClaim,
ManageFiles.GetClaim, ManageFiles.GetClaim,
ViewFiles.GetClaim ViewFiles.GetClaim,
ManageFaq.GetClaim
}; };
public static List<Claim> CustomerClaims = new List<Claim> public static List<Claim> CustomerClaims = new List<Claim>

View File

@ -2,6 +2,8 @@
public static class ApplicationPermission public static class ApplicationPermission
{ {
public static string ManageFaq = nameof(ManageFaq);
public const string ViewSettings = nameof(ViewSettings); public const string ViewSettings = nameof(ViewSettings);
public const string ManageSettings = nameof(ManageSettings); public const string ManageSettings = nameof(ManageSettings);

View File

@ -12,6 +12,7 @@
<PackageReference Include="Mapster" Version="7.4.0" /> <PackageReference Include="Mapster" Version="7.4.0" />
<PackageReference Include="Mapster.Core" Version="1.2.1" /> <PackageReference Include="Mapster.Core" Version="1.2.1" />
<PackageReference Include="MediatR" Version="12.4.0" /> <PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.7" /> <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.7" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" /> <PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
</ItemGroup> </ItemGroup>
@ -59,6 +60,7 @@
<ItemGroup> <ItemGroup>
<Using Include="Mapster" /> <Using Include="Mapster" />
<Using Include="MediatR" /> <Using Include="MediatR" />
<Using Include="Microsoft.EntityFrameworkCore"/>
<Using Include="Microsoft.AspNetCore.Identity" /> <Using Include="Microsoft.AspNetCore.Identity" />
<Using Include="Microsoft.Extensions.Logging" /> <Using Include="Microsoft.Extensions.Logging" />
<Using Include="Netina.Common.Extensions" /> <Using Include="Netina.Common.Extensions" />
@ -78,6 +80,7 @@
<Using Include="Netina.Domain.Entities.Users" /> <Using Include="Netina.Domain.Entities.Users" />
<Using Include="Netina.Domain.Entities.Warehouses" /> <Using Include="Netina.Domain.Entities.Warehouses" />
<Using Include="Netina.Domain.Enums" /> <Using Include="Netina.Domain.Enums" />
<Using Include="Netina.Domain.MartenEntities.Faqs" />
<Using Include="Netina.Domain.MartenEntities.Settings" /> <Using Include="Netina.Domain.MartenEntities.Settings" />
<Using Include="System.ComponentModel.DataAnnotations" /> <Using Include="System.ComponentModel.DataAnnotations" />
<Using Include="System.Diagnostics" /> <Using Include="System.Diagnostics" />

View File

@ -1,33 +1,52 @@
using Marten; using Marten;
using Netina.Repository.Abstracts;
namespace Netina.Infrastructure.Marten; namespace Netina.Infrastructure.Marten;
public class MartenRepository<TMartenEntity> : IMartenRepository<TMartenEntity> where TMartenEntity : IMartenEntity public class MartenRepository<TMartenEntity>(IDocumentStore documentStore, ICurrentUserService currentUserService)
: IMartenRepository<TMartenEntity>
where TMartenEntity : IMartenEntity
{ {
private readonly IDocumentStore _documentStore; private readonly ICurrentUserService _currentUserService = currentUserService;
public MartenRepository(IDocumentStore documentStore)
{
_documentStore = documentStore;
}
public async Task<List<TMartenEntity>> GetEntitiesAsync(CancellationToken cancellation) public async Task<List<TMartenEntity>> GetEntitiesAsync(CancellationToken cancellation)
{ {
await using var session = _documentStore.QuerySession(); await using var session = documentStore.QuerySession();
var entities = await session.Query<TMartenEntity>().ToListAsync(cancellation); var entities = await session
.Query<TMartenEntity>()
.ToListAsync(cancellation);
return entities.ToList();
}
public async Task<List<TMartenEntity>> GetEntitiesAsync(int page, int count, CancellationToken cancellation)
{
await using var session = documentStore.QuerySession();
var entities = await session
.Query<TMartenEntity>()
.Skip(page * count)
.Take(count)
.ToListAsync(cancellation);
return entities.ToList(); return entities.ToList();
} }
public async Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, int page, int count, CancellationToken cancellation)
{
await using var session = documentStore.QuerySession();
var entities = await session.Query<TMartenEntity>().Where(expression)
.Skip(page * count)
.Take(count)
.ToListAsync(cancellation);
return entities.ToList();
}
public async Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation) public async Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation)
{ {
await using var session = _documentStore.QuerySession(); await using var session = documentStore.QuerySession();
var entities = await session.Query<TMartenEntity>().Where(expression).ToListAsync(cancellation); var entities = await session.Query<TMartenEntity>().Where(expression).ToListAsync(cancellation);
return entities.ToList(); return entities.ToList();
} }
public async Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation) public async Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation)
{ {
await using var session = _documentStore.QuerySession(); await using var session = documentStore.QuerySession();
var setting = await session.LoadAsync<TMartenEntity>(id, cancellation); var setting = await session.LoadAsync<TMartenEntity>(id, cancellation);
if (setting == null) if (setting == null)
throw new AppException($"{nameof(setting)} not found", ApiResultStatusCode.NotFound); throw new AppException($"{nameof(setting)} not found", ApiResultStatusCode.NotFound);
@ -36,7 +55,7 @@ public class MartenRepository<TMartenEntity> : IMartenRepository<TMartenEntity>
public async Task<TMartenEntity?> GetEntityAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation) public async Task<TMartenEntity?> GetEntityAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation)
{ {
await using var session = _documentStore.QuerySession(); await using var session = documentStore.QuerySession();
var entity = await session.Query<TMartenEntity>().FirstOrDefaultAsync(expression, cancellation); var entity = await session.Query<TMartenEntity>().FirstOrDefaultAsync(expression, cancellation);
return entity; return entity;
} }
@ -46,16 +65,26 @@ public class MartenRepository<TMartenEntity> : IMartenRepository<TMartenEntity>
if (entity == null) if (entity == null)
throw new AppException($"{nameof(entity)} is null", ApiResultStatusCode.BadRequest); throw new AppException($"{nameof(entity)} is null", ApiResultStatusCode.BadRequest);
await using var session = _documentStore.LightweightSession(); await using var session = documentStore.LightweightSession();
session.Store(entity); session.Store(entity);
await session.SaveChangesAsync(cancellation); await session.SaveChangesAsync(cancellation);
} }
public async Task UpdateEntityAsync(TMartenEntity entity, CancellationToken cancellation = default)
{
if (entity == null)
throw new AppException($"{nameof(entity)} is null", ApiResultStatusCode.BadRequest);
await using var session = documentStore.LightweightSession();
session.Update(entity);
await session.SaveChangesAsync(cancellation);
}
public async Task RemoveEntityAsync(TMartenEntity entity, CancellationToken cancellation) public async Task RemoveEntityAsync(TMartenEntity entity, CancellationToken cancellation)
{ {
if (entity == null) if (entity == null)
throw new AppException($"{nameof(entity)} is null", ApiResultStatusCode.BadRequest); throw new AppException($"{nameof(entity)} is null", ApiResultStatusCode.BadRequest);
await using var session = _documentStore.LightweightSession(); await using var session = documentStore.LightweightSession();
session.Delete(entity); session.Delete(entity);
await session.SaveChangesAsync(cancellation); await session.SaveChangesAsync(cancellation);
} }

View File

@ -1,16 +1,10 @@
using Marten; using Marten;
using Netina.Repository.Abstracts;
namespace Netina.Infrastructure.Marten; namespace Netina.Infrastructure.Marten;
public class MartenRepositoryWrapper : IMartenRepositoryWrapper public class MartenRepositoryWrapper(IDocumentStore documentStore,ICurrentUserService currentUserService) : IMartenRepositoryWrapper
{ {
private readonly IDocumentStore _documentStore;
public MartenRepositoryWrapper(IDocumentStore documentStore)
{
_documentStore = documentStore;
}
public IMartenRepository<TMartenEntity> SetRepository<TMartenEntity>() where TMartenEntity : IMartenEntity public IMartenRepository<TMartenEntity> SetRepository<TMartenEntity>() where TMartenEntity : IMartenEntity
=> new MartenRepository<TMartenEntity>(_documentStore); => new MartenRepository<TMartenEntity>(documentStore, currentUserService);
} }

View File

@ -102,7 +102,7 @@ public class DigikalaScraper : IDigikalaScraper
newSummery, newSummery,
string.Empty, string.Empty, string.Empty, true, 0, string.Empty, string.Empty, string.Empty, true, 0,
0, 0, false 0, 0, false
, 5, false, nonBrand.Id, nonCat.Id, new DiscountSDto(), specifications, files); , 5, false, nonBrand.Id, nonCat.Id, new DiscountSDto(), specifications, files,new Dictionary<string, string>(),new Dictionary<string, string>());
await _mediator.Send(request, cancellationToken); await _mediator.Send(request, cancellationToken);
return true; return true;

View File

@ -2,14 +2,8 @@
namespace Netina.Repository.Handlers.Brands; namespace Netina.Repository.Handlers.Brands;
public class CreateBrandCommandHandler : IRequestHandler<CreateBrandCommand , Guid> public class CreateBrandCommandHandler(IRepositoryWrapper repositoryWrapper,IMartenRepositoryWrapper martenRepositoryWrapper , IMediator mediator) : IRequestHandler<CreateBrandCommand, Guid>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public CreateBrandCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<Guid> Handle(CreateBrandCommand request, CancellationToken cancellationToken) public async Task<Guid> Handle(CreateBrandCommand request, CancellationToken cancellationToken)
{ {
var ent = Brand.Create(request.PersianName,request.EnglishName, request.Description, request.HasSpecialPage, request.PageUrl); var ent = Brand.Create(request.PersianName,request.EnglishName, request.Description, request.HasSpecialPage, request.PageUrl);
@ -17,8 +11,28 @@ public class CreateBrandCommandHandler : IRequestHandler<CreateBrandCommand , Gu
{ {
ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
} }
_repositoryWrapper.SetRepository<Brand>().Add(ent); repositoryWrapper.SetRepository<Brand>().Add(ent);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
await UpdateFaqAsync(ent, request.Faqs, cancellationToken);
return ent.Id; return ent.Id;
} }
private async Task UpdateFaqAsync(Brand newEnt, Dictionary<string, string> faqs, CancellationToken cancellationToken)
{
var url = newEnt.GetWebSiteUrl();
var oldFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == newEnt.Slug, cancellationToken);
var newFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == url, cancellationToken);
if (oldFaq != null)
await mediator.Send(new DeleteFaqCommand(oldFaq.Id), cancellationToken);
if (newFaq == null)
await mediator.Send(new CreateFaqCommand(faqs, url, newEnt.EnglishName), cancellationToken);
else
await mediator.Send(new UpdateFaqCommand(newFaq.Id, faqs, url, newEnt.EnglishName), cancellationToken);
}
} }

View File

@ -1,19 +1,12 @@
using Microsoft.EntityFrameworkCore; using Netina.Domain.Entities.Brands;
using Netina.Domain.Entities.Brands;
namespace Netina.Repository.Handlers.Brands; namespace Netina.Repository.Handlers.Brands;
public class UpdateBrandCommandHandler : IRequestHandler<UpdateBrandCommand,bool> public class UpdateBrandCommandHandler(IRepositoryWrapper repositoryWrapper,IMartenRepositoryWrapper martenRepositoryWrapper,IMediator mediator) : IRequestHandler<UpdateBrandCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public UpdateBrandCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(UpdateBrandCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(UpdateBrandCommand request, CancellationToken cancellationToken)
{ {
var ent = await _repositoryWrapper.SetRepository<Brand>().TableNoTracking var ent = await repositoryWrapper.SetRepository<Brand>().TableNoTracking
.FirstOrDefaultAsync(b => b.Id == request.Id, cancellationToken); .FirstOrDefaultAsync(b => b.Id == request.Id, cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Brand not found"); throw new AppException("Brand not found");
@ -22,14 +15,14 @@ public class UpdateBrandCommandHandler : IRequestHandler<UpdateBrandCommand,bool
newEnt.CreatedAt = ent.CreatedAt; newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy; newEnt.CreatedBy = ent.CreatedBy;
var dbFiles = await _repositoryWrapper.SetRepository<BrandStorageFile>().TableNoTracking var dbFiles = await repositoryWrapper.SetRepository<BrandStorageFile>().TableNoTracking
.Where(s => s.BrandId == newEnt.Id).ToListAsync(cancellationToken); .Where(s => s.BrandId == newEnt.Id).ToListAsync(cancellationToken);
foreach (var dbFile in dbFiles) foreach (var dbFile in dbFiles)
{ {
if (request.Files.FirstOrDefault(s => s.Id == dbFile.Id) == null) if (request.Files.FirstOrDefault(s => s.Id == dbFile.Id) == null)
{ {
_repositoryWrapper.SetRepository<BrandStorageFile>().Delete(dbFile); repositoryWrapper.SetRepository<BrandStorageFile>().Delete(dbFile);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
} }
foreach (var file in request.Files.Where(f => f.Id == default)) foreach (var file in request.Files.Where(f => f.Id == default))
@ -37,8 +30,26 @@ public class UpdateBrandCommandHandler : IRequestHandler<UpdateBrandCommand,bool
newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
} }
_repositoryWrapper.SetRepository<Brand>().Update(newEnt); repositoryWrapper.SetRepository<Brand>().Update(newEnt);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
await UpdateFaqAsync(newEnt, request.Faqs, cancellationToken);
return true; return true;
} }
private async Task UpdateFaqAsync(Brand newEnt, Dictionary<string, string> faqs, CancellationToken cancellationToken)
{
var url = newEnt.GetWebSiteUrl();
var oldFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == newEnt.Slug, cancellationToken);
var newFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == url, cancellationToken);
if (oldFaq != null)
await mediator.Send(new DeleteFaqCommand(oldFaq.Id), cancellationToken);
if (newFaq == null)
await mediator.Send(new CreateFaqCommand(faqs, url, newEnt.EnglishName), cancellationToken);
else
await mediator.Send(new UpdateFaqCommand(newFaq.Id, faqs, url, newEnt.EnglishName), cancellationToken);
}
} }

View File

@ -0,0 +1,18 @@
namespace Netina.Repository.Handlers.Faqs;
public class CreateFaqCommandHandler(IMartenRepositoryWrapper martenRepositoryWrapper)
: IRequestHandler<CreateFaqCommand, bool>
{
public async Task<bool> Handle(CreateFaqCommand request, CancellationToken cancellationToken)
{
var faq = new BaseFaq
{
Faqs = request.Faqs,
Slug = request.Slug,
Title = request.Title
};
await martenRepositoryWrapper.SetRepository<BaseFaq>()
.AddOrUpdateEntityAsync(faq, cancellationToken);
return true;
}
}

View File

@ -0,0 +1,12 @@
namespace Netina.Repository.Handlers.Faqs;
public class DeleteFaqCommandHandler(IMartenRepositoryWrapper martenRepositoryWrapper)
: IRequestHandler<DeleteFaqCommand, bool>
{
public async Task<bool> Handle(DeleteFaqCommand request, CancellationToken cancellationToken)
{
var ent = await martenRepositoryWrapper.SetRepository<BaseFaq>().GetEntityAsync(request.Id, cancellationToken);
await martenRepositoryWrapper.SetRepository<BaseFaq>().RemoveEntityAsync(ent, cancellationToken);
return true;
}
}

View File

@ -0,0 +1,27 @@
namespace Netina.Repository.Handlers.Faqs;
public class GetFaqQueryHandler(IMartenRepositoryWrapper martenRepositoryWrapper)
: IRequestHandler<GetFaqQuery, BaseFaq>
{
public async Task<BaseFaq> Handle(GetFaqQuery request, CancellationToken cancellationToken)
{
if (request.Id is not null)
{
var ent = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(request.Id.Value, cancellationToken);
if (ent == null)
return new BaseFaq();
return ent;
}else if (request.Slug != null)
{
var htmlSlug = request.Slug;
var ent = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f=>f.Slug == htmlSlug, cancellationToken);
if (ent == null)
return new BaseFaq();
return ent;
}
return new BaseFaq();
}
}

View File

@ -0,0 +1,16 @@
namespace Netina.Repository.Handlers.Faqs;
public class GetFaqsQueryHandler(IMartenRepositoryWrapper martenRepositoryWrapper)
: IRequestHandler<GetFaqsQuery, List<BaseFaq>>
{
public async Task<List<BaseFaq>> Handle(GetFaqsQuery request, CancellationToken cancellationToken)
{
var count = request.Count > 0 ? request.Count : 20;
if (count > 50)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Count limit is 50");
var response = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntitiesAsync(request.Page, count, cancellationToken);
response.ForEach(f => { f.Faqs ??= new Dictionary<string, string>(); });
return response;
}
}

View File

@ -0,0 +1,24 @@
namespace Netina.Repository.Handlers.Faqs;
public class UpdateFaqCommandHandler(IMartenRepositoryWrapper martenRepositoryWrapper)
: IRequestHandler<UpdateFaqCommand, bool>
{
public async Task<bool> Handle(UpdateFaqCommand request, CancellationToken cancellationToken)
{
var ent = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(request.Id, cancellationToken);
if (ent == null)
throw new BaseApiException(ApiResultStatusCode.NotFound, "Faq not found");
var newEnt = new BaseFaq
{
Id = ent.Id,
Faqs = request.Faqs,
Slug = request.Slug,
Title = request.Title
};
await martenRepositoryWrapper.SetRepository<BaseFaq>()
.UpdateEntityAsync(newEnt, cancellationToken);
return true;
}
}

View File

@ -1,14 +1,8 @@
namespace Netina.Repository.Handlers.ProductCategories; namespace Netina.Repository.Handlers.ProductCategories;
public class CreateProductCategoryCommandHandler : IRequestHandler<CreateProductCategoryCommand,Guid> public class CreateProductCategoryCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator,IMartenRepositoryWrapper martenRepositoryWrapper)
: IRequestHandler<CreateProductCategoryCommand, Guid>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public CreateProductCategoryCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<Guid> Handle(CreateProductCategoryCommand request, CancellationToken cancellationToken) public async Task<Guid> Handle(CreateProductCategoryCommand request, CancellationToken cancellationToken)
{ {
var ent = ProductCategory.Create(request.Name, request.Description, request.IsMain); var ent = ProductCategory.Create(request.Name, request.Description, request.IsMain);
@ -18,8 +12,25 @@ public class CreateProductCategoryCommandHandler : IRequestHandler<CreateProduct
{ {
ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
} }
_repositoryWrapper.SetRepository<ProductCategory>().Add(ent); repositoryWrapper.SetRepository<ProductCategory>().Add(ent);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
await UpdateFaqAsync(ent, request.Faqs, cancellationToken);
return ent.Id; return ent.Id;
} }
private async Task UpdateFaqAsync(ProductCategory newEnt, Dictionary<string, string> faqs, CancellationToken cancellationToken)
{
var url = newEnt.GetWebSiteUrl();
var oldFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == newEnt.Slug, cancellationToken);
var newFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == url, cancellationToken);
if (oldFaq != null)
await mediator.Send(new DeleteFaqCommand(oldFaq.Id), cancellationToken);
if (newFaq == null)
await mediator.Send(new CreateFaqCommand(faqs, url, newEnt.Name), cancellationToken);
else
await mediator.Send(new UpdateFaqCommand(newFaq.Id, faqs, url, newEnt.Name), cancellationToken);
}
} }

View File

@ -1,24 +1,17 @@
using Microsoft.EntityFrameworkCore; namespace Netina.Repository.Handlers.ProductCategories;
namespace Netina.Repository.Handlers.ProductCategories; public class DeleteProductCategoryCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<DeleteProductCategoryCommand, bool>
public class DeleteProductCategoryCommandHandler : IRequestHandler<DeleteProductCategoryCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public DeleteProductCategoryCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(DeleteProductCategoryCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(DeleteProductCategoryCommand request, CancellationToken cancellationToken)
{ {
var ent = await _repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking var ent = await repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking
.FirstOrDefaultAsync(c => c.Id == request.Id, cancellationToken); .FirstOrDefaultAsync(c => c.Id == request.Id, cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("ProductCategory not found", ApiResultStatusCode.NotFound); throw new AppException("ProductCategory not found", ApiResultStatusCode.NotFound);
_repositoryWrapper.SetRepository<ProductCategory>().Delete(ent); repositoryWrapper.SetRepository<ProductCategory>().Delete(ent);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
return true; return true;
} }
} }

View File

@ -2,21 +2,16 @@
namespace Netina.Repository.Handlers.ProductCategories; namespace Netina.Repository.Handlers.ProductCategories;
public class GetProductCategoriesQueryHandler : IRequestHandler<GetProductCategoriesQuery, List<ProductCategorySDto>> public class GetProductCategoriesQueryHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<GetProductCategoriesQuery, List<ProductCategorySDto>>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public GetProductCategoriesQueryHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<List<ProductCategorySDto>> Handle(GetProductCategoriesQuery request, CancellationToken cancellationToken) public async Task<List<ProductCategorySDto>> Handle(GetProductCategoriesQuery request, CancellationToken cancellationToken)
{ {
IQueryable<ProductCategory> basCategories; IQueryable<ProductCategory> basCategories;
List<ProductCategorySDto> groupCats; List<ProductCategorySDto> groupCats;
if (request.CategoryName != null) if (request.CategoryName != null)
{ {
basCategories = _repositoryWrapper.SetRepository<ProductCategory>() basCategories = repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking .TableNoTracking
.Where(c => c.Name.Trim().Contains(request.CategoryName.Trim())) .Where(c => c.Name.Trim().Contains(request.CategoryName.Trim()))
.OrderByDescending(c => c.CreatedAt); .OrderByDescending(c => c.CreatedAt);
@ -24,7 +19,7 @@ public class GetProductCategoriesQueryHandler : IRequestHandler<GetProductCatego
else else
{ {
basCategories = _repositoryWrapper.SetRepository<ProductCategory>() basCategories = repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking .TableNoTracking
.OrderByDescending(c=>c.CreatedAt); .OrderByDescending(c=>c.CreatedAt);
} }

View File

@ -2,15 +2,9 @@
namespace Netina.Repository.Handlers.ProductCategories; namespace Netina.Repository.Handlers.ProductCategories;
public class GetProductCategoryChildrenQueryHandler : IRequestHandler<GetProductCategoryChildrenQuery,List<Guid>> public class GetProductCategoryChildrenQueryHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<GetProductCategoryChildrenQuery, List<Guid>>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public GetProductCategoryChildrenQueryHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<List<Guid>> Handle(GetProductCategoryChildrenQuery request, CancellationToken cancellationToken) public async Task<List<Guid>> Handle(GetProductCategoryChildrenQuery request, CancellationToken cancellationToken)
{ {
if (request.Id == default) if (request.Id == default)
@ -23,7 +17,7 @@ public class GetProductCategoryChildrenQueryHandler : IRequestHandler<GetProduct
private async Task<List<Guid>> Recursive(Guid id,CancellationToken cancellationToken) private async Task<List<Guid>> Recursive(Guid id,CancellationToken cancellationToken)
{ {
var children = await _repositoryWrapper.SetRepository<ProductCategory>() var children = await repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking .TableNoTracking
.Where(c => c.ParentId == id) .Where(c => c.ParentId == id)
.Select(c => c.Id) .Select(c => c.Id)

View File

@ -2,17 +2,12 @@
namespace Netina.Repository.Handlers.ProductCategories; namespace Netina.Repository.Handlers.ProductCategories;
public class GetProductCategoryQueryHandler : IRequestHandler<GetProductCategoryQuery, ProductCategoryLDto> public class GetProductCategoryQueryHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<GetProductCategoryQuery, ProductCategoryLDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public GetProductCategoryQueryHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<ProductCategoryLDto> Handle(GetProductCategoryQuery request, CancellationToken cancellationToken) public async Task<ProductCategoryLDto> Handle(GetProductCategoryQuery request, CancellationToken cancellationToken)
{ {
var ent = await _repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking var ent = await repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking
.Where(b => b.Id == request.Id) .Where(b => b.Id == request.Id)
.Select(ProductCategoryMapper.ProjectToLDto) .Select(ProductCategoryMapper.ProjectToLDto)
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);

View File

@ -1,18 +1,11 @@
using Microsoft.EntityFrameworkCore; namespace Netina.Repository.Handlers.ProductCategories;
namespace Netina.Repository.Handlers.ProductCategories; public class UpdateProductCategoryCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator,IMartenRepositoryWrapper martenRepositoryWrapper)
: IRequestHandler<UpdateProductCategoryCommand, bool>
public class UpdateProductCategoryCommandHandler : IRequestHandler<UpdateProductCategoryCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public UpdateProductCategoryCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(UpdateProductCategoryCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(UpdateProductCategoryCommand request, CancellationToken cancellationToken)
{ {
var ent = await _repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking var ent = await repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking
.FirstOrDefaultAsync(c => c.Id == request.Id, cancellationToken); .FirstOrDefaultAsync(c => c.Id == request.Id, cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("ProductCategory not found", ApiResultStatusCode.NotFound); throw new AppException("ProductCategory not found", ApiResultStatusCode.NotFound);
@ -25,22 +18,39 @@ public class UpdateProductCategoryCommandHandler : IRequestHandler<UpdateProduct
newEnt.SetParent(request.ParentId); newEnt.SetParent(request.ParentId);
var dbFiles = await _repositoryWrapper.SetRepository<ProductCategoryStorageFile>().TableNoTracking var dbFiles = await repositoryWrapper.SetRepository<ProductCategoryStorageFile>().TableNoTracking
.Where(s => s.CategoryId == newEnt.Id).ToListAsync(cancellationToken); .Where(s => s.CategoryId == newEnt.Id).ToListAsync(cancellationToken);
foreach (var dbFile in dbFiles) foreach (var dbFile in dbFiles)
{ {
if (request.Files.FirstOrDefault(s => s.Id == dbFile.Id) == null) if (request.Files.FirstOrDefault(s => s.Id == dbFile.Id) == null)
{ {
_repositoryWrapper.SetRepository<ProductCategoryStorageFile>().Delete(dbFile); repositoryWrapper.SetRepository<ProductCategoryStorageFile>().Delete(dbFile);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
} }
foreach (var file in request.Files.Where(f => f.Id == default)) foreach (var file in request.Files.Where(f => f.Id == default))
{ {
newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
} }
_repositoryWrapper.SetRepository<ProductCategory>().Update(newEnt); repositoryWrapper.SetRepository<ProductCategory>().Update(newEnt);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
await UpdateFaqAsync(newEnt, request.Faqs, cancellationToken);
return true; return true;
} }
private async Task UpdateFaqAsync(ProductCategory newEnt, Dictionary<string, string> faqs, CancellationToken cancellationToken)
{
var url = newEnt.GetWebSiteUrl();
var oldFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == newEnt.Slug, cancellationToken);
var newFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == url, cancellationToken);
if (oldFaq != null)
await mediator.Send(new DeleteFaqCommand(oldFaq.Id), cancellationToken);
if (newFaq == null)
await mediator.Send(new CreateFaqCommand(faqs, url, newEnt.Name), cancellationToken);
else
await mediator.Send(new UpdateFaqCommand(newFaq.Id, faqs, url, newEnt.Name), cancellationToken);
}
} }

View File

@ -1,16 +1,8 @@
namespace Netina.Repository.Handlers.Products; namespace Netina.Repository.Handlers.Products;
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, ProductLDto> public class CreateProductCommandHandler(IRepositoryWrapper repositoryWrapper,IMartenRepositoryWrapper martenRepositoryWrapper, IMediator mediator)
: IRequestHandler<CreateProductCommand, ProductLDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public CreateProductCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<ProductLDto> Handle(CreateProductCommand request, CancellationToken cancellationToken) public async Task<ProductLDto> Handle(CreateProductCommand request, CancellationToken cancellationToken)
{ {
@ -34,8 +26,8 @@ public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand,
_repositoryWrapper.SetRepository<Product>().Add(ent); repositoryWrapper.SetRepository<Product>().Add(ent);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
if (request.IsSpecialOffer) if (request.IsSpecialOffer)
{ {
@ -48,15 +40,34 @@ public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand,
if (request.SpecialOffer.Id == default) if (request.SpecialOffer.Id == default)
{ {
var discountRequest = discount.Adapt<CreateDiscountCommand>(); var discountRequest = discount.Adapt<CreateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken); await mediator.Send(discountRequest, cancellationToken);
} }
else else
{ {
var discountRequest = discount.Adapt<UpdateDiscountCommand>(); var discountRequest = discount.Adapt<UpdateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken); await mediator.Send(discountRequest, cancellationToken);
} }
} }
await UpdateFaqAsync(ent, request.Faqs, cancellationToken);
return ent.AdaptToLDto(); return ent.AdaptToLDto();
} }
private async Task UpdateFaqAsync(Product newEnt, Dictionary<string, string> faqs, CancellationToken cancellationToken)
{
var url = newEnt.GetWebSiteUrl();
var oldFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == newEnt.Slug, cancellationToken);
var newFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == url, cancellationToken);
if (oldFaq != null)
await mediator.Send(new DeleteFaqCommand(oldFaq.Id), cancellationToken);
if (newFaq == null)
await mediator.Send(new CreateFaqCommand(faqs, url, newEnt.EnglishName), cancellationToken);
else
await mediator.Send(new UpdateFaqCommand(newFaq.Id, faqs, url, newEnt.EnglishName), cancellationToken);
}
} }

View File

@ -2,23 +2,18 @@
namespace Netina.Repository.Handlers.Products; namespace Netina.Repository.Handlers.Products;
public class DeleteProductCommandHandler : IRequestHandler<DeleteProductCommand, bool> public class DeleteProductCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<DeleteProductCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public DeleteProductCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(DeleteProductCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(DeleteProductCommand request, CancellationToken cancellationToken)
{ {
var ent = await _repositoryWrapper.SetRepository<Product>().TableNoTracking var ent = await repositoryWrapper.SetRepository<Product>().TableNoTracking
.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken); .FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Product NotFound", ApiResultStatusCode.NotFound); throw new AppException("Product NotFound", ApiResultStatusCode.NotFound);
_repositoryWrapper.SetRepository<Product>().Delete(ent); repositoryWrapper.SetRepository<Product>().Delete(ent);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
return true; return true;
} }
} }

View File

@ -1,6 +1,4 @@
using Microsoft.EntityFrameworkCore; namespace Netina.Repository.Handlers.Products;
namespace Netina.Repository.Handlers.Products;
public class GetProductQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator) public class GetProductQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<GetProductQuery, GetProductResponseDto> : IRequestHandler<GetProductQuery, GetProductResponseDto>
@ -13,7 +11,7 @@ public class GetProductQueryHandler(IRepositoryWrapper repositoryWrapper, IMedia
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Product not found", ApiResultStatusCode.NotFound); throw new BaseApiException(ApiResultStatusCode.NotFound,"Product not found");
await mediator.Send(new CalculateProductDiscountCommand(ent), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(ent), cancellationToken);

View File

@ -2,25 +2,19 @@
namespace Netina.Repository.Handlers.Products; namespace Netina.Repository.Handlers.Products;
public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, GetProductsResponseDto> public class GetProductsQueryHandler(
IRepositoryWrapper repositoryWrapper,
IMediator mediator,
ICurrentUserService currentUserService)
: IRequestHandler<GetProductsQuery, GetProductsResponseDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
private readonly ICurrentUserService _currentUserService;
public GetProductsQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator, ICurrentUserService currentUserService)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
_currentUserService = currentUserService;
}
public async Task<GetProductsResponseDto> Handle(GetProductsQuery request, CancellationToken cancellationToken) public async Task<GetProductsResponseDto> Handle(GetProductsQuery request, CancellationToken cancellationToken)
{ {
var response = new GetProductsResponseDto(); var response = new GetProductsResponseDto();
var products = _repositoryWrapper.SetRepository<Product>().TableNoTracking; var products = repositoryWrapper.SetRepository<Product>().TableNoTracking;
if (_currentUserService.JwtToken == null) if (currentUserService.JwtToken == null)
products = products.Where(p => p.BeDisplayed); products = products.Where(p => p.BeDisplayed);
var roleClaim = _currentUserService.JwtToken?.Claims.FirstOrDefault(c => c.Type == "role"); var roleClaim = currentUserService.JwtToken?.Claims.FirstOrDefault(c => c.Type == "role");
if (roleClaim != null && roleClaim.Value.Contains("Customer")) if (roleClaim != null && roleClaim.Value.Contains("Customer"))
products = products.Where(p => p.BeDisplayed); products = products.Where(p => p.BeDisplayed);
@ -46,7 +40,7 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, GetProd
if (request.CategoryId != default) if (request.CategoryId != default)
{ {
var cats = await _mediator.Send(new GetProductCategoryChildrenQuery(request.CategoryId), cancellationToken); var cats = await mediator.Send(new GetProductCategoryChildrenQuery(request.CategoryId), cancellationToken);
products = products.Where(p => cats.Contains(p.CategoryId)); products = products.Where(p => cats.Contains(p.CategoryId));
} }
if (request.BrandIds is { Length: > 0 }) if (request.BrandIds is { Length: > 0 })
@ -61,7 +55,7 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, GetProd
{ {
if (request.SpecialOffer.Value) if (request.SpecialOffer.Value)
{ {
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>() var productDiscount = await repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking .TableNoTracking
.Where(d => d.HasCode == false && d.IsSpecialOffer && d.ExpireDate.Date >= DateTime.Today.Date) .Where(d => d.HasCode == false && d.IsSpecialOffer && d.ExpireDate.Date >= DateTime.Today.Date)
.OrderByDescending(d => d.CreatedAt) .OrderByDescending(d => d.CreatedAt)
@ -92,7 +86,7 @@ public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, GetProd
foreach (var productSDto in productSDtos) foreach (var productSDto in productSDtos)
{ {
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
} }
response.Products = productSDtos; response.Products = productSDtos;

View File

@ -1,8 +1,6 @@
using Microsoft.EntityFrameworkCore; namespace Netina.Repository.Handlers.Products;
namespace Netina.Repository.Handlers.Products; public class UpdateProductCommandHandler(IRepositoryWrapper repositoryWrapper,IMartenRepositoryWrapper martenRepositoryWrapper, IMediator mediator)
public class UpdateProductCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<UpdateProductCommand, bool> : IRequestHandler<UpdateProductCommand, bool>
{ {
public async Task<bool> Handle(UpdateProductCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(UpdateProductCommand request, CancellationToken cancellationToken)
@ -82,7 +80,34 @@ public class UpdateProductCommandHandler(IRepositoryWrapper repositoryWrapper, I
await mediator.Send(discountRequest, cancellationToken); await mediator.Send(discountRequest, cancellationToken);
} }
} }
else
{
var discount = await repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.ProductId == newEnt.Id && d.IsSpecialOffer, cancellationToken);
if (discount != null)
await mediator.Send(new DeleteDiscountCommand(discount.Id), cancellationToken);
}
await UpdateFaqAsync(newEnt, request.Faqs, cancellationToken);
return true; return true;
} }
private async Task UpdateFaqAsync(Product newEnt, Dictionary<string, string> faqs, CancellationToken cancellationToken)
{
var url = newEnt.GetWebSiteUrl();
var oldFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == newEnt.Slug, cancellationToken);
var newFaq = await martenRepositoryWrapper.SetRepository<BaseFaq>()
.GetEntityAsync(f => f.Slug == url, cancellationToken);
if (oldFaq != null)
await mediator.Send(new DeleteFaqCommand(oldFaq.Id), cancellationToken);
if (newFaq == null)
await mediator.Send(new CreateFaqCommand(faqs, url, newEnt.EnglishName), cancellationToken);
else
await mediator.Send(new UpdateFaqCommand(newFaq.Id, faqs, url, newEnt.EnglishName), cancellationToken);
}
} }

View File

@ -45,6 +45,7 @@
<Using Include="MediatR" /> <Using Include="MediatR" />
<Using Include="Microsoft.AspNetCore.Builder" /> <Using Include="Microsoft.AspNetCore.Builder" />
<Using Include="Microsoft.AspNetCore.Identity" /> <Using Include="Microsoft.AspNetCore.Identity" />
<Using Include="Microsoft.EntityFrameworkCore" />
<Using Include="Microsoft.Extensions.DependencyInjection" /> <Using Include="Microsoft.Extensions.DependencyInjection" />
<Using Include="Microsoft.Extensions.Logging" /> <Using Include="Microsoft.Extensions.Logging" />
<Using Include="Microsoft.Extensions.Options" /> <Using Include="Microsoft.Extensions.Options" />
@ -63,7 +64,9 @@
<Using Include="Netina.Domain.Entities.Products" /> <Using Include="Netina.Domain.Entities.Products" />
<Using Include="Netina.Domain.Entities.Users" /> <Using Include="Netina.Domain.Entities.Users" />
<Using Include="Netina.Domain.Enums" /> <Using Include="Netina.Domain.Enums" />
<Using Include="Netina.Domain.Extensions" />
<Using Include="Netina.Domain.Mappers" /> <Using Include="Netina.Domain.Mappers" />
<Using Include="Netina.Domain.MartenEntities.Faqs" />
<Using Include="Netina.Domain.Models.Claims" /> <Using Include="Netina.Domain.Models.Claims" />
<Using Include="Netina.Domain.Models.Settings" /> <Using Include="Netina.Domain.Models.Settings" />
<Using Include="Netina.Repository.Abstracts" /> <Using Include="Netina.Repository.Abstracts" />
@ -71,6 +74,7 @@
<Using Include="Netina.Repository.Models" /> <Using Include="Netina.Repository.Models" />
<Using Include="Netina.Repository.Repositories.Base" /> <Using Include="Netina.Repository.Repositories.Base" />
<Using Include="Netina.Repository.Repositories.Base.Contracts" /> <Using Include="Netina.Repository.Repositories.Base.Contracts" />
<Using Include="Netina.Repository.Repositories.Marten" />
<Using Include="Netina.Repository.Services.Abstracts" /> <Using Include="Netina.Repository.Services.Abstracts" />
<Using Include="Pluralize.NET" /> <Using Include="Pluralize.NET" />
<Using Include="System.Diagnostics" /> <Using Include="System.Diagnostics" />

View File

@ -6,10 +6,13 @@ public interface IMartenRepository<TMartenEntity> : IScopedDependency where TMar
{ {
Task<List<TMartenEntity>> GetEntitiesAsync(CancellationToken cancellation = default); Task<List<TMartenEntity>> GetEntitiesAsync(CancellationToken cancellation = default);
Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default); Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default);
Task<List<TMartenEntity>> GetEntitiesAsync(int page, int count, CancellationToken cancellation);
Task<List<TMartenEntity>> GetEntitiesAsync(Expression<Func<TMartenEntity, bool>> expression, int page, int count, CancellationToken cancellation);
Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation = default); Task<TMartenEntity> GetEntityAsync(Guid id, CancellationToken cancellation = default);
Task<TMartenEntity?> GetEntityAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default); Task<TMartenEntity?> GetEntityAsync(Expression<Func<TMartenEntity, bool>> expression, CancellationToken cancellation = default);
Task AddOrUpdateEntityAsync(TMartenEntity entity, CancellationToken cancellation = default); Task AddOrUpdateEntityAsync(TMartenEntity entity, CancellationToken cancellation = default);
Task UpdateEntityAsync(TMartenEntity entity, CancellationToken cancellation = default);
Task RemoveEntityAsync(TMartenEntity entity, CancellationToken cancellation = default); Task RemoveEntityAsync(TMartenEntity entity, CancellationToken cancellation = default);
} }

View File

@ -1,44 +1,25 @@
using Microsoft.EntityFrameworkCore; namespace Netina.Repository.Services;
namespace Netina.Repository.Services; public class DbInitializerService(
public class DbInitializerService : IDbInitializerService
{
private readonly IOptionsSnapshot<SiteSettings> _adminUserSeedOptions;
private readonly ApplicationContext _context;
private readonly ILogger<DbInitializerService> _logger;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly UserManager<ApplicationUser> _userManager;
public DbInitializerService(
ApplicationContext context, ApplicationContext context,
RoleManager<ApplicationRole> roleManager, RoleManager<ApplicationRole> roleManager,
UserManager<ApplicationUser> userManager, UserManager<ApplicationUser> userManager,
IOptionsSnapshot<SiteSettings> adminUserSeedOptions, IOptionsSnapshot<SiteSettings> adminUserSeedOptions,
ILogger<DbInitializerService> logger, ILogger<DbInitializerService> logger,
IRepositoryWrapper repositoryWrapper) IRepositoryWrapper repositoryWrapper)
: IDbInitializerService
{ {
_context = context;
_roleManager = roleManager;
_userManager = userManager;
_adminUserSeedOptions = adminUserSeedOptions;
_logger = logger;
_repositoryWrapper = repositoryWrapper;
}
public void Initialize() public void Initialize()
{ {
try try
{ {
_context.Database.Migrate(); context.Database.Migrate();
_context.Database.ExecuteSqlRaw("CREATE EXTENSION IF NOT EXISTS pg_trgm"); context.Database.ExecuteSqlRaw("CREATE EXTENSION IF NOT EXISTS pg_trgm");
_logger.LogInformation("Migration SUCCESS !!!!"); logger.LogInformation("Migration SUCCESS !!!!");
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(e, e.Message); logger.LogError(e, e.Message);
} }
} }
@ -47,9 +28,9 @@ public class DbInitializerService : IDbInitializerService
try try
{ {
await SeedRoles(); await SeedRoles();
var seedAdmin = _adminUserSeedOptions.Value.UserSetting; var seedAdmin = adminUserSeedOptions.Value.UserSetting;
var manager = _adminUserSeedOptions.Value.Manager; var manager = adminUserSeedOptions.Value.Manager;
var user = await _userManager.FindByNameAsync(seedAdmin.Username); var user = await userManager.FindByNameAsync(seedAdmin.Username);
if (user == null) if (user == null)
{ {
var adminUser = new ApplicationUser var adminUser = new ApplicationUser
@ -65,17 +46,17 @@ public class DbInitializerService : IDbInitializerService
PhoneNumber = seedAdmin.Phone, PhoneNumber = seedAdmin.Phone,
BirthDate = DateTime.Now.AddYears(-23) BirthDate = DateTime.Now.AddYears(-23)
}; };
var adminUserResult = await _userManager.CreateAsync(adminUser, seedAdmin.Password); var adminUserResult = await userManager.CreateAsync(adminUser, seedAdmin.Password);
_repositoryWrapper.SetRepository<Manager>() repositoryWrapper.SetRepository<Manager>()
.Add(new Manager .Add(new Manager
{ {
UserId = adminUser.Id UserId = adminUser.Id
}); });
await _repositoryWrapper.SaveChangesAsync(default); await repositoryWrapper.SaveChangesAsync(default);
if (adminUserResult.Succeeded) await _userManager.AddToRoleAsync(adminUser, seedAdmin.RoleName); if (adminUserResult.Succeeded) await userManager.AddToRoleAsync(adminUser, seedAdmin.RoleName);
} }
var mahanUser = await _userManager.FindByNameAsync(manager.Username); var mahanUser = await userManager.FindByNameAsync(manager.Username);
if (mahanUser == null) if (mahanUser == null)
{ {
mahanUser = new ApplicationUser mahanUser = new ApplicationUser
@ -91,14 +72,14 @@ public class DbInitializerService : IDbInitializerService
PhoneNumber = manager.Phone, PhoneNumber = manager.Phone,
BirthDate = DateTime.Now.AddYears(-23) BirthDate = DateTime.Now.AddYears(-23)
}; };
var adminUserResult = await _userManager.CreateAsync(mahanUser, seedAdmin.Password); var adminUserResult = await userManager.CreateAsync(mahanUser, seedAdmin.Password);
_repositoryWrapper.SetRepository<Manager>() repositoryWrapper.SetRepository<Manager>()
.Add(new Manager .Add(new Manager
{ {
UserId = mahanUser.Id UserId = mahanUser.Id
}); });
await _repositoryWrapper.SaveChangesAsync(default); await repositoryWrapper.SaveChangesAsync(default);
if (adminUserResult.Succeeded) await _userManager.AddToRoleAsync(mahanUser, "Manager"); if (adminUserResult.Succeeded) await userManager.AddToRoleAsync(mahanUser, "Manager");
} }
} }
catch (Exception e) catch (Exception e)
@ -110,8 +91,8 @@ public class DbInitializerService : IDbInitializerService
public async Task SeedRoles() public async Task SeedRoles()
{ {
var seedAdmin = _adminUserSeedOptions.Value.UserSetting; var seedAdmin = adminUserSeedOptions.Value.UserSetting;
var rootRole = await _roleManager.FindByNameAsync(seedAdmin.RoleName); var rootRole = await roleManager.FindByNameAsync(seedAdmin.RoleName);
if (rootRole == null) if (rootRole == null)
{ {
rootRole = new ApplicationRole rootRole = new ApplicationRole
@ -120,21 +101,21 @@ public class DbInitializerService : IDbInitializerService
EnglishName = seedAdmin.RoleName, EnglishName = seedAdmin.RoleName,
Description = "root admin role" Description = "root admin role"
}; };
var adminRoleResult = await _roleManager.CreateAsync(rootRole); var adminRoleResult = await roleManager.CreateAsync(rootRole);
foreach (var claim in ApplicationClaims.AllClaims) foreach (var claim in ApplicationClaims.AllClaims)
await _roleManager.AddClaimAsync(rootRole, claim); await roleManager.AddClaimAsync(rootRole, claim);
} }
else else
{ {
foreach (var claim in ApplicationClaims.AllClaims) foreach (var claim in ApplicationClaims.AllClaims)
{ {
var claims = await _roleManager.GetClaimsAsync(rootRole); var claims = await roleManager.GetClaimsAsync(rootRole);
if (claims.FirstOrDefault(c => c.Value == claim.Value) == null) if (claims.FirstOrDefault(c => c.Value == claim.Value) == null)
await _roleManager.AddClaimAsync(rootRole, claim); await roleManager.AddClaimAsync(rootRole, claim);
} }
} }
var managerRole = await _roleManager.FindByNameAsync("Manager"); var managerRole = await roleManager.FindByNameAsync("Manager");
if (managerRole == null) if (managerRole == null)
{ {
managerRole = new ApplicationRole managerRole = new ApplicationRole
@ -144,21 +125,21 @@ public class DbInitializerService : IDbInitializerService
PersianName = "مدیریتـــ", PersianName = "مدیریتـــ",
Description = "admin role" Description = "admin role"
}; };
var adminRoleResult = await _roleManager.CreateAsync(managerRole); var adminRoleResult = await roleManager.CreateAsync(managerRole);
foreach (var claim in ApplicationClaims.AllClaims) foreach (var claim in ApplicationClaims.AllClaims)
await _roleManager.AddClaimAsync(managerRole, claim); await roleManager.AddClaimAsync(managerRole, claim);
} }
else else
{ {
foreach (var claim in ApplicationClaims.AllClaims) foreach (var claim in ApplicationClaims.AllClaims)
{ {
var claims = await _roleManager.GetClaimsAsync(managerRole); var claims = await roleManager.GetClaimsAsync(managerRole);
if (claims.FirstOrDefault(c => c.Value == claim.Value) == null) if (claims.FirstOrDefault(c => c.Value == claim.Value) == null)
await _roleManager.AddClaimAsync(managerRole, claim); await roleManager.AddClaimAsync(managerRole, claim);
} }
} }
var customerRole = await _roleManager.FindByNameAsync("Customer"); var customerRole = await roleManager.FindByNameAsync("Customer");
if (customerRole == null) if (customerRole == null)
{ {
customerRole = new ApplicationRole customerRole = new ApplicationRole
@ -168,17 +149,17 @@ public class DbInitializerService : IDbInitializerService
EnglishName = "Customer", EnglishName = "Customer",
}; };
var customerRoleResult = await _roleManager.CreateAsync(customerRole); var customerRoleResult = await roleManager.CreateAsync(customerRole);
foreach (var claim in ApplicationClaims.CustomerClaims) foreach (var claim in ApplicationClaims.CustomerClaims)
await _roleManager.AddClaimAsync(customerRole, claim); await roleManager.AddClaimAsync(customerRole, claim);
} }
else else
{ {
foreach (var claim in ApplicationClaims.CustomerClaims) foreach (var claim in ApplicationClaims.CustomerClaims)
{ {
var claims = await _roleManager.GetClaimsAsync(customerRole); var claims = await roleManager.GetClaimsAsync(customerRole);
if (claims.FirstOrDefault(c => c.Value == claim.Value) == null) if (claims.FirstOrDefault(c => c.Value == claim.Value) == null)
await _roleManager.AddClaimAsync(customerRole, claim); await roleManager.AddClaimAsync(customerRole, claim);
} }
} }
} }