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

@ -1,24 +1,26 @@
namespace Netina.Domain.CommandQueries.Commands; namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateProductCommand( public sealed record CreateProductCommand(
string PersianName, string PersianName,
string EnglishName, string EnglishName,
string Summery, string Summery,
string ExpertCheck, string ExpertCheck,
string Tags, string Tags,
string Warranty, string Warranty,
bool BeDisplayed, bool BeDisplayed,
double Cost, double Cost,
double PackingCost, double PackingCost,
int Stock, int Stock,
bool HasExpressDelivery, bool HasExpressDelivery,
int MaxOrderCount, int MaxOrderCount,
bool IsSpecialOffer, bool IsSpecialOffer,
Guid BrandId, 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,10 +41,13 @@ 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(
ApplicationContext context,
RoleManager<ApplicationRole> roleManager,
public class DbInitializerService : IDbInitializerService UserManager<ApplicationUser> userManager,
IOptionsSnapshot<SiteSettings> adminUserSeedOptions,
ILogger<DbInitializerService> logger,
IRepositoryWrapper repositoryWrapper)
: 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,
RoleManager<ApplicationRole> roleManager,
UserManager<ApplicationUser> userManager,
IOptionsSnapshot<SiteSettings> adminUserSeedOptions,
ILogger<DbInitializerService> logger,
IRepositoryWrapper repositoryWrapper)
{
_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);
} }
} }
} }