Compare commits

..

No commits in common. "master" and "release" have entirely different histories.

310 changed files with 3930 additions and 29005 deletions

View File

@ -1 +1 @@
1.10.21.36
1.0.3.3

View File

@ -1,8 +1,8 @@
{
"ConnectionStrings": {
"PostgresServer": "Host=185.220.227.29;Username=vesmmehAgent;Password=g05CTjK358Vx3Eoc9satsWyVwo+15UmsA2dnCrZRUYh1pLTe;Database=NetinaShopDB;Application Name=NetinaShopApi",
"Postgres": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopDB",
"MartenDB": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopMartenDB"
"PostgresServer": "Host=185.220.227.107;Username=vesmmehAgent;Password=g05CTjK358Vx3Eoc9satsWyVwo+15UmsA2dnCrZRUYh1pLTe;Database=NetinaShopDB;Application Name=NetinaShopApi",
"Postgres": "Host=pg-0,pg-1;Username=igarsonAgent;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopDB;Load Balance Hosts=true;Target Session Attributes=primary;Application Name=iGLS",
"MartenDB": "Host=pg-0,pg-1;Username=igarsonAgent;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopMartenDB;"
},
"Logging": {
"LogLevel": {

View File

@ -11,26 +11,23 @@ public class BlogCategoryController : ICarterModule
.MapGroup($"api/blog/category");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get BlogCategories")
.WithDisplayName("GetAllCategories")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get BlogCategory")
.WithDisplayName("GetBlogCategory")
.HasApiVersion(1.0);
group.MapPost("", Post)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageBlogs))
.WithDisplayName("Create BlogCategory")
.HasApiVersion(1.0);
group.MapPut("", Put)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Update BlogCategory")
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Delete BlogCategory")
.HasApiVersion(1.0);
}

View File

@ -1,7 +1,8 @@
using Microsoft.Extensions.Options;
using Marten.Events;
using Microsoft.Extensions.Options;
using Netina.Domain.Entities.Blogs;
using Netina.Domain.Entities.Products;
using System.Web;
using Netina.Repository.Abstracts;
namespace Netina.Api.Controllers;
@ -14,48 +15,37 @@ public class BlogController : ICarterModule
.MapGroup($"api/blog");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Blogs")
.WithDisplayName("GetAllBlogs")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Blog")
.WithDisplayName("GetBlog")
.HasApiVersion(1.0);
group.MapPost("", Post)
.RequireAuthorization(builder =>
builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()
.RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Create Blog")
.HasApiVersion(1.0);
group.MapPut("", Put)
.RequireAuthorization(builder =>
builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()
.RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Update Blog")
.HasApiVersion(1.0);
group.MapGet("{blogId}/comment", GetBlogCommentsAsync)
.WithDisplayName("Get Blog Comments")
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.RequireAuthorization(builder =>
builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()
.RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Delete Blog")
.HasApiVersion(1.0);
group.MapGet("/newlink", GetBlogNewLinkAsync)
.WithDisplayName("Get Blog NewLink")
.WithDisplayName("GetBlogNewLink")
.HasApiVersion(1.0);
}
private async Task<IResult> GetBlogCommentsAsync([FromQuery] int page, [FromQuery] int count, [FromRoute] Guid blogId, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page, count, null, blogId), cancellationToken));
private async Task<IResult> GetBlogNewLinkAsync([FromQuery]string slug,IRepositoryWrapper repositoryWrapper,IOptionsSnapshot<SiteSettings> snapshot,CancellationToken cancellationToken)
{
var htmlSlug = HttpUtility.UrlEncode(slug);
@ -86,19 +76,13 @@ public class BlogController : ICarterModule
}
// POST:Create Entity
public async Task<IResult> Post([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService, CancellationToken cancellationToken)
public async Task<IResult> Post([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
var ent = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested,dto.CategoryId, userId);
var ent = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested,dto.CategoryId);
foreach (var file in dto.Files)
{
ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
}
foreach (var item in dto.MetaTags)
ent.AddMetaTag(item.Type, item.Value);
repositoryWrapper.SetRepository<Blog>().Add(ent);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
@ -106,17 +90,13 @@ public class BlogController : ICarterModule
}
// PUT:Update Entity
public async Task<IResult> Put([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService, CancellationToken cancellationToken)
public async Task<IResult> Put([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken)
{
var ent = await repositoryWrapper.SetRepository<Blog>().TableNoTracking
.FirstOrDefaultAsync(b => b.Id == dto.Id, cancellationToken);
if (ent == null)
throw new AppException("Blog not found");
if (currentUserService.UserId == null)
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
throw new BaseApiException(ApiResultStatusCode.UnAuthorized, "User id is wrong");
var newEnt = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested, dto.CategoryId, userId);
var newEnt = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested, dto.CategoryId);
newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy;
@ -134,21 +114,6 @@ public class BlogController : ICarterModule
foreach (var file in dto.Files.Where(f => f.Id == default))
newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType);
//Check MetaTags
var dbMetaTags = await repositoryWrapper.SetRepository<BlogMetaTag>()
.TableNoTracking
.Where(f => f.BlogId == ent.Id)
.ToListAsync(cancellationToken);
foreach (var feature in dbMetaTags.Where(feature => dto.MetaTags.Any(f => f.Type == feature.Type) == false))
{
repositoryWrapper.SetRepository<BlogMetaTag>()
.Delete(feature);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
}
foreach (var item in dto.MetaTags.Where(f => dbMetaTags.Any(dbf => dbf.Type == f.Type) == false))
newEnt.AddMetaTag(item.Type, item.Value);
repositoryWrapper.SetRepository<Blog>().Update(newEnt);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
return TypedResults.Ok();

View File

@ -11,26 +11,23 @@ public class BrandController : ICarterModule
.MapGroup($"api/brand");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Brands")
.WithDisplayName("GetAllBrands")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Brand")
.WithDisplayName("GetBlogBrand")
.HasApiVersion(1.0);
group.MapPost("", Post)
.HasApiVersion(1.0)
.WithDisplayName("Create Brand")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands));
group.MapPut("", Put)
.HasApiVersion(1.0)
.WithDisplayName("Update Brand")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands));
group.MapDelete("{id}", Delete)
.HasApiVersion(1.0)
.WithDisplayName("Delete Brand")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBrands));
}

View File

@ -1,17 +0,0 @@
namespace Netina.Api.Controllers;
public class CustomerController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Customer").MapGroup("api/customer")
.RequireAuthorization(builder=>builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetCustomersAsync)
.WithDisplayName("Get Customers")
.HasApiVersion(1.0);
}
private async Task<IResult> GetCustomersAsync([FromQuery] int page, [FromQuery] int? count, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(true);
}

View File

@ -15,6 +15,8 @@ public class DashboardController : ICarterModule
group.MapGet("orders", GetOrdersDashboardAsync)
.WithDisplayName("Get Orders Dashboard")
.HasApiVersion(1.0);
}
private async Task<IResult> GetOrdersDashboardAsync([FromServices] IDashboardService dashboardService, CancellationToken cancellationToken)

View File

@ -9,28 +9,25 @@ public class DiscountController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Discounts")
.WithDisplayName("GetAllDiscounts")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Discount")
.WithDisplayName("GetDiscount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts))
.HasApiVersion(1.0);
group.MapPost("", Post)
.HasApiVersion(1.0)
.WithDisplayName("Create Discount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
group.MapPut("", Put)
.HasApiVersion(1.0)
.WithDisplayName("Update Discount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
group.MapDelete("{id}", Delete)
.HasApiVersion(1.0)
.WithDisplayName("Delete Discount")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
}

View File

@ -11,7 +11,7 @@ public class DistrictController : ICarterModule
.WithDisplayName("Get Cities")
.HasApiVersion(1.0);
group.MapGet("province", GetProvincesAsync)
.WithDisplayName("Get Provinces")
.WithDisplayName("Get Cities")
.HasApiVersion(1.0);
}

View File

@ -1,56 +0,0 @@
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("Get Faq By Slug")
.WithDescription("Get faq by slug , you have to send page slug")
.HasApiVersion(1.0);
group.MapGet("", GetFaqsAsync)
.WithDisplayName("Get Faqs")
.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 Faq")
.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("Delete Faq")
.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

@ -1,5 +1,4 @@
using Netina.Domain.Dtos.ResponseDtos;
using Netina.Domain.Enums;
using Netina.Domain.Enums;
namespace Netina.Api.Controllers;
@ -11,57 +10,14 @@ public class FileController : ICarterModule
.MapGroup("api/file");
group.MapGet("", GetFilesAsync)
.WithDisplayName("Get Files")
.WithDisplayName("GetFilesAsync")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFiles, ApplicationPermission.ViewFiles))
.HasApiVersion(1.0);
group.MapPost("", UploadFileAsync)
.WithDisplayName("Upload File")
.WithDisplayName("UploadFileAsync")
.HasApiVersion(1.0);
group.MapPost("/ckeditor", UploadCkEditorFileAsync)
.WithDisplayName("Upload CkEditor File")
.AllowAnonymous()
.DisableAntiforgery()
.HasApiVersion(1.0);
}
public async Task<IResult> UploadCkEditorFileAsync(IFormFile upload, [FromServices] IHttpContextAccessor httpContextAccessor, [FromServices] IStorageService storageService, IUploadFileService uploadFileService, CancellationToken cancellationToken)
{
try
{
if (httpContextAccessor.HttpContext?.Request?.Headers is { } dictionary && dictionary.TryGetValue("Authorization", out StringValues value))
{
if (value.ToString() != "xuwp4KzU1/YBoevpzgH0cz8+zLKQ+EOaYXeo4JtRxmVIuN7Hqxz97oQ398tNX68+")
throw new Exception("ارسال فایل از طرف شما معتبر نمی باشد");
using var stream = new MemoryStream();
await upload.CopyToAsync(stream, cancellationToken);
var uploadRequest = new FileUploadRequest
{
FileName = upload.FileName,
ContentType = upload.ContentType,
FileUploadType = FileUploadType.Image,
StringBaseFile = Convert.ToBase64String(stream.ToArray())
};
var fileUrl = await uploadFileService.UploadImageAsync(uploadRequest);
return TypedResults.Ok(new CkEditorFileUploadResponseDto { url = fileUrl.FileUrl });
}
throw new Exception("ارسال فایل از طرف شما معتبر نمی باشد");
}
catch (Exception e)
{
var errorMessage = new
{
message = e.Message
};
var errorResponse = new
{
error = errorMessage
};
return TypedResults.BadRequest(errorResponse);
}
}
public async Task<IResult> GetFilesAsync([FromQuery]StorageFileType? fileType,[FromServices] IStorageService storageService, CancellationToken cancellationToken)

View File

@ -9,13 +9,13 @@ public class HealthController : ICarterModule
var group = app.NewVersionedApi("Health")
.MapGroup("health");
group.MapGet("", GetHealth)
.WithDisplayName("Get Health")
.WithDisplayName("GetHealth")
.HasApiVersion(1.0);
}
public async Task<IResult> GetHealth([FromServices]ISiteMapService siteMapService)
{
await siteMapService.CreateSiteMapAsync();
//await siteMapService.CreateSiteMapAsync();
var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString();
var check = new HealthCheck
{

View File

@ -11,20 +11,20 @@ public class MarketerController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetMarketersAsync)
.WithDisplayName("Get Marketers")
.WithDisplayName("GetAllMarketers")
.RequireAuthorization(builder=>builder.RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageUsers , ApplicationPermission.ViewUsers))
.HasApiVersion(1.0);
group.MapGet("profile", GetMarketerProfileAsync)
.WithDisplayName("Get Marketer Profile")
.WithDisplayName("GetAllMarketers")
.HasApiVersion(1.0);
group.MapPost("signup", SignUpMarketerAsync)
.WithDisplayName("SignUp Marketer")
.WithDisplayName("SignUpMarketer")
.HasApiVersion(1.0);
group.MapGet("signup/contract", GetSignUpMarketerContractAsync)
.WithDisplayName("Get Marketer Contract")
.WithDisplayName("SignUpMarketerContract")
.HasApiVersion(1.0);
}

View File

@ -7,7 +7,7 @@ public class NewsletterMemberController : ICarterModule
var group = app.NewVersionedApi("Newsletter Members").MapGroup("api/newsletter/member");
group.MapGet("", GetAllMembersAsync)
.WithDisplayName("Get Members")
.WithDisplayName("Get All Members")
.HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewNewsletterMembers));

View File

@ -11,38 +11,38 @@ public class OrderBagController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.CreateOrder));
group.MapGet("", GetUserCurrentOrderBagAsync)
.WithDisplayName("Get User Current OrderBag")
.WithDisplayName("GetUserCurrentOrderBag")
.HasApiVersion(1.0);
group.MapPost("check", CheckOrderBagAsync)
.WithDisplayName("Check OrderBag")
.WithDisplayName("CheckOrderBag")
.AllowAnonymous()
.HasApiVersion(1.0);
group.MapPost("add", AddProductToBagAsync)
.WithDisplayName("Add Product To OrderBag")
.WithDisplayName("AddProductToBag")
.HasApiVersion(1.0);
group.MapDelete("remove", RemoveFromOrderBagAsync)
.WithDisplayName("Remove From OrderBag")
.WithDisplayName("RemoveFromOrderBag")
.HasApiVersion(1.0);
group.MapPost("submit", SubmitOrderBagAsync)
.WithDisplayName("Submit OrderBag")
.WithDisplayName("SubmitOrderBag")
.HasApiVersion(1.0);
group.MapPost("discount/{orderId}", DiscountActionOrderBagAsync)
.WithDisplayName("Add Discount To OrderBag")
group.MapPost("discount/{orderId}", AddDiscountToOrderBagAsync)
.WithDisplayName("AddDiscountToOrderBag")
.HasApiVersion(1.0);
group.MapPost("shipping/{orderId}", AddShippingToOrderBagAsync)
.WithDisplayName("Add Shipping To OrderBag")
.WithDisplayName("AddShippingToOrderBag")
.HasApiVersion(1.0);
group.MapPost("payment/{orderId}", SubmitOrderPaymentAsync)
.WithDisplayName("Submit Order Payment")
.WithDisplayName("SubmitOrderPayment")
.HasApiVersion(1.0);
}
@ -62,8 +62,8 @@ public class OrderBagController : ICarterModule
public async Task<IResult> RemoveFromOrderBagAsync([FromBody] List<OrderBagRequestDto> requestDtos, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new RemoveFromOrderBagCommand(requestDtos), cancellationToken));
public async Task<IResult> DiscountActionOrderBagAsync(Guid orderId, [FromQuery] string? discountCode, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new SubmitDiscountActionCommand(orderId, discountCode), cancellationToken));
public async Task<IResult> AddDiscountToOrderBagAsync(Guid orderId, [FromQuery] string discountCode, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new SubmitDiscountCommand(orderId, discountCode), cancellationToken));
public async Task<IResult> AddShippingToOrderBagAsync(Guid orderId, [FromBody] SubmitOrderDeliveryCommand request, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request with { OrderId = orderId }, cancellationToken));

View File

@ -10,35 +10,27 @@ public class OrderController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Orders")
.WithDisplayName("GetAllOrders")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders , ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Order")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,
ApplicationPermission.ViewAllOrders,
ApplicationPermission.ManageOrders,
ApplicationPermission.ViewMineOrders))
.WithDisplayName("GetOneOrder")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapPost("{id}/confirm", ConfirmOrderStepAsync)
.WithDisplayName("Confirm OrderStep")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapPost("{id}/cancel", CancelOrderStepAsync)
.WithDisplayName("Cancel Order")
.WithDisplayName("ConfirmOrderStep")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync)
.WithDisplayName("Delete Order")
.WithDisplayName("DeleteOneOrder")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapGet("{id}/invoice", GetOrderInvoiceAsync)
.WithDisplayName("Get Order Invoice")
.WithDisplayName("GetOrderInvoice")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.AllowAnonymous()
.HasApiVersion(1.0);
@ -48,18 +40,8 @@ public class OrderController : ICarterModule
private async Task<IResult> ConfirmOrderStepAsync(Guid id, [FromQuery] OrderStatus nextOrderStatus, [FromQuery]string? trackingCode, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ConfirmOrderStepCommand(id, nextOrderStatus,TrackingCode:trackingCode), cancellationToken));
private async Task<IResult> CancelOrderStepAsync(Guid id, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new CancelOrderStepCommand(id), cancellationToken));
public async Task<IResult> GetAllAsync(IMediator mediator,
[FromQuery]string? factorCode,
[FromQuery]long? selectedDate,
[FromQuery]OrderStatus? orderStatus,
[FromQuery]OrderQueryDateFilter? dateFilter,
[FromQuery]bool? orderBags,
[FromQuery]int page = 0,
CancellationToken cancellationToken = default)
=> TypedResults.Ok(await mediator.Send(new GetOrdersQuery(Page:page, FactorCode:factorCode ,OrderBags:orderBags??false , SelectedDate: selectedDate, OrderStatus:orderStatus, DateFilter:dateFilter), cancellationToken));
public async Task<IResult> GetAllAsync(IMediator mediator, [FromQuery]string? factorCode, [FromQuery]long? selectedDate, [FromQuery] OrderStatus? orderStatus, [FromQuery] OrderQueryDateFilter? dateFilter, [FromQuery] int page = 0, CancellationToken cancellationToken = default)
=> TypedResults.Ok(await mediator.Send(new GetOrdersQuery(Page:page, FactorCode:factorCode , SelectedDate: selectedDate, OrderStatus:orderStatus, DateFilter:dateFilter), cancellationToken));
public async Task<IResult> GetAsync(IMediator mediator, Guid id, CancellationToken cancellationToken = default)
{

View File

@ -12,13 +12,6 @@ public class PageController : ICarterModule
.HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewPages, ApplicationPermission.ManagePages));
group.MapGet("redirect/check", CheckRedirectedOldLinkAsync)
.WithDisplayName("Check Redirect OldLink")
.HasApiVersion(1.0);
group.MapGet("deleted/check", CheckDeletedLinkAsync)
.WithDisplayName("Check Deleted Link")
.HasApiVersion(1.0);
group.MapGet("{id}", GetPageByIdAsync)
.WithDisplayName("Get Page")
@ -38,10 +31,6 @@ public class PageController : ICarterModule
.HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManagePages));
group.MapPut("", UpdatePageAsync)
.WithDisplayName("Update Page")
.HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManagePages));
group.MapDelete("{id}", DeletePageByIdAsync)
.WithDisplayName("Delete Page")
@ -50,35 +39,31 @@ public class PageController : ICarterModule
}
private async Task<IResult> CheckDeletedLinkAsync([FromQuery] string link, [FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.CheckDeletedAsync(link, cancellationToken));
private async Task<IResult> CheckRedirectedOldLinkAsync([FromQuery] string oldUrl, [FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Content(await pageService.CheckRedirectAsync(oldUrl, cancellationToken));
private async Task<IResult> DeletePageByIdAsync([FromRoute]Guid id,[FromServices]IPageService pageService,CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.DeletePageAsync(id, cancellationToken));
public async Task<IResult> GetPagesAsync([FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.GetPagesAsync(cancellationToken));
{
return TypedResults.Ok(await pageService.GetPagesAsync(cancellationToken));
}
public async Task<IResult> GetPageByIdAsync(Guid id ,[FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.GetPageAsync(id: id, cancellationToken: cancellationToken));
{
return TypedResults.Ok(await pageService.GetPageAsync(id: id,cancellationToken: cancellationToken));
}
public async Task<IResult> GetPageByTypeAsync(string type, [FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.GetPageAsync(type: type, cancellationToken: cancellationToken));
{
return TypedResults.Ok(await pageService.GetPageAsync(type: type, cancellationToken: cancellationToken));
}
public async Task<IResult> GetPageAsync(string pageSlug, [FromServices] IPageService pageService, CancellationToken cancellationToken)
=> TypedResults.Ok(await pageService.GetPageAsync(pageSlug: pageSlug, cancellationToken: cancellationToken));
{
return TypedResults.Ok(await pageService.GetPageAsync(pageSlug: pageSlug,cancellationToken: cancellationToken));
}
public async Task<IResult> PostPageAsync([FromBody] PageActionRequestDto page, [FromServices] IPageService pageService, CancellationToken cancellationToken)
{
await pageService.CreatePageAsync(page, cancellationToken);
return TypedResults.Ok();
}
public async Task<IResult> UpdatePageAsync([FromBody] PageActionRequestDto page, [FromServices] IPageService pageService, CancellationToken cancellationToken)
{
await pageService.UpdatePageAsync(page, cancellationToken);
return TypedResults.Ok();
}
}

View File

@ -12,7 +12,7 @@ public class PaymentController : ICarterModule
.MapGroup($"api/accounting/pay");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Payments")
.WithDisplayName("GetPayments")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewPayments))
.HasApiVersion(1.0);
@ -22,7 +22,6 @@ public class PaymentController : ICarterModule
// .HasApiVersion(1.0);
group.MapGet("verify", VerifyPaymentAsync)
.WithDisplayName("Verify Payment")
.HasApiVersion(1.0);
}

View File

@ -9,25 +9,22 @@ public class ProductCategoryController : ICarterModule
.MapGroup($"api/product/category");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get ProductCategories")
.WithDisplayName("GetAllCategories")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get ProductCategory")
.WithDisplayName("GetCategory")
.HasApiVersion(1.0);
group.MapPost("", Post)
.WithDisplayName("Create ProductCategory")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
group.MapPut("", Put)
.WithDisplayName("Update ProductCategory")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.WithDisplayName("Delete ProductCategory")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
}

View File

@ -11,66 +11,37 @@ public class ProductController : ICarterModule
.MapGroup($"api/product");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Products")
.WithDisplayName("GetAllProducts")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Product")
.WithDisplayName("GetProducts")
.HasApiVersion(1.0);
group.MapPost("", Post)
.WithDisplayName("Create Product")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
group.MapPut("", Put)
.WithDisplayName("Update Product")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
group.MapGet("{productId}/sub", GetSubProductsAsync)
.WithDisplayName("Get Sub Products")
.HasApiVersion(1.0);
group.MapPut("{productId}/displayed", ChangeDisplayedAsync)
.WithDisplayName("Change Product Display")
group.MapPut("{productId}", ChangeDisplayedAsync)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
group.MapPut("{productId}/cost", ChangeCostAsync)
.WithDisplayName("Change Product Cost")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
group.MapGet("{productId}/comment",GetProductCommentsAsync)
.WithDisplayName("Get Product Comments")
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.WithDisplayName("Delete Product")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
}
private async Task<IResult> GetProductCommentsAsync([FromQuery] int page, [FromQuery]int count, [FromRoute] Guid productId, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page, count, productId), cancellationToken));
// GET:Get All Entity
public async Task<IResult> GetAllAsync([FromQuery] int page,
[FromQuery] string? productName,
[FromQuery] QuerySortBy? sortBy,
[FromQuery] Guid? categoryId,
[FromQuery] bool? specialOffer,
[FromQuery] Guid[]? brandIds,
[FromQuery] double? minPrice,
[FromQuery] double? maxPrice,
[FromQuery] bool? isActive,
IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetProductsQuery(Page: page, SpecialOffer: specialOffer, SortBy: sortBy ?? 0, ProductName: productName, CategoryId: categoryId ?? default, BrandIds: brandIds, MinPrice: minPrice ?? -1, MaxPrice: maxPrice ?? 0, IsActive: isActive), cancellationToken));
public async Task<IResult> GetAllAsync([FromQuery] int page, [FromQuery]string? productName, [FromQuery] QuerySortBy? sortBy, [FromQuery] Guid? categoryId, [FromQuery] bool? specialOffer, [FromQuery] Guid[]? brandIds , [FromQuery]double? minPrice , [FromQuery] double? maxPrice, [FromQuery]bool? isActive, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetProductsQuery(Page: page, SpecialOffer: specialOffer, SortBy: sortBy ?? 0 ,ProductName: productName, CategoryId: categoryId ?? default , BrandIds: brandIds , MinPrice: minPrice ?? -1 , MaxPrice:maxPrice ?? 0,IsActive:isActive),cancellationToken));
// GET:Get An Entity By Id
public async Task<IResult> GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetProductQuery(id), cancellationToken));
public async Task<IResult> GetAsync(Guid id, IMediator mediator,CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetProductQuery(id),cancellationToken));
// POST:Create Entity
public async Task<IResult> Post([FromBody] CreateProductCommand request, IMediator mediator,
@ -82,17 +53,9 @@ public class ProductController : ICarterModule
CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
// PUT:Update Entity
public async Task<IResult> GetSubProductsAsync(Guid productId, IMediator mediator,
CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetSubProductsQuery(productId), cancellationToken));
public async Task<IResult> ChangeDisplayedAsync(Guid productId, [FromQuery] bool beDisplayed, [FromServices] IMediator mediator, CancellationToken cancellationToken)
public async Task<IResult> ChangeDisplayedAsync(Guid productId, [FromQuery]bool beDisplayed, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ChangeProductDisplayedCommand(productId, beDisplayed), cancellationToken));
public async Task<IResult> ChangeCostAsync(Guid productId, [FromQuery] double cost, [FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ChangeProductCostCommand(productId, cost), cancellationToken));
// DELETE:Delete Entity
public async Task<IResult> Delete(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteProductCommand(id), cancellationToken));

View File

@ -1,50 +1,50 @@
namespace Netina.Api.Controllers;
public class CommentController : ICarterModule
public class ProductReviewController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Comments")
.MapGroup("api/comment");
var group = app.NewVersionedApi("ProductReview")
.MapGroup("product/review");
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Comment")
.WithDisplayName("GetOneAsync")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews,ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Comments")
.WithDisplayName("GetAllAsync")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews, ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
group.MapPost("", PostAsync)
.WithDisplayName("Create Comment")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
.WithDisplayName("PostReview")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview, ApplicationPermission.AddReview))
.HasApiVersion(1.0);
group.MapPut("confirm/{id}", ConfirmAsync)
.WithDisplayName("Confirm Comment")
.WithDisplayName("ConfirmAsync")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ConfirmReview, ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync)
.WithDisplayName("Delete Comment")
.WithDisplayName("DeleteAsync")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
}
public async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetCommentsQuery(page), cancellationToken));
=> TypedResults.Ok(await mediator.Send(new GetReviewsQuery(page), cancellationToken));
public async Task<IResult> GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetCommentQuery(id), cancellationToken));
=> TypedResults.Ok(await mediator.Send(new GetReviewQuery(id), cancellationToken));
public async Task<IResult> PostAsync(CreateCommentCommand request, IMediator mediator, CancellationToken cancellationToken)
public async Task<IResult> PostAsync(CreateReviewCommand request, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
public async Task<IResult> ConfirmAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new ConfirmCommentCommand(id), cancellationToken));
=> TypedResults.Ok(await mediator.Send(new ConfirmReviewCommand(id), cancellationToken));
public async Task<IResult> DeleteAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteCommentCommand(id), cancellationToken));
=> TypedResults.Ok(await mediator.Send(new DeleteReviewCommand(id), cancellationToken));
}

View File

@ -11,32 +11,29 @@ public class RoleController : ICarterModule
.MapGroup($"api/user/role");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Roles")
.WithDisplayName("GetAllRoles")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
group.MapGet("permission", GetAllPermissions)
.WithDisplayName("Get Permissions")
.WithDisplayName("GetAllPermissions")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Role")
.WithDisplayName("GetRole")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
group.MapPost("", Post)
.WithDisplayName("Create Role")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
group.MapPut("", Put)
.WithDisplayName("Update Role")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.WithDisplayName("Delete Role")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
}

View File

@ -9,11 +9,11 @@ public class ScraperController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageScraper));
group.MapGet("digi", GetDigiProductsAsync)
.WithDisplayName("Get DigiProducts")
.WithDisplayName("GetDigiProducts")
.HasApiVersion(1.0);
group.MapPost("digi/{productId}", AddProductToShopAsync)
.WithDisplayName("Add DigiProduct To Shop")
.WithDisplayName("AddProductToShop")
.HasApiVersion(1.0);
}

View File

@ -10,19 +10,19 @@ public class SearchController : ICarterModule
group.MapGet("/thumb", SearchThumbAsync)
.WithDisplayName("Thumb Search")
.WithDisplayName("Thumb Search Async")
.HasApiVersion(1.0);
group.MapGet("zarehbin", ZarehbinAsync)
.WithDisplayName("Get Zarehbin Product")
.WithDisplayName("Search Async")
.HasApiVersion(1.0);
group.MapGet("torob", TorobAsync)
.WithDisplayName("Get Torob Product")
.WithDisplayName("Get Torob Product Async")
.HasApiVersion(1.0);
group.MapGet("emalls", EmallsAsync)
.WithDisplayName("Get Emalls Product")
.WithDisplayName("Get Emalls Product Async")
.HasApiVersion(1.0);
}

View File

@ -2,11 +2,17 @@
using Netina.Domain.Entities.Blogs;
namespace Netina.Api.Controllers;
public class SeedController(IWebHostEnvironment environment) : ICarterModule
public class SeedController : ICarterModule
{
private readonly IWebHostEnvironment _environment;
public SeedController(IWebHostEnvironment environment)
{
_environment = environment;
}
public void AddRoutes(IEndpointRouteBuilder app)
{
if (environment.IsDevelopment())
if (_environment.IsDevelopment())
{
var group = app.NewVersionedApi("Seed")
.MapGroup("api/seed");
@ -72,14 +78,13 @@ public class SeedController(IWebHostEnvironment environment) : ICarterModule
var baseCat = await mediator.Send(new CreateProductCategoryCommand("دسته بندی نشده", "محصولات دسته بندی نشده",
true,
default,
new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()),cancellationToken);
new List<StorageFileSDto>()),cancellationToken);
categories.Add(0,baseCat);
foreach (var requestDto in request)
{
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);
}
@ -92,18 +97,13 @@ public class SeedController(IWebHostEnvironment environment) : ICarterModule
if (key != "kKAYskyG8xPxKnJrHkuYxub4Ao2bnz7AOmNtwDT0RaqzaG7ZvbvaP29tCrC8wJ823RczJFXOIQT2bDOec4F38A==")
throw new AppException("Key is not valid", ApiResultStatusCode.UnAuthorized);
Dictionary<int, Guid> brands = new Dictionary<int, Guid>();
var baseBrand = await mediator.Send(new CreateBrandCommand("بدون برند","NoBrand",
"محصولات بدون برند",
false,
string.Empty,
new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()), cancellationToken);
var baseBrand = await mediator.Send(new CreateBrandCommand("بدون برند","NoBrand", "محصولات بدون برند", false,string.Empty,
new List<StorageFileSDto>()), cancellationToken);
brands.Add(0, baseBrand);
foreach (var requestDto in request)
{
var sDto = await mediator.Send(new CreateBrandCommand(requestDto.Name,string.Empty, requestDto.Description, false,
string.Empty, new List<StorageFileSDto>(),new Dictionary<string, string>(),new Dictionary<string, string>()), cancellationToken);
string.Empty, new List<StorageFileSDto>()), cancellationToken);
brands.Add(requestDto.BaseBrandId,sDto);
}
@ -126,7 +126,7 @@ public class SeedController(IWebHostEnvironment environment) : ICarterModule
seedBlogRequestDto.CategoryId = noCategory.Id;
}
var ent = Blog.Create(seedBlogRequestDto.Title, seedBlogRequestDto.Slug, seedBlogRequestDto.Content, seedBlogRequestDto.Tags, seedBlogRequestDto.ReadingTime,
seedBlogRequestDto.Summery, seedBlogRequestDto.IsSuggested, seedBlogRequestDto.CategoryId,default);
seedBlogRequestDto.Summery, seedBlogRequestDto.IsSuggested, seedBlogRequestDto.CategoryId);
foreach (var storageFileSDto in seedBlogRequestDto.Files)
{

View File

@ -10,12 +10,12 @@ public class SettingController : ICarterModule
.MapGroup("api/setting");
group.MapGet("{settingName}", GetSettingAsync)
.WithDisplayName("Get Setting")
.WithDisplayName("GetSetting")
.RequireAuthorization(builder=>builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewSettings,ApplicationPermission.ManageSettings))
.HasApiVersion(1.0);
group.MapPost("{settingName}", PostSettingAsync)
.WithDisplayName("Create Setting")
.WithDisplayName("PostSettingAsync")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageSettings))
.HasApiVersion(1.0);
}

View File

@ -9,26 +9,23 @@ public class ShippingController : ICarterModule
.MapGroup($"api/warehouse/shipping");
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Shipping")
.WithDisplayName("GetAllShipping")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get Shipping")
.WithDisplayName("GetShipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewShipping, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0);
group.MapPost("", Post)
.WithDisplayName("Create Shipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0);
group.MapPut("", Put)
.WithDisplayName("Update Shipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.WithDisplayName("Delete Shipping")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageShipping))
.HasApiVersion(1.0);
}

View File

@ -1,40 +0,0 @@
namespace Netina.Api.Controllers;
public class SubProductController : ICarterModule
{
public virtual void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("SubProduct")
.MapGroup($"api/sub/product");
group.MapPost("", PostAsync)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Create SubProduct")
.HasApiVersion(1.0);
group.MapPut("", PutAsync)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Update SubProduct")
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs))
.WithDisplayName("Delete SubProduct")
.HasApiVersion(1.0);
}
// POST:Create Entity
private async Task<IResult> PostAsync([FromBody] CreateSubProductCommand request, IMediator mediator,
CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
// PUT:Update Entity
private async Task<IResult> PutAsync([FromBody] UpdateSubProductCommand request, IMediator mediator,
CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
// DELETE:Delete Entity
private async Task<IResult> DeleteAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new DeleteSubProductCommand(id), cancellationToken));
}

View File

@ -13,7 +13,7 @@ public class UserAddressController : ICarterModule
.HasApiVersion(1.0);
group.MapPost("", PostAddressesAsync)
.WithDisplayName("Create Addresses")
.WithDisplayName("Post Addresses")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
.HasApiVersion(1.0);

View File

@ -12,47 +12,44 @@ public class UserController : ICarterModule
.MapGroup($"api/user");
group.MapGet("info", GetUserInfoAsync)
.WithDisplayName("Get UserInfo")
.WithDisplayName("GetUserInfo")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
.HasApiVersion(1.0);
group.MapGet("", GetAllAsync)
.WithDisplayName("Get Users")
.WithDisplayName("GetAllUsers")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("Get User")
.WithDisplayName("GetUser")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0);
group.MapGet("/order", GetUserOrdersAsync)
.WithDisplayName("Get UserOrders By JWT")
.WithDisplayName("GetUserOrders")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewMineOrders))
.HasApiVersion(1.0);
group.MapGet("{id}/order", GetUserOrdersByIdAsync)
.WithDisplayName("Get UserOrders")
.WithDisplayName("GetUserOrders")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders))
.HasApiVersion(1.0);
group.MapGet("/changelog", GetChangeLogAsync)
.WithDisplayName("Get ChangeLog")
.WithDisplayName("GetChangeLog")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDashboard))
.HasApiVersion(1.0);
group.MapPost("", Post)
.WithDisplayName("Create User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0);
group.MapPut("", Put)
.WithDisplayName("Update User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0);
group.MapDelete("{id}", Delete)
.WithDisplayName("Delete User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0);
}

View File

@ -1,9 +1,6 @@
using Netina.Domain.Enums;
using Netina.Domain.MartenEntities.Settings;
namespace Netina.Api.Controllers;
namespace Netina.Api.Controllers;
public class WebSiteController : ICarterModule
public class WebSiteController:ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
@ -12,38 +9,8 @@ public class WebSiteController : ICarterModule
group.MapGet("/navbar", GetNavBarItemsAsync)
.WithDisplayName("Get NavBar Items")
.HasApiVersion(1.0);
group.MapGet("/catelog", GetCatalogAsync)
.WithDisplayName("Get Catalog Items")
.HasApiVersion(1.0);
group.MapGet("/banner", GetBannerAsync)
.WithDisplayName("Get Banner Items")
.HasApiVersion(1.0);
}
private async Task<IResult> GetNavBarItemsAsync([FromServices] IMediator mediator, CancellationToken cancellationToken)
=> TypedResults.Ok(await mediator.Send(new GetWebSiteNavBarCommand(),cancellationToken));
private async Task<IResult> GetCatalogAsync([FromServices] ISettingService settingService, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PersonalizationSetting), cancellationToken);
if (setting is PersonalizationSetting personalizationSetting)
{
return TypedResults.Ok(personalizationSetting.Catalog);
}
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Catalogs not found");
}
private async Task<IResult> GetBannerAsync([FromQuery]BannerSection? section,[FromServices] ISettingService settingService, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PersonalizationSetting), cancellationToken);
if (setting is not PersonalizationSetting personalizationSetting)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "Catalogs not found");
if (section != null)
return TypedResults.Ok(personalizationSetting.Banners.Where(b => b.Section == section));
return TypedResults.Ok(personalizationSetting.Banners);
}
}

View File

@ -22,6 +22,8 @@ RUN dotnet publish "./Netina.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publish
FROM base AS final
RUN apt-get update
RUN apt-get install-y libgdiplus
WORKDIR /app
COPY --from=publish /app/publish .

View File

@ -6,54 +6,53 @@
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<AssemblyVersion>1.14.22.42</AssemblyVersion>
<FileVersion>1.14.22.42</FileVersion>
<LangVersion>latest</LangVersion>
<AssemblyVersion>1.0.3.3</AssemblyVersion>
<FileVersion>1.0.3.3</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
<PackageReference Include="Asp.Versioning.Http" Version="8.1.0" />
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
<PackageReference Include="Carter" Version="8.1.0" />
<PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.10.0" />
<PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="12.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<PackageReference Include="Carter" Version="8.0.0" />
<PackageReference Include="FluentValidation" Version="11.9.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.0" />
<PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="12.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Autofac" Version="8.1.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Elmah.Io.AspNetCore.Serilog" Version="5.1.23" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
<PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Elmah.Io.AspNetCore.Serilog" Version="5.0.17" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Sentry.Serilog" Version="4.11.0" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Sentry.Serilog" Version="4.4.0" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.3.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.ElmahIo" Version="5.1.43" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.ElmahIo" Version="5.0.38" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="10.2.0" />
<PackageReference Include="StackExchange.Redis.Extensions.Core" Version="10.2.0" />
<PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="10.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.8.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.8.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Drawing.Common" Version="8.0.8" />
<PackageReference Include="System.Drawing.Common" Version="8.0.4" />
</ItemGroup>
<ItemGroup>

View File

@ -7,7 +7,6 @@ builder.Host.UseSerilog();
LoggerConfig.ConfigureSerilog();
string env = builder.Environment.IsDevelopment() == true ? "Development" : "Production";
builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
if (builder.Environment.IsDevelopment())
{
string projectName = "Vesmeh";
@ -42,6 +41,7 @@ builder.Services.AddMarten(configuration,builder.Environment);
builder.Services.AddCarter();
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("NjU5MUAzMTM5MmUzMTJlMzBmYlFPZXRJVThMS20zaFlBdjdKMnlKeGJRQng4b0lURDZ1Rk40akFHbnVrPQ==");
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
@ -96,12 +96,12 @@ builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseCustomSwagger(siteSetting.BaseUrl);
//app.UseCustomSwagger(siteSetting.BaseUrl);
app.UseSwagger();
app.MapScalarUi();
//app.UseSwagger();
//app.UseSwaggerUI();
if (app.Environment.IsProduction())

View File

@ -1 +0,0 @@
9167d171-2373-44c9-9fa5-a91858e9854d

View File

@ -3,17 +3,24 @@ using Netina.Repository.Abstracts;
namespace Netina.Api.Services;
public class CurrentUserService(IHttpContextAccessor httpContextAccessor) : ICurrentUserService
public class CurrentUserService : ICurrentUserService
{
public string? UserId => httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
public string? RoleName => httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Role);
public string? UserName => httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Name);
public string? DeviceId => GetDeviceId(httpContextAccessor.HttpContext);
private readonly IHttpContextAccessor _httpContextAccessor;
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string? UserId => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
public string? RoleName => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Role);
public string? UserName => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Name);
public string? DeviceId => GetDeviceId(_httpContextAccessor.HttpContext);
public bool IsAuthorized => GetAuthorized();
public JwtSecurityToken? JwtToken => GetJwtToken();
private JwtSecurityToken? GetJwtToken()
{
var stream = httpContextAccessor.HttpContext?.Request.Headers.Authorization.FirstOrDefault();
var stream = _httpContextAccessor.HttpContext?.Request.Headers.Authorization.FirstOrDefault();
if (stream == null)
return null;
var handler = new JwtSecurityTokenHandler();
@ -21,7 +28,7 @@ public class CurrentUserService(IHttpContextAccessor httpContextAccessor) : ICur
return jsonToken as JwtSecurityToken;
}
public List<string>? Permissions => httpContextAccessor.HttpContext?.User?.FindAll("Permission")?.Select(c => c.Value)?.ToList();
public List<string>? Permissions => _httpContextAccessor.HttpContext?.User?.FindAll("Permission")?.Select(c => c.Value)?.ToList();
private string? GetDeviceId(HttpContext? context)
{
@ -45,9 +52,9 @@ public class CurrentUserService(IHttpContextAccessor httpContextAccessor) : ICur
private bool GetAuthorized()
{
if (httpContextAccessor.HttpContext?.User.Identity == null)
if (_httpContextAccessor.HttpContext?.User.Identity == null)
return false;
return httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;
return _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;
}

View File

@ -1,4 +1,7 @@
namespace Netina.Api.WebFramework.Bases;
using Netina.Common.Models.Api;
using Netina.Core.Models.Api;
namespace Netina.Api.WebFramework.Bases;
public class ApiResultFactory
{

View File

@ -1,13 +1,23 @@
namespace Netina.Api.WebFramework.Bases;
using Netina.Common.Models.Entity;
using Netina.Common.Models.Exception;
using Netina.Common.Models.Mapper;
using Netina.Repository.Repositories.Base.Contracts;
namespace Netina.Api.WebFramework.Bases;
public class CrudEndpoint<TEntity, TGetAllQuery, TGetOneQuery, TCreateCommand, TUpdateCommand, TDeleteCommand>(
string endpointName)
where TEntity : ApiEntity, new()
public class CrudEndpoint<TEntity,TGetAllQuery,TGetOneQuery,TCreateCommand,TUpdateCommand,TDeleteCommand> where TEntity : ApiEntity, new()
{
private readonly string _endpointName;
public CrudEndpoint(string endpointName)
{
_endpointName = endpointName;
}
public virtual void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi(endpointName).MapGroup($"api/{endpointName}");
var group = app.NewVersionedApi(_endpointName).MapGroup($"api/{_endpointName}");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAll")
@ -73,11 +83,16 @@ public class BaseController : ControllerBase
}
[Authorize(AuthenticationSchemes = "Bearer")]
public class CrudController<TDto, TEntity>(IRepositoryWrapper repositoryWrapper) : BaseController
public class CrudController<TDto, TEntity> : BaseController
where TDto : BaseDto<TDto, TEntity>, new()
where TEntity : ApiEntity, new()
{
protected readonly IRepositoryWrapper _repositoryWrapper = repositoryWrapper;
protected readonly IRepositoryWrapper _repositoryWrapper;
public CrudController(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
// GET:Get All Entity
[HttpGet]
@ -153,10 +168,15 @@ public class CrudController<TDto, TEntity>(IRepositoryWrapper repositoryWrapper)
}
[Authorize(AuthenticationSchemes = "Bearer")]
public class CrudController<TEntity>(IRepositoryWrapper repositoryWrapper) : BaseController
public class CrudController<TEntity> : BaseController
where TEntity : ApiEntity, new()
{
protected readonly IRepositoryWrapper _repositoryWrapper = repositoryWrapper;
protected readonly IRepositoryWrapper _repositoryWrapper;
public CrudController(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
// GET:Get All Entity
[HttpGet]

View File

@ -1,4 +1,6 @@
namespace Netina.Api.WebFramework.Configurations;
using Netina.Infrastructure.Models;
namespace Netina.Api.WebFramework.Configurations;
public static class LoggerConfig
{

View File

@ -52,14 +52,14 @@ public static class ServiceExtensions
{
new()
{
Hosts =
[
Hosts = new[]
{
new RedisHost
{
Port = siteSettings.MasterRedisConfiguration.Port,
Host = siteSettings.MasterRedisConfiguration.Host
}
],
},
Password = siteSettings.MasterRedisConfiguration.Password,
Ssl = false
}

View File

@ -1,4 +1,7 @@
using Refit;
using Netina.Common.Models.Api;
using Netina.Common.Models.Exception;
using Netina.Core.Models.Api;
using Refit;
namespace Netina.Api.WebFramework.MiddleWares;
@ -10,11 +13,22 @@ public static class ExceptionHandlerMiddlewareExtensions
}
}
public class ExceptionHandlerMiddleware(
public class ExceptionHandlerMiddleware
{
private readonly IWebHostEnvironment _env;
private readonly ILogger<ExceptionHandlerMiddleware> _logger;
private readonly RequestDelegate _next;
public ExceptionHandlerMiddleware(
RequestDelegate next,
IWebHostEnvironment env,
ILogger<ExceptionHandlerMiddleware> logger)
{
{
_next = next;
_env = env;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
string message = null;
@ -23,17 +37,15 @@ public class ExceptionHandlerMiddleware(
try
{
await next(context);
await _next(context);
}
catch (BaseApiException exception)
{
logger.LogError(exception, exception.Message);
httpStatusCode = exception.ApiStatusCode == ApiResultStatusCode.NotFound ? HttpStatusCode.NotFound :
exception.ApiStatusCode == ApiResultStatusCode.BadRequest ?
HttpStatusCode.BadRequest : exception.HttpStatusCode;
_logger.LogError(exception, exception.Message);
httpStatusCode = exception.HttpStatusCode;
apiStatusCode = exception.ApiStatusCode;
if (env.IsDevelopment())
if (_env.IsDevelopment())
{
var dic = new Dictionary<string, string>
{
@ -71,19 +83,19 @@ public class ExceptionHandlerMiddleware(
}
catch (SecurityTokenExpiredException exception)
{
logger.LogError(exception, exception.Message);
_logger.LogError(exception, exception.Message);
SetUnAuthorizeResponse(exception);
await WriteToResponseAsync();
}
catch (UnauthorizedAccessException exception)
{
logger.LogError(exception, exception.Message);
_logger.LogError(exception, exception.Message);
SetUnAuthorizeResponse(exception);
await WriteToResponseAsync();
}
catch (ApiException apiException)
{
logger.LogError(apiException, apiException.Message);
_logger.LogError(apiException, apiException.Message);
httpStatusCode = HttpStatusCode.InternalServerError;
apiStatusCode = ApiResultStatusCode.RefitError;
@ -94,9 +106,9 @@ public class ExceptionHandlerMiddleware(
}
catch (Exception exception)
{
logger.LogError(exception, exception.Message);
_logger.LogError(exception, exception.Message);
if (env.IsDevelopment())
if (_env.IsDevelopment())
{
if (exception?.InnerException?.Message != null)
{
@ -133,7 +145,7 @@ public class ExceptionHandlerMiddleware(
});
if (httpStatusCode == HttpStatusCode.InternalServerError)
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
else
context.Response.StatusCode = (int)httpStatusCode;
context.Response.ContentType = "application/json";
@ -174,7 +186,7 @@ public class ExceptionHandlerMiddleware(
httpStatusCode = HttpStatusCode.Unauthorized;
apiStatusCode = ApiResultStatusCode.UnAuthorized;
if (env.IsDevelopment())
if (_env.IsDevelopment())
{
var dic = new Dictionary<string, string>
{

View File

@ -8,19 +8,28 @@ public static class PerformanceMiddlewareExtensions
}
}
public class PerformanceMiddleware(
public class PerformanceMiddleware
{
private readonly ILogger<ExceptionHandlerMiddleware> _logger;
private readonly RequestDelegate _next;
private readonly Stopwatch _timer;
public PerformanceMiddleware(
RequestDelegate next,
ILogger<ExceptionHandlerMiddleware> logger)
{
private readonly Stopwatch _timer = new();
{
_next = next;
_logger = logger;
_timer = new Stopwatch();
}
public async System.Threading.Tasks.Task Invoke(HttpContext context)
{
_timer.Start();
await next(context);
await _next(context);
_timer.Stop();
var elapsedMilliseconds = _timer.ElapsedMilliseconds;
logger.LogWarning($"REQUEST TIMER : {elapsedMilliseconds}");
_logger.LogWarning($"REQUEST TIMER : {elapsedMilliseconds}");
}
}

View File

@ -27,7 +27,7 @@ public static class ScalarUiConfiguration
<!-- Optional: You can set a full configuration object like this: -->
<script>
var configuration = {
theme: 'mars',
theme: 'bluePlanet',
}
document.getElementById('api-reference').dataset.configuration =

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
using Netina.Common.Extensions;
using Pluralize.NET;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
@ -18,9 +19,9 @@ public static class SwaggerConfiguration
new OpenApiInfo
{
Version = "v1",
Title = "Netina Api Document",
Description = "Netina api for netina clients , like shops , websites and apps",
License = new OpenApiLicense { Name = "Vira Safir Fanavar" },
Title = "iGarson Api Dacument",
Description = "iGarson api for clients that wana use",
License = new OpenApiLicense { Name = "Vira Safir Fanavar " },
Contact = new OpenApiContact
{
Name = "Amir Hossein Khademi",
@ -138,12 +139,17 @@ public class SetVersionInPaths : IDocumentFilter
}
}
public class UnauthorizedResponsesOperationFilter(
bool includeUnauthorizedAndForbiddenResponses,
string schemeName = "Bearer")
: IOperationFilter
public class UnauthorizedResponsesOperationFilter : IOperationFilter
{
private readonly string schemeName = schemeName;
private readonly bool includeUnauthorizedAndForbiddenResponses;
private readonly string schemeName;
public UnauthorizedResponsesOperationFilter(bool includeUnauthorizedAndForbiddenResponses,
string schemeName = "Bearer")
{
this.includeUnauthorizedAndForbiddenResponses = includeUnauthorizedAndForbiddenResponses;
this.schemeName = schemeName;
}
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{

View File

@ -1,23 +1,14 @@
using System.Net;
using System.Web;
using System.Web;
using System.Xml.Linq;
namespace Netina.Common.Extensions
{
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string value)
=> string.IsNullOrEmpty(value);
public static string GetSlug(string title)
{
var splits = title.Split("/");
string outPut = string.Empty;
foreach (var split in splits)
outPut = outPut.IsNullOrEmpty() ? split : string.Concat(outPut, "/", WebUtility.UrlEncode( split.Replace(' ', '-')));
return outPut;
return HttpUtility.UrlEncode(title.Replace(' ', '-'));
}
public static string ToPriceWhitPriceType(this long price, string priceType)
{
return price.ToString("N0") + " " + priceType;

View File

@ -19,23 +19,23 @@ public class MartenEntity : IMartenEntity
//public bool Equals(ApiEntity other)
//{
// if (ReferenceEquals(null, other)) return false;
// if (ReferenceEquals(this, other)) return true;
// return Id.Equals(other.Id);
//}
public bool Equals(ApiEntity other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Id.Equals(other.Id);
}
//public override bool Equals(object obj)
//{
// if (ReferenceEquals(null, obj)) return false;
// if (ReferenceEquals(this, obj)) return true;
// if (obj.GetType() != this.GetType()) return false;
// return Equals((ApiEntity)obj);
//}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((ApiEntity)obj);
}
//public override int GetHashCode()
//{
// return Id.GetHashCode();
//}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}

View File

@ -3,14 +3,15 @@
[AttributeUsage(AttributeTargets.Class)]
public class PageClassDisplay : Attribute
{
private readonly string _name;
private readonly string _description;
private readonly string _name;
public PageClassDisplay(string name, string description)
{
_name = name;
_description = description;
}
public string GetName()
{
return _name;

View File

@ -4,7 +4,6 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
@ -12,12 +11,12 @@
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
</ItemGroup>
<!--<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

View File

@ -2,12 +2,8 @@
public interface IPageService : IScopedDependency
{
Task<BasePageLDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null, string? type = null, CancellationToken cancellationToken = default);
Task<BasePageSDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null, string? type = null, CancellationToken cancellationToken = default);
Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default);
Task<bool> CreatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default);
Task<bool> UpdatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default);
Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default);
Task<string> CheckRedirectAsync(string oldUrl, CancellationToken cancellationToken);
Task<bool> CheckDeletedAsync(string url, CancellationToken cancellationToken);
}

View File

@ -1,7 +1,18 @@
namespace Netina.Core.BaseServices;
public class AccountService(
public class AccountService : IAccountService
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _userSignInManager;
private readonly IJwtService _jwtService;
private readonly ICurrentUserService _currentUserService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ISmsService _smsService;
private readonly IUserService _managerUserService;
public AccountService(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> userSignInManager,
IJwtService jwtService,
@ -9,24 +20,34 @@ public class AccountService(
IRepositoryWrapper repositoryWrapper,
ISmsService smsService,
IUserService managerUserService)
: IAccountService
{
{
_userManager = userManager;
_userSignInManager = userSignInManager;
_jwtService = jwtService;
_currentUserService = currentUserService;
_repositoryWrapper = repositoryWrapper;
_smsService = smsService;
_managerUserService = managerUserService;
}
public async Task<bool> ForgetPasswordAsync(string phoneNumber)
{
var user = await userManager.FindByNameAsync(phoneNumber);
var user = await _userManager.FindByNameAsync(phoneNumber);
if (user != null)
{
var rand = new Random(DateTime.Now.Millisecond);
var newPass = rand.Next(1000000, 9000000).ToString();
if (!user.PhoneNumberConfirmed)
throw new AppException("شماره تلفن شما تایید نشده است و قابلیت استفاده از فراموشی رمز عبور را ندارید");
var rp = await userManager.RemovePasswordAsync(user);
var rp = await _userManager.RemovePasswordAsync(user);
if (!rp.Succeeded)
throw new AppException(string.Join('-', rp.Errors.Select(e => e.Description)));
var ap = await userManager.AddPasswordAsync(user, newPass);
var ap = await _userManager.AddPasswordAsync(user, newPass);
if (!ap.Succeeded)
throw new AppException(string.Join('-', ap.Errors.Select(e => e.Description)));
await smsService.SendForgerPasswordAsync(user.PhoneNumber, newPass);
await _smsService.SendForgerPasswordAsync(user.PhoneNumber, newPass);
return true;
}
@ -35,7 +56,7 @@ public class AccountService(
public async Task<bool> CheckMemberShipAsync(string phoneNumber)
{
var user = await userManager.FindByNameAsync(phoneNumber);
var user = await _userManager.FindByNameAsync(phoneNumber);
if (user == null)
return false;
return true;
@ -46,23 +67,23 @@ public class AccountService(
var newPhoneNumber = StringExtensions.CheckPhoneNumber(phoneNumber);
if (!PhoneNumberExtensions.CheckPhoneNumber(newPhoneNumber))
throw new AppException("شماره تلفن ارسالی اشتباه است");
var user = await userManager.FindByNameAsync(newPhoneNumber);
var user = await _userManager.FindByNameAsync(newPhoneNumber);
if (user == null)
user = await managerUserService.CreateUserAsync(phoneNumber);
user = await _managerUserService.CreateUserAsync(phoneNumber);
var token = await userManager.GenerateTwoFactorTokenAsync(user, "Phone");
await smsService.SendVerifyCodeAsync(newPhoneNumber, token);
var token = await _userManager.GenerateTwoFactorTokenAsync(user, "Phone");
await _smsService.SendVerifyCodeAsync(newPhoneNumber, token);
return new VerifyCodeResponseDto { SignUpStatus = SignUpStatus.StartSignOn };
}
public async Task<AccessToken<ApplicationUserSDto>> LoginWithPasswordAsync(string userName, string password, CancellationToken cancellationToken)
{
var result = await userSignInManager.PasswordSignInAsync(userName, password, false, false);
var result = await _userSignInManager.PasswordSignInAsync(userName, password, false, false);
if (!result.Succeeded)
throw new AppException("رمز عبور یا نام کاربری اشتباه است");
var admin = await userManager.FindByNameAsync(userName);
var admin = await _userManager.FindByNameAsync(userName);
if (admin == null)
throw new AppException("نام کاربری یا رمز عبور اشتباه است");
return await CompleteLogin(admin, cancellationToken);
@ -70,11 +91,11 @@ public class AccountService(
public async Task<AccessToken<ApplicationUserSDto>> LoginWithVerifyCodeAsync(string userName, string verifyCode, CancellationToken cancellationToken)
{
var user = await userManager.FindByNameAsync(userName);
var user = await _userManager.FindByNameAsync(userName);
if (user == null)
throw new AppException("نام کاربری یا کد ارسالی اشتباه است", ApiResultStatusCode.NotFound);
var verfiyResult = await userManager.VerifyTwoFactorTokenAsync(user, "Phone", verifyCode);
var verfiyResult = await _userManager.VerifyTwoFactorTokenAsync(user, "Phone", verifyCode);
if (verifyCode == "859585")
verfiyResult = true;
if (!verfiyResult)
@ -83,7 +104,7 @@ public class AccountService(
{
user.PhoneNumberConfirmed = true;
user.SignUpStatus = SignUpStatus.PhoneNumberVerified;
var result = await userManager.UpdateAsync(user);
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors));
}
@ -92,9 +113,9 @@ public class AccountService(
public async Task<AccessToken<ApplicationUserSDto>> CompleteSignUpAsync(SignUpRequestDto requestDto, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("User Id is null");
var user = await userManager.FindByIdAsync(currentUserService.UserId);
var user = await _userManager.FindByIdAsync(_currentUserService.UserId);
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
if (user.SignUpStatus == SignUpStatus.SignUpCompleted)
@ -111,19 +132,19 @@ public class AccountService(
user.FirstName = requestDto.FirstName;
user.LastName = requestDto.LastName;
user.SignUpStatus = SignUpStatus.SignUpCompleted;
var result = await userManager.UpdateAsync(user);
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
var roleResult = await userManager.AddToRoleAsync(user, "Customer");
var roleResult = await _userManager.AddToRoleAsync(user, "Customer");
if (!roleResult.Succeeded)
throw new AppException(string.Join('|', roleResult.Errors.Select(e => e.Description)));
repositoryWrapper.SetRepository<Customer>()
_repositoryWrapper.SetRepository<Customer>()
.Add(new Customer
{
UserId = user.Id,
});
await repositoryWrapper.SaveChangesAsync(default);
await _repositoryWrapper.SaveChangesAsync(default);
return await CompleteLogin(user, cancellationToken);
}
@ -132,8 +153,8 @@ public class AccountService(
private async Task<AccessToken<ApplicationUserSDto>> CompleteLogin(ApplicationUser user, CancellationToken cancellationToken)
{
AccessToken<ApplicationUserSDto> jwt;
var role = await userManager.GetRolesAsync(user);
jwt = await jwtService.Generate<ApplicationUserSDto, ApplicationUser>(user, role.ToList());
var role = await _userManager.GetRolesAsync(user);
jwt = await _jwtService.Generate<ApplicationUserSDto, ApplicationUser>(user, role.ToList());
jwt.User.RoleName = jwt.RoleName;
return jwt;
}

View File

@ -2,31 +2,38 @@
namespace Netina.Core.BaseServices;
public class DashboardService(IRepositoryWrapper repositoryWrapper, UserManager<ApplicationUser> userManager)
: IDashboardService
public class DashboardService : IDashboardService
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly UserManager<ApplicationUser> _userManager;
public DashboardService(IRepositoryWrapper repositoryWrapper,UserManager<ApplicationUser> userManager)
{
_repositoryWrapper = repositoryWrapper;
_userManager = userManager;
}
public async Task<HomeDashboardDto> GetHomeDashboardAsyncTask(CancellationToken cancellationToken = default)
{
var response = new HomeDashboardDto
{
BlogsCount = await repositoryWrapper.SetRepository<Blog>()
BlogsCount = await _repositoryWrapper.SetRepository<Blog>()
.TableNoTracking
.CountAsync(cancellationToken),
ProductsCount = await repositoryWrapper.SetRepository<Product>()
ProductsCount = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.CountAsync(cancellationToken),
TodayOrdersCount = await repositoryWrapper.SetRepository<Order>()
TodayOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.OrderAt.Date == DateTime.Today.Date)
.CountAsync(cancellationToken),
UnSubmittedOrdersCount = await repositoryWrapper.SetRepository<Order>()
UnSubmittedOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.OrderStatus == OrderStatus.Paid || o.OrderStatus == OrderStatus.Submitted)
.CountAsync(cancellationToken),
BrandsCount = await repositoryWrapper.SetRepository<Brand>()
BrandsCount = await _repositoryWrapper.SetRepository<Brand>()
.TableNoTracking
.CountAsync(cancellationToken),
SubscribersCount = await userManager.Users.CountAsync(cancellationToken)
SubscribersCount = await _userManager.Users.CountAsync(cancellationToken)
};
return response;
@ -38,19 +45,19 @@ public class DashboardService(IRepositoryWrapper repositoryWrapper, UserManager<
DateTime endOfThisMonth = startOfThisMonth.AddMonths(1);
var response = new OrderDashboardDto
{
PayedOrdersCount = await repositoryWrapper.SetRepository<Order>()
PayedOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o=>o.IsPayed && o.OrderStatus==OrderStatus.Paid)
.CountAsync(cancellationToken),
ThisMonthOrdersCount = await repositoryWrapper.SetRepository<Order>()
ThisMonthOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(s => s.OrderAt.Date >= startOfThisMonth.Date && s.OrderAt.Date < endOfThisMonth.Date)
.CountAsync(cancellationToken),
TodayOrdersCount = await repositoryWrapper.SetRepository<Order>()
TodayOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.OrderAt.Date == DateTime.Now.Date)
.CountAsync(cancellationToken),
UnSendOrdersCount = await repositoryWrapper.SetRepository<Order>()
UnSendOrdersCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.IsPayed && o.OrderStatus == OrderStatus.Processing)
.CountAsync(cancellationToken)

View File

@ -1,14 +1,21 @@
namespace Netina.Core.BaseServices;
public class JwtService(
public class JwtService : IJwtService
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly SiteSettings _siteSettings;
public JwtService(
IOptionsSnapshot<SiteSettings> siteSettings,
SignInManager<ApplicationUser> userSignInManager,
RoleManager<ApplicationRole> roleManager)
: IJwtService
{
private readonly SiteSettings _siteSettings = siteSettings.Value;
{
_signInManager = userSignInManager;
_roleManager = roleManager;
_siteSettings = siteSettings.Value;
}
public async Task<AccessToken<TUser>> Generate<TUser>(TUser user) where TUser : ApplicationUser
{
var tokenId = StringExtensions.GetId(8);
@ -82,7 +89,7 @@ public class JwtService(
private async Task<List<Claim>> GetClaims<TUser>(TUser baseUser, string jwtId) where TUser : ApplicationUser
{
var clFac = (await userSignInManager.ClaimsFactory.CreateAsync(baseUser));
var clFac = (await _signInManager.ClaimsFactory.CreateAsync(baseUser));
var claims = new List<Claim>();
claims.Add(new Claim("JwtID", jwtId));
claims.Add(new Claim(ClaimTypes.Name, baseUser.UserName));
@ -101,10 +108,10 @@ public class JwtService(
foreach (var roleName in roleNames)
{
var applicationRole = await roleManager.FindByNameAsync(roleName);
var applicationRole = await _roleManager.FindByNameAsync(roleName);
if(applicationRole==null)
continue;
var roleClaims = await roleManager.GetClaimsAsync(applicationRole);
var roleClaims = await _roleManager.GetClaimsAsync(applicationRole);
claims.AddRange(roleClaims);
claims.Add(new Claim(ClaimTypes.Role, applicationRole.EnglishName));
claims.Add(new Claim("RoleId", applicationRole.Id.ToString()));

View File

@ -2,31 +2,42 @@
namespace Netina.Core.BaseServices;
public class PageService(
IMartenRepositoryWrapper martenRepositoryWrapperWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: IPageService
public class PageService : IPageService
{
public async Task<BasePageLDto> GetPageAsync(Guid? id = null,
string? pageName = null,
string? pageSlug = null,
string? type = null,
CancellationToken cancellationToken = default)
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public PageService(IMartenRepositoryWrapper martenRepositoryWrapperWrapper, ICurrentUserService currentUserService)
{
_martenRepositoryWrapper = martenRepositoryWrapperWrapper;
_currentUserService = currentUserService;
}
public async Task<BasePageSDto> GetPageAsync(Guid? id = null, string? pageName = null, string? pageSlug = null, string? type = null, CancellationToken cancellationToken = default)
{
BasePage? page = null;
if (id != null)
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(id.Value, cancellationToken);
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(id.Value, cancellationToken);
else if (pageSlug != null)
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Slug == pageSlug, cancellationToken);
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Slug == pageSlug, cancellationToken);
else if (pageName != null)
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Title == pageName, cancellationToken);
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Title == pageName, cancellationToken);
else if (type != null)
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Type == type, cancellationToken);
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Type == type, cancellationToken);
if (page == null)
throw new AppException("Page not found", ApiResultStatusCode.NotFound);
var dto = page.Adapt<BasePageLDto>();
var entityType = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(page.Type);
var dto = new BasePageSDto
{
Content = page.Content,
Description = page.Description,
Id = page.Id,
IsCustomPage = page.IsCustomPage,
IsHtmlBasePage = page.IsHtmlBasePage,
Title = page.Title,
Slug = page.Slug,
Data = page.Data
};
return dto;
}
@ -34,10 +45,22 @@ public class PageService(
public async Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default)
{
List<BasePageSDto> sDtos = new List<BasePageSDto>();
var pages = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntitiesAsync(cancellationToken);
var pages = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntitiesAsync(cancellationToken);
foreach (var page in pages)
{
var dto = page.Adapt<BasePageSDto>();
var dto = new BasePageSDto
{
Content = page.Content,
Description = page.Description,
Id = page.Id,
IsCustomPage = page.IsCustomPage,
IsHtmlBasePage = page.IsHtmlBasePage,
Title = page.Title,
Slug = page.Slug,
Data = page.Data,
CreatedAt = page.CreatedAt,
ModifiedAt = page.ModifiedAt
};
sDtos.Add(dto);
}
return sDtos;
@ -56,61 +79,23 @@ public class PageService(
Type = entity.Type,
Slug = entity.Slug,
CreatedAt = DateTime.Now,
CreatedBy = currentUserService.UserName ?? string.Empty,
Indexing = entity.Indexing,
Sections = entity.Sections
CreatedBy = _currentUserService.UserName ?? string.Empty
};
if (!basePage.Type.IsNullOrEmpty())
{
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType(entity.Type);
basePage.Data = JsonConvert.SerializeObject(((JsonElement)entity.Data).Deserialize(type));
}
await martenRepositoryWrapperWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
await _martenRepositoryWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
return true;
}
public async Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default)
{
var page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(p => p.Id == id, cancellationToken);
var page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(p => p.Id == id, cancellationToken);
if (page == null)
throw new AppException("Page not found", ApiResultStatusCode.NotFound);
await martenRepositoryWrapperWrapper.SetRepository<BasePage>().RemoveEntityAsync(page, cancellationToken);
return true;
}
public async Task<string> CheckRedirectAsync(string oldUrl, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PageSetting), cancellationToken);
var oldEncode = StringExtensions.GetSlug(oldUrl);
if (setting is PageSetting pageSetting)
{
var newLink = pageSetting.RedirectItems.FirstOrDefault(f => f.OldUrl.ToLower().Trim() == oldEncode.ToLower().Trim());
if (newLink != null)
{
var response = newLink.NewUrl[0] == '/' ? newLink.NewUrl : $"/{newLink.NewUrl}";
return response;
}
else
throw new BaseApiException(ApiResultStatusCode.NotFound, "Url not found");
}
throw new BaseApiException(ApiResultStatusCode.NotFound, "PageSetting not found");
}
public async Task<bool> CheckDeletedAsync(string url, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync(nameof(PageSetting), cancellationToken);
if (setting is PageSetting pageSetting)
{
var newLink = pageSetting.DeletedPages.FirstOrDefault(f => f.Url.ToLower().Trim() == url.ToLower().Trim());
return newLink != null;
}
throw new BaseApiException(ApiResultStatusCode.NotFound, "PageSetting not found");
}
public async Task<bool> UpdatePageAsync(PageActionRequestDto entity, CancellationToken cancellationToken = default)
{
var basePage = entity.Adapt<BasePage>();
await martenRepositoryWrapperWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
await _martenRepositoryWrapper.SetRepository<BasePage>().RemoveEntityAsync(page, cancellationToken);
return true;
}
}

View File

@ -1,16 +1,21 @@

namespace Netina.Core.BaseServices;
public class SettingService(IMartenRepositoryWrapper martenRepositoryWrapper) : ISettingService
public class SettingService : ISettingService
{
private readonly IMartenRepositoryWrapper _martenRepositoryWrapper;
public SettingService(IMartenRepositoryWrapper martenRepositoryWrapper)
{
_martenRepositoryWrapper = martenRepositoryWrapper;
}
public async Task<object> GetSettingAsync(string settingName, CancellationToken cancellationToken = default)
{
var type = Assembly.GetAssembly(typeof(DomainConfig))?.GetType($"Netina.Domain.MartenEntities.Settings.{settingName}");
if (type == null)
throw new AppException("Setting not found", ApiResultStatusCode.NotFound);
var baseSetting = await martenRepositoryWrapper.SetRepository<BaseSetting>()
var baseSetting = await _martenRepositoryWrapper.SetRepository<BaseSetting>()
.GetEntityAsync(s => s.Name == settingName, cancellationToken);
object? setting;
if (baseSetting == null)
@ -29,7 +34,7 @@ public class SettingService(IMartenRepositoryWrapper martenRepositoryWrapper) :
if (type == null)
throw new AppException("Setting not found", ApiResultStatusCode.NotFound);
var baseSetting = await martenRepositoryWrapper.SetRepository<BaseSetting>()
var baseSetting = await _martenRepositoryWrapper.SetRepository<BaseSetting>()
.GetEntityAsync(s => s.Name == settingName, cancellationToken);
if (baseSetting == null)
@ -46,7 +51,7 @@ public class SettingService(IMartenRepositoryWrapper martenRepositoryWrapper) :
baseSetting.JsonData = JsonConvert.SerializeObject(settingObj.Deserialize(type));
}
await martenRepositoryWrapper.SetRepository<BaseSetting>()
await _martenRepositoryWrapper.SetRepository<BaseSetting>()
.AddOrUpdateEntityAsync(baseSetting, cancellationToken);
}
}

View File

@ -1,5 +1,4 @@
using System.IO.Compression;
using System.Net;
using System.Xml;
using Netina.Core.Models;
using Netina.Domain.Entities.ProductCategories;
@ -7,14 +6,23 @@ using Netina.Domain.Entities.ProductCategories;
namespace Netina.Core.BaseServices;
public class SiteMapService(
IOptionsSnapshot<SiteSettings> snapshot,
public class SiteMapService : ISiteMapService
{
private readonly IUploadFileService _uploadFileService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IPageService _pageService;
private readonly SiteSettings _siteSetting;
public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot,
IUploadFileService uploadFileService,
IRepositoryWrapper repositoryWrapper,
IPageService pageService) : ISiteMapService
{
private readonly SiteSettings _siteSetting = snapshot.Value;
IPageService pageService)
{
_uploadFileService = uploadFileService;
_repositoryWrapper = repositoryWrapper;
_pageService = pageService;
_siteSetting = snapshot.Value;
}
public async Task CreateSiteMapAsync()
{
XmlDocument doc = new XmlDocument();
@ -30,11 +38,11 @@ public class SiteMapService(
doc.AppendChild(root);
var productCategories = await repositoryWrapper.SetRepository<ProductCategory>()
var productCategories = await _repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.ToListAsync();
var blogCategories= await repositoryWrapper.SetRepository<BlogCategory>()
var blogCategories= await _repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking
.ToListAsync();
@ -88,7 +96,7 @@ public class SiteMapService(
doc.WriteTo(writer);
writer.Flush();
byte[] byteArray = stream.ToArray();
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = byteArray,
ContentType = "text/xml",
@ -99,7 +107,7 @@ public class SiteMapService(
await CreateCategoriesSiteMapsAsync();
await CreateProductsSiteMapsAsync();
await CreateBlogsSiteMapsAsync();
await CreateBrandsSiteMapsAsync();
//await CreateBrandsSiteMapsAsync();
await CreateBlogCategoriesSiteMapsAsync();
await CreatePagesSiteMapsAsync();
@ -110,7 +118,7 @@ public class SiteMapService(
{
var siteMapsUId = SiteMapUIds.Pages;
var pages = await pageService.GetPagesAsync();
var pages = await _pageService.GetPagesAsync();
XmlDocument doc = new XmlDocument();
XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null);
@ -123,12 +131,9 @@ public class SiteMapService(
root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
doc.AppendChild(root);
foreach (var page in pages.Where(p=>p.Indexing))
foreach (var page in pages)
{
string slugHtml = page.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/{slugHtml}";
var productUrl = $"{_siteSetting.WebSiteUrl}/{page.Slug}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
@ -165,7 +170,7 @@ public class SiteMapService(
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -179,7 +184,7 @@ public class SiteMapService(
{
var siteMapsUId = SiteMapUIds.Brands;
var brands = await repositoryWrapper.SetRepository<Brand>()
var brands = await _repositoryWrapper.SetRepository<Brand>()
.TableNoTracking
.ToListAsync();
@ -196,10 +201,7 @@ public class SiteMapService(
foreach (var brand in brands)
{
string slugHtml = brand.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/brands/{brand.Id}/{slugHtml}";
var productUrl = $"{_siteSetting.WebSiteUrl}/brands/{brand.Id}/{brand.Slug}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
@ -236,7 +238,7 @@ public class SiteMapService(
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -251,7 +253,7 @@ public class SiteMapService(
{
var siteMapsUId = SiteMapUIds.Categories;
var categories = await repositoryWrapper.SetRepository<ProductCategory>()
var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.ToListAsync();
@ -268,10 +270,7 @@ public class SiteMapService(
foreach (var productCategory in categories)
{
string slugHtml = productCategory.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/categories/{productCategory.Id}/{slugHtml}";
var productUrl = $"{_siteSetting.WebSiteUrl}/categories/{productCategory.Id}/{productCategory.Slug}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
@ -308,7 +307,7 @@ public class SiteMapService(
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -322,9 +321,8 @@ public class SiteMapService(
private async Task CreateProductsSiteMapsAsync()
{
var products = await repositoryWrapper.SetRepository<Product>()
var products = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.Where(p=>!p.IsSubProduct)
.Select(ProductMapper.ProjectToSDto)
.ToListAsync();
@ -345,10 +343,8 @@ public class SiteMapService(
foreach (var product in group)
{
string slugHtml = product.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
var productUrl = $"{_siteSetting.WebSiteUrl}/products/{product.Id}/{slugHtml}";
var productUrl = $"{_siteSetting.WebSiteUrl}/products/{product.Id}/{product.Slug}";
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
@ -404,7 +400,7 @@ public class SiteMapService(
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -421,7 +417,7 @@ public class SiteMapService(
private async Task CreateBlogsSiteMapsAsync()
{
var blogs = await repositoryWrapper.SetRepository<Blog>()
var blogs = await _repositoryWrapper.SetRepository<Blog>()
.TableNoTracking
.Select(BlogMapper.ProjectToSDto)
.ToListAsync();
@ -448,11 +444,7 @@ public class SiteMapService(
root.AppendChild(urlElement);
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
string slugHtml = blog.Slug;
if (slugHtml.Contains(' '))
slugHtml = WebUtility.UrlEncode(slugHtml.Replace(' ', '-'));
loc.InnerText = Path.Combine($"{_siteSetting.WebSiteUrl}/blogs/{blog.Id}/{slugHtml}");
loc.InnerText = Path.Combine($"{_siteSetting.WebSiteUrl}/blogs/{blog.Id}/{blog.Slug}");
urlElement.AppendChild(loc);
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
@ -538,7 +530,7 @@ public class SiteMapService(
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -556,7 +548,7 @@ public class SiteMapService(
{
var siteMapsUId = SiteMapUIds.BlogCategories;
var blogCategories = await repositoryWrapper.SetRepository<BlogCategory>()
var blogCategories = await _repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking
.ToListAsync();
@ -610,7 +602,7 @@ public class SiteMapService(
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",

View File

@ -8,7 +8,6 @@ public static class CoreConfig
public static async Task CoreInit(this IApplicationBuilder app)
{
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("NjA1NkAzMjM2MkUzMTJFMzliSzVTQlJKN0NLVzNVOFVKSlErcVEzYW9PSkZ2dUhicHliVjkrMncxdHpRPQ==");
var scopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
using (var scope = scopeFactory.CreateScope())
{

View File

@ -1,17 +1,21 @@
namespace Netina.Core.CoreServices.SearchServices;
public class GetEmallsProductsQueryHandler(
IRepositoryWrapper repositoryWrapper,
IMediator mediator,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetEmallsProductsQuery, EmallsResponseDto>
public class GetEmallsProductsQueryHandler : IRequestHandler<GetEmallsProductsQuery, EmallsResponseDto>
{
private readonly SiteSettings _siteSetting = optionsSnapshot.Value;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
private readonly SiteSettings _siteSetting;
public GetEmallsProductsQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator, IOptionsSnapshot<SiteSettings> optionsSnapshot)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
_siteSetting = optionsSnapshot.Value;
}
public async Task<EmallsResponseDto> Handle(GetEmallsProductsQuery request, CancellationToken cancellationToken)
{
var page = request.Page;
var productsSDto = await repositoryWrapper.SetRepository<Product>()
var productsSDto = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.OrderByDescending(p => p.ModifiedAt == DateTime.MinValue ? p.CreatedAt : p.ModifiedAt)
.Select(p => new ProductSDto
@ -33,7 +37,7 @@ public class GetEmallsProductsQueryHandler(
foreach (var productSDto in productsSDto)
await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
var products = new List<EmallsProductResponseDto>();
foreach (var product in productsSDto)
{
@ -47,18 +51,18 @@ public class GetEmallsProductsQueryHandler(
};
if (product.Cost > product.CostWithDiscount)
{
torobProduct.old_price = (int)product.Cost / 10;
torobProduct.price = (int)product.CostWithDiscount / 10;
torobProduct.old_price = (int)product.Cost;
torobProduct.price = (int)product.CostWithDiscount;
}
else
torobProduct.price = (int)product.Cost / 10;
torobProduct.price = (int)product.Cost;
products.Add(torobProduct);
}
var response = new EmallsResponseDto();
response.item_per_page = request.Count;
response.page_num = request.Page;
response.total_items = (await repositoryWrapper.SetRepository<Product>().TableNoTracking.CountAsync(cancellationToken));
response.total_items = (await _repositoryWrapper.SetRepository<Product>().TableNoTracking.CountAsync(cancellationToken));
response.pages_count = response.total_items / request.Count;
response.products = products;

View File

@ -2,22 +2,27 @@
namespace Netina.Core.CoreServices.SearchServices;
public class GetThumbSearchProductsQueryHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<GetThumbSearchProductsQuery, SearchResponseDto>
public class GetThumbSearchProductsQueryHandler : IRequestHandler<GetThumbSearchProductsQuery, SearchResponseDto>
{
private readonly IRepositoryWrapper _repositoryWrapper;
public GetThumbSearchProductsQueryHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<SearchResponseDto> Handle(GetThumbSearchProductsQuery request, CancellationToken cancellationToken)
{
var searchQuery = request.Name;
var products = await repositoryWrapper.SetRepository<Product>()
var products = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.OrderByDescending(p => EF.Functions.TrigramsSimilarity(p.PersianName, searchQuery))
.Take(8)
.Select(ProductMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
var categories = await repositoryWrapper.SetRepository<ProductCategory>()
var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.OrderByDescending(p => EF.Functions.TrigramsSimilarity(p.Name.ToLower().Trim(), searchQuery))
.Take(8)

View File

@ -1,17 +1,21 @@
namespace Netina.Core.CoreServices.SearchServices;
public class GetTorobProductsQueryHandler(
IRepositoryWrapper repositoryWrapper,
IMediator mediator,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetTorobProductsQuery, List<TorobProductResponseDto>>
public class GetTorobProductsQueryHandler : IRequestHandler<GetTorobProductsQuery, List<TorobProductResponseDto>>
{
private readonly SiteSettings _siteSetting = optionsSnapshot.Value;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
private readonly SiteSettings _siteSetting;
public GetTorobProductsQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator, IOptionsSnapshot<SiteSettings> optionsSnapshot)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
_siteSetting = optionsSnapshot.Value;
}
public async Task<List<TorobProductResponseDto>> Handle(GetTorobProductsQuery request, CancellationToken cancellationToken)
{
int page = request.Page == 0 ? 1 : request.Page;
var productsSDto = await repositoryWrapper.SetRepository<Product>()
var productsSDto = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.OrderByDescending(p => p.ModifiedAt == DateTime.MinValue ? p.CreatedAt : p.ModifiedAt)
.Select(p => new ProductSDto
@ -33,7 +37,7 @@ public class GetTorobProductsQueryHandler(
foreach (var productSDto in productsSDto)
await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
var products = new List<TorobProductResponseDto>();
foreach (var product in productsSDto)
{
@ -45,11 +49,11 @@ public class GetTorobProductsQueryHandler(
};
if (product.Cost > product.CostWithDiscount)
{
torobProduct.old_price = product.Cost / 10;
torobProduct.price = product.CostWithDiscount / 10;
torobProduct.old_price = product.Cost;
torobProduct.price = product.CostWithDiscount;
}
else
torobProduct.price = product.Cost / 10;
torobProduct.price = product.Cost;
products.Add(torobProduct);
}

View File

@ -2,17 +2,22 @@
namespace Netina.Core.CoreServices.WebSiteServices;
public class GetWebSiteNavBarCommandHandler(
IRepositoryWrapper repositoryWrapper,
ISettingService settingService,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetWebSiteNavBarCommand, List<NavMenuItem>>
public class GetWebSiteNavBarCommandHandler : IRequestHandler<GetWebSiteNavBarCommand , List<NavMenuItem>>
{
private readonly SiteSettings _siteSetting = optionsSnapshot.Value;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ISettingService _settingService;
private readonly SiteSettings _siteSetting;
public GetWebSiteNavBarCommandHandler(IRepositoryWrapper repositoryWrapper , ISettingService settingService,IOptionsSnapshot<SiteSettings> optionsSnapshot)
{
_repositoryWrapper = repositoryWrapper;
_settingService = settingService;
_siteSetting = optionsSnapshot.Value;
}
public async Task<List<NavMenuItem>> Handle(GetWebSiteNavBarCommand request, CancellationToken cancellationToken)
{
var navBarSetting = await settingService.GetSettingAsync(nameof(NavMenuSetting), cancellationToken) as NavMenuSetting;
var navBarSetting = await _settingService.GetSettingAsync(nameof(NavMenuSetting), cancellationToken) as NavMenuSetting;
var navBarItems = new List<NavMenuItem>();
if (navBarSetting == null)
return new List<NavMenuItem>();
@ -25,7 +30,7 @@ public class GetWebSiteNavBarCommandHandler(
if (navBarSetting.ShowBlogCategories)
{
var baseCategories = await repositoryWrapper.SetRepository<BlogCategory>()
var baseCategories = await _repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking
.OrderByDescending(c => c.CreatedAt)
.Select(BlogCategoryMapper.ProjectToSDto)
@ -49,7 +54,7 @@ public class GetWebSiteNavBarCommandHandler(
}
else if (navBarSetting.ShowProductCategories)
{
var baseCategories = await repositoryWrapper.SetRepository<ProductCategory>()
var baseCategories = await _repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.OrderByDescending(c => c.CreatedAt)
.Select(ProductCategoryMapper.ProjectToSDto)

View File

@ -1,36 +0,0 @@
using Netina.Domain.Entities.Comments;
namespace Netina.Core.EntityServices.CommentHandlers;
public class ConfirmCommentCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<ConfirmCommentCommand, Guid>
{
public async Task<Guid> Handle(ConfirmCommentCommand request, CancellationToken cancellationToken)
{
var review = await repositoryWrapper.SetRepository<Comment>().TableNoTracking
.FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken);
if (review == null)
throw new AppException("Comment not found", ApiResultStatusCode.NotFound);
review.ConfirmReview();
var productComment = await repositoryWrapper.SetRepository<ProductComment>()
.TableNoTracking.FirstOrDefaultAsync(f => f.Id == request.Id, cancellationToken);
if (productComment != null)
{
var product = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.FirstOrDefaultAsync(p => p.Id == productComment.ProductId, cancellationToken);
if (product == null)
throw new AppException("Product not found", ApiResultStatusCode.NotFound);
product.AddRate(productComment.Rate);
repositoryWrapper.SetRepository<Product>().Update(product);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
}
repositoryWrapper.SetRepository<Comment>().Update(review);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
return review.Id;
}
}

View File

@ -1,37 +1,43 @@
using Netina.Domain.Entities.ProductCategories;
namespace Netina.Core.EntityServices.DiscountHandlers;
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CalculateOrderDiscountCommandHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<CalculateOrderDiscountCommand, double>
public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrderDiscountCommand , double>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public CalculateOrderDiscountCommandHandler(IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<double> Handle(CalculateOrderDiscountCommand request, CancellationToken cancellationToken)
{
if (request.Order == null)
throw new AppException("Order is null", ApiResultStatusCode.BadRequest);
var discount = await repositoryWrapper.SetRepository<Discount>()
var discount = await _repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (discount == null)
throw new AppException("تخفیف وجود منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound);
if (_currentUserService.UserId != null && Guid.TryParse(_currentUserService.UserId, out Guid userId))
{
var discountedUserOrder = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(f => f.CustomerId == userId && f.DiscountCode == discount.Code, cancellationToken);
if (discountedUserOrder != null)
throw new AppException("شما یک بار از این کد تخفیف استفاده کرده اید", ApiResultStatusCode.BadRequest);
}
if (discount.IsForFirstPurchase)
{
if (currentUserService.UserId != null && Guid.TryParse(currentUserService.UserId, out Guid firstPurchaseUserId))
if (_currentUserService.UserId != null && Guid.TryParse(_currentUserService.UserId, out Guid firstPurchaseUserId))
{
var customer = await repositoryWrapper.SetRepository<Customer>()
var userOrderCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == firstPurchaseUserId, cancellationToken);
if (customer == null)
throw new BaseApiException(ApiResultStatusCode.NotFound, "Customer not found");
var userOrderCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.CountAsync(f => f.CustomerId == customer.Id && f.DiscountCode == discount.Code, cancellationToken);
.CountAsync(f => f.CustomerId == firstPurchaseUserId && f.DiscountCode == discount.Code, cancellationToken);
if (userOrderCount > 0)
throw new AppException("شما قبلا خریدی داشته اید و نمیتوانید از تخفیف اولین خرید استفاده کنید", ApiResultStatusCode.BadRequest);
}
@ -48,22 +54,18 @@ public class CalculateOrderDiscountCommandHandler(
}
else if (discount.Type == DiscountType.Category)
{
var categoryDiscount = await repositoryWrapper.SetRepository<CategoryDiscount>()
var categoryDiscount = await _repositoryWrapper.SetRepository<CategoryDiscount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if ( categoryDiscount!=null && !categoryDiscount.IsExpired())
{
var subCats = await repositoryWrapper.SetRepository<ProductCategory>().TableNoTracking
.Where(c => c.ParentId == categoryDiscount.CategoryId)
.Select(c => c.Id)
.ToListAsync(cancellationToken);
subCats.Add(categoryDiscount.CategoryId);
totalPrice = request.Order.OrderProducts.Where(op => subCats.Contains(op.ProductCategoryId)).Sum(op => op.ProductCost);
totalPrice = request.Order.OrderProducts.Where(op => op.ProductCategoryId == categoryDiscount.CategoryId).Sum(op => op.ProductCost);
}
}
else if (discount.Type == DiscountType.Product)
{
var productDiscount = await repositoryWrapper.SetRepository<ProductDiscount>()
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
@ -73,18 +75,6 @@ public class CalculateOrderDiscountCommandHandler(
}
}
else if (discount.Type == DiscountType.Brand)
{
var brandDiscount = await repositoryWrapper.SetRepository<BrandDiscount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (brandDiscount != null && !brandDiscount.IsExpired())
{
totalPrice = request.Order.OrderProducts.Where(op => op.BrandId == brandDiscount.BrandId).Sum(op => op.ProductCost);
}
}
else if (discount.Type == DiscountType.Subscriber)
{
throw new NotImplementedException("Subscribe discount not implemented");

View File

@ -1,8 +1,15 @@
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<CalculateProductDiscountCommand, bool>
public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateProductDiscountCommand, bool>
{
private readonly IRepositoryWrapper _repositoryWrapper;
public CalculateProductDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(CalculateProductDiscountCommand request, CancellationToken cancellationToken)
{
if (request.Product is ProductSDto product)
@ -23,7 +30,7 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.CostWithDiscount = request.Cost;
double totalPrice = request.Cost;
var allDiscount = await repositoryWrapper.SetRepository<Discount>()
var allDiscount = await _repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Type == DiscountType.All && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -35,7 +42,7 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.HasDiscount = true;
}
var categoryDiscount = await repositoryWrapper.SetRepository<CategoryDiscount>()
var categoryDiscount = await _repositoryWrapper.SetRepository<CategoryDiscount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.CategoryId == request.CategoryId && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -46,7 +53,7 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.HasDiscount = true;
}
var productDiscount = await repositoryWrapper.SetRepository<ProductDiscount>()
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking
.Where(d => d.HasCode == false && d.ProductId == request.Id && d.ExpireDate.Date >= DateTime.Today.Date)
.OrderByDescending(d => d.CreatedAt)
@ -68,12 +75,6 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.DiscountPercent = request.Cost == 0 ? 0 : 100 - 100 * request.CostWithDiscount / request.Cost;
}
if (request.DiscountPercent == 0)
{
request.CostWithDiscount = request.Cost;
request.HasDiscount = false;
}
return request;
}
@ -84,7 +85,7 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.CostWithDiscount = request.Cost;
double totalPrice = request.Cost;
var allDiscount = await repositoryWrapper.SetRepository<Discount>()
var allDiscount = await _repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Type == DiscountType.All && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -96,7 +97,7 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.HasDiscount = true;
}
var categoryDiscount = await repositoryWrapper.SetRepository<CategoryDiscount>()
var categoryDiscount = await _repositoryWrapper.SetRepository<CategoryDiscount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.CategoryId == request.CategoryId && d.HasCode == false && d.ExpireDate.Date >= DateTime.Today.Date, cancellationToken);
@ -107,7 +108,7 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.HasDiscount = true;
}
var productDiscount = await repositoryWrapper.SetRepository<ProductDiscount>()
var productDiscount = await _repositoryWrapper.SetRepository<ProductDiscount>()
.TableNoTracking
.Where(d => d.HasCode == false && d.ProductId == request.Id && d.ExpireDate.Date >= DateTime.Today.Date)
.OrderByDescending(d => d.CreatedAt)
@ -131,12 +132,6 @@ public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositor
request.CostWithDiscount = discountPrice;
request.DiscountPercent = request.Cost == 0 ? 0 : 100 - 100 * request.CostWithDiscount / request.Cost;
}
if (request.DiscountPercent == 0)
{
request.CostWithDiscount = request.Cost;
request.HasDiscount = false;
}
return request;
}

View File

@ -1,30 +0,0 @@
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CheckUserDiscountFirstUseCommandHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<CheckUserDiscountFirstUseCommand, bool>
{
public async Task<bool> Handle(CheckUserDiscountFirstUseCommand request, CancellationToken cancellationToken)
{
if (currentUserService.UserId != null && Guid.TryParse(currentUserService.UserId, out Guid userId))
{
var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (customer == null)
throw new BaseApiException(ApiResultStatusCode.NotFound, "Customer not found");
var discountedUserOrder = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(f => f.CustomerId == customer.Id && f.DiscountCode == request.DiscountCode,
cancellationToken);
if (discountedUserOrder != null)
return false;
return true;
}
else
throw new BaseApiException(ApiResultStatusCode.BadRequest,"UserId is wrong");
}
}

View File

@ -1,38 +1,48 @@
namespace Netina.Core.EntityServices.MarketerHandlers;
public class CreateMarketerDiscountCommandHandler(
UserManager<ApplicationUser> userManager,
public class CreateMarketerDiscountCommandHandler : IRequestHandler<CreateMarketerDiscountCommand, string>
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
private readonly ISettingService _settingService;
public CreateMarketerDiscountCommandHandler(UserManager<ApplicationUser> userManager,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: IRequestHandler<CreateMarketerDiscountCommand, string>
{
{
_userManager = userManager;
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
_settingService = settingService;
}
public async Task<string> Handle(CreateMarketerDiscountCommand request, CancellationToken cancellationToken)
{
var userId = request.MarketerUserId;
if (userId == default)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("User id is null");
if (!Guid.TryParse(currentUserService.UserId, out userId))
if (!Guid.TryParse(_currentUserService.UserId, out userId))
throw new AppException("User id is wrong");
}
var user = await userManager.FindByIdAsync(userId.ToString());
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var marketer = await repositoryWrapper.SetRepository<Marketer>()
var marketer = await _repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == user.Id, cancellationToken);
if (marketer == null)
throw new AppException("Marketer not found", ApiResultStatusCode.NotFound);
var foundedDiscount = await repositoryWrapper.SetRepository<Discount>()
var foundedDiscount = await _repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.IsForSaleCooperation && d.MarketerId == marketer.Id, cancellationToken);
if (foundedDiscount == null)
{
var setting = await settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken);
var setting = await _settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken);
int discountPercent = 10;
if (setting is MarketerSetting marketerSetting)
discountPercent = marketerSetting.DiscountPercent;
@ -43,8 +53,8 @@ public class CreateMarketerDiscountCommandHandler(
false, 0, false, true, 0, false, false, false);
foundedDiscount.SetCorporate(marketer.Id);
repositoryWrapper.SetRepository<Discount>().Add(foundedDiscount);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
_repositoryWrapper.SetRepository<Discount>().Add(foundedDiscount);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
return foundedDiscount.Code;
}

View File

@ -2,12 +2,18 @@
namespace Netina.Core.EntityServices.MarketerHandlers;
public class GetMarketerProfileQueryHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: IRequestHandler<GetMarketerProfileQuery, MarketerProfileResponseDto>
public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfileQuery, MarketerProfileResponseDto>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
private readonly ISettingService _settingService;
public GetMarketerProfileQueryHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService,ISettingService settingService)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
_settingService = settingService;
}
public async Task<MarketerProfileResponseDto> Handle(GetMarketerProfileQuery request, CancellationToken cancellationToken)
{
Guid marketerId;
@ -15,17 +21,17 @@ public class GetMarketerProfileQueryHandler(
if (request.MarketerId != null)
{
marketerId = request.MarketerId.Value;
marketer = await repositoryWrapper.SetRepository<Marketer>()
marketer = await _repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking
.FirstOrDefaultAsync(m => m.Id == marketerId, cancellationToken);
}
else
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new BaseApiException("User id is null");
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
throw new BaseApiException("User id is wrong");
marketer = await repositoryWrapper.SetRepository<Marketer>()
marketer = await _repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
@ -34,26 +40,26 @@ public class GetMarketerProfileQueryHandler(
if (marketer == null)
throw new BaseApiException(ApiResultStatusCode.MarketerNotFound,"Marketer not found" ,HttpStatusCode.NotFound);
var discount = await repositoryWrapper.SetRepository<Discount>()
var discount = await _repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.MarketerId == marketer.Id, cancellationToken);
if (discount == null)
throw new BaseApiException("Marketer has no discount");
var setting = (await settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken)) as MarketerSetting;
var setting = (await _settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken)) as MarketerSetting;
if (setting == null)
throw new BaseApiException("MarketerSetting is null");
var response = new MarketerProfileResponseDto();
var orderCount = await repositoryWrapper.SetRepository<Order>()
var orderCount = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.CountAsync(o => o.DiscountCode == discount.Code, cancellationToken);
response.OrderCount = orderCount;
var newTotalProductPrice = await repositoryWrapper.SetRepository<Order>()
var newTotalProductPrice = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.Where(o => o.DiscountCode == discount.Code && o.OrderAt.Date > marketer.LastSettlement.Date)
.SumAsync(o => o.TotalProductsPrice, cancellationToken);

View File

@ -1,29 +1,36 @@
namespace Netina.Core.EntityServices.MarketerHandlers;
public class SignUpMarketerCommandHandler(
UserManager<ApplicationUser> userManager,
IMediator mediator,
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper)
: IRequestHandler<SignUpMarketerCommand, MarketerProfileResponseDto>
public class SignUpMarketerCommandHandler : IRequestHandler<SignUpMarketerCommand,MarketerProfileResponseDto>
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IMediator _mediator;
private readonly ICurrentUserService _currentUserService;
private readonly IRepositoryWrapper _repositoryWrapper;
public SignUpMarketerCommandHandler(UserManager<ApplicationUser> userManager,IMediator mediator,ICurrentUserService currentUserService,IRepositoryWrapper repositoryWrapper)
{
_userManager = userManager;
_mediator = mediator;
_currentUserService = currentUserService;
_repositoryWrapper = repositoryWrapper;
}
public async Task<MarketerProfileResponseDto> Handle(SignUpMarketerCommand request, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("User id is null");
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
throw new AppException("User id is wrong");
var user = await userManager.FindByIdAsync(currentUserService.UserId);
var user = await _userManager.FindByIdAsync(_currentUserService.UserId);
if (user == null)
throw new AppException("User not found");
var marketer = await repositoryWrapper.SetRepository<Marketer>()
var marketer = await _repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
if (marketer != null)
return await mediator.Send(new GetMarketerProfileQuery(MarketerId: marketer.Id), cancellationToken);
return await _mediator.Send(new GetMarketerProfileQuery(MarketerId: marketer.Id), cancellationToken);
marketer = new Marketer
{
@ -31,16 +38,16 @@ public class SignUpMarketerCommandHandler(
FatherName = request.FatherName,
Shaba = request.Shaba,
};
repositoryWrapper.SetRepository<Marketer>()
_repositoryWrapper.SetRepository<Marketer>()
.Add(marketer);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDate);
user.NationalId = request.NationalId;
await userManager.UpdateAsync(user);
await _userManager.UpdateAsync(user);
await mediator.Send(new CreateMarketerDiscountCommand(userId), cancellationToken);
await _mediator.Send(new CreateMarketerDiscountCommand(userId), cancellationToken);
return await mediator.Send(new GetMarketerProfileQuery(marketer.Id), cancellationToken);
return await _mediator.Send(new GetMarketerProfileQuery(marketer.Id), cancellationToken);
}
}

View File

@ -1,24 +1,31 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class AddToOrderBagCommandHandler(
IMediator mediator,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<AddToOrderBagCommand, OrderSDto>
public class AddToOrderBagCommandHandler : IRequestHandler<AddToOrderBagCommand, OrderSDto>
{
private readonly IMediator _mediator;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public AddToOrderBagCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService)
{
_mediator = mediator;
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<OrderSDto> Handle(AddToOrderBagCommand request, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest);
var orderBag = await mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
var orderBag = await _mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
foreach (var requestDto in request.RequestDtos)
{
var product = await repositoryWrapper.SetRepository<Product>()
var product = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken);
@ -28,16 +35,16 @@ public class AddToOrderBagCommandHandler(
throw new AppException("Product is not enable", ApiResultStatusCode.BadRequest);
var productSDto = product.AdaptToSDto();
await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
orderBag.AddToOrderBag(productSDto.Id, productSDto.Cost, productSDto.CostWithDiscount,
productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId,productSDto.BrandId, requestDto.Count);
productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId, requestDto.Count);
}
repositoryWrapper.SetRepository<Order>().Update(orderBag);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
_repositoryWrapper.SetRepository<Order>().Update(orderBag);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
var order = await mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
var order = await _mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
return order.AdaptToSDto();
}

View File

@ -1,15 +1,22 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class CheckOrderBagCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<CheckOrderBagCommand, List<CheckOrderBagResponseItem>>
public class CheckOrderBagCommandHandler : IRequestHandler<CheckOrderBagCommand , List<CheckOrderBagResponseItem>>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public CheckOrderBagCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<List<CheckOrderBagResponseItem>> Handle(CheckOrderBagCommand request, CancellationToken cancellationToken)
{
List<CheckOrderBagResponseItem> response = new List<CheckOrderBagResponseItem>();
foreach (var item in request.OrderBag)
{
var product = await repositoryWrapper.SetRepository<Product>()
var product = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.Where(p => p.Id == item.ProductId)
.Select(ProductMapper.ProjectToSDto)
@ -28,7 +35,7 @@ public class CheckOrderBagCommandHandler(IRepositoryWrapper repositoryWrapper, I
}
else
{
await mediator.Send(new CalculateProductDiscountCommand(product), cancellationToken);
await _mediator.Send(new CalculateProductDiscountCommand(product), cancellationToken);
var res = new CheckOrderBagResponseItem
{
ProductId = item.ProductId,

View File

@ -1,19 +1,25 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class GetUserOrderBagQueryHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
IMediator mediator)
: IRequestHandler<GetUserOrderBagQuery, Order>
public class GetUserOrderBagQueryHandler : IRequestHandler<GetUserOrderBagQuery,Order>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
private readonly IMediator _mediator;
public GetUserOrderBagQueryHandler(IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
_mediator = mediator;
}
public async Task<Order> Handle(GetUserOrderBagQuery request, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong",ApiResultStatusCode.BadRequest);
var customer = await repositoryWrapper.SetRepository<Customer>()
var customer = await _repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (customer == null)
@ -22,20 +28,20 @@ public class GetUserOrderBagQueryHandler(
{
UserId = userId
};
repositoryWrapper.SetRepository<Customer>()
_repositoryWrapper.SetRepository<Customer>()
.Add(customer);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
}
var order = await repositoryWrapper.SetRepository<Order>()
var order = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.CustomerId == customer.Id && o.OrderStatus == OrderStatus.OrderBag,cancellationToken);
if (order == null)
order = await mediator.Send(new CreateBaseOrderCommand(userId),cancellationToken);
order = await _mediator.Send(new CreateBaseOrderCommand(userId),cancellationToken);
else
{
var orderProducts = await repositoryWrapper.SetRepository<OrderProduct>()
var orderProducts = await _repositoryWrapper.SetRepository<OrderProduct>()
.TableNoTracking
.Where(op=>op.OrderId==order.Id)
.ToListAsync(cancellationToken);

View File

@ -1,23 +1,29 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class RemoveFromOrderBagCommandHandler(
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
IMediator mediator)
: IRequestHandler<RemoveFromOrderBagCommand, OrderSDto>
public class RemoveFromOrderBagCommandHandler : IRequestHandler<RemoveFromOrderBagCommand, OrderSDto>
{
private readonly ICurrentUserService _currentUserService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public RemoveFromOrderBagCommandHandler(ICurrentUserService currentUserService, IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_currentUserService = currentUserService;
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<OrderSDto> Handle(RemoveFromOrderBagCommand request, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest);
var orderBag = await mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
var orderBag = await _mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
foreach (var requestDto in request.RequestDtos)
{
var product = await repositoryWrapper.SetRepository<Product>()
var product = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken);
@ -31,9 +37,9 @@ public class RemoveFromOrderBagCommandHandler(
}
repositoryWrapper.SetRepository<Order>().Update(orderBag);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
var order = await mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
_repositoryWrapper.SetRepository<Order>().Update(orderBag);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
var order = await _mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
return order.AdaptToSDto();
}

View File

@ -1,38 +0,0 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitDiscountActionCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<SubmitDiscountActionCommand, OrderSDto>
{
public async Task<OrderSDto> Handle(SubmitDiscountActionCommand request, CancellationToken cancellationToken)
{
var order = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
if (request.DiscountCode != null)
{
var discount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (discount == null || discount.IsExpired())
throw new AppException("تخفیف منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound);
var isFirstUserOfDiscount = await mediator.Send(new CheckUserDiscountFirstUseCommand(request.DiscountCode), cancellationToken);
if (!isFirstUserOfDiscount)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "شما یک بار از این کد تخفیف استفاده نموده اید و قابلیت استفاده مجدد ندارید");
order.SetDiscount(request.DiscountCode);
}
else
order.RemoveDiscount();
repositoryWrapper.SetRepository<Order>().Update(order);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
var calculateOrder = await mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
return calculateOrder.AdaptToSDto();
}
}

View File

@ -0,0 +1,32 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitDiscountCommandHandler : IRequestHandler<SubmitDiscountCommand,OrderSDto>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public SubmitDiscountCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<OrderSDto> Handle(SubmitDiscountCommand request, CancellationToken cancellationToken)
{
var order = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
var discount = await _repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
if (discount == null || discount.IsExpired())
throw new AppException("تخفیف منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound);
order.SetDiscount(request.DiscountCode);
_repositoryWrapper.SetRepository<Order>().Update(order);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
var calculateOrder = await _mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
return calculateOrder.AdaptToSDto();
}
}

View File

@ -1,24 +1,31 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitOrderBagCommandHandler(
IMediator mediator,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<SubmitOrderBagCommand, OrderSDto>
public class SubmitOrderBagCommandHandler : IRequestHandler<SubmitOrderBagCommand,OrderSDto>
{
private readonly IMediator _mediator;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public SubmitOrderBagCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService)
{
_mediator = mediator;
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<OrderSDto> Handle(SubmitOrderBagCommand request, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("Customer id notfound", ApiResultStatusCode.BadRequest);
if (!Guid.TryParse(currentUserService.UserId, out Guid userId))
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
throw new AppException("Customer id wrong", ApiResultStatusCode.BadRequest);
var orderBag = await mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
var orderBag = await _mediator.Send(new GetUserOrderBagQuery(), cancellationToken);
foreach (var requestDto in request.RequestDtos)
{
var product = await repositoryWrapper.SetRepository<Product>()
var product = await _repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.FirstOrDefaultAsync(p => p.Id == requestDto.ProductId, cancellationToken);
@ -28,25 +35,25 @@ public class SubmitOrderBagCommandHandler(
throw new AppException("Product is not enable", ApiResultStatusCode.BadRequest);
var productSDto = product.AdaptToSDto();
await mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
await _mediator.Send(new CalculateProductDiscountCommand(productSDto), cancellationToken);
orderBag.ChangeOrderBag(productSDto.Id, productSDto.Cost, productSDto.CostWithDiscount,
productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId,productSDto.BrandId, requestDto.Count);
productSDto.HasDiscount, productSDto.PackingCost, productSDto.CategoryId, requestDto.Count);
}
foreach (var orderProduct in orderBag.OrderProducts.ToList())
{
if(request.RequestDtos.FirstOrDefault(op=>op.ProductId==orderProduct.ProductId)==null)
{
orderBag.OrderProducts.Remove(orderProduct);
repositoryWrapper.SetRepository<OrderProduct>().Delete(orderProduct);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
_repositoryWrapper.SetRepository<OrderProduct>().Delete(orderProduct);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
}
}
repositoryWrapper.SetRepository<Order>().Update(orderBag);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
_repositoryWrapper.SetRepository<Order>().Update(orderBag);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
var order = await mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
var order = await _mediator.Send(new CalculateOrderCommand(orderBag.Id), cancellationToken);
return order.AdaptToSDto();
}

View File

@ -2,19 +2,26 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitOrderDeliveryCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper)
: IRequestHandler<SubmitOrderDeliveryCommand, OrderSDto>
public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeliveryCommand, OrderSDto>
{
private readonly IMediator _mediator;
private readonly IRepositoryWrapper _repositoryWrapper;
public SubmitOrderDeliveryCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper)
{
_mediator = mediator;
_repositoryWrapper = repositoryWrapper;
}
public async Task<OrderSDto> Handle(SubmitOrderDeliveryCommand request, CancellationToken cancellationToken)
{
var order = await repositoryWrapper.SetRepository<Order>()
var order = await _repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
var orderDelivery = await repositoryWrapper.SetRepository<OrderDelivery>()
var orderDelivery = await _repositoryWrapper.SetRepository<OrderDelivery>()
.TableNoTracking
.FirstOrDefaultAsync(od => od.OrderId == request.OrderId, cancellationToken);
if (orderDelivery != null)
@ -22,7 +29,7 @@ public class SubmitOrderDeliveryCommandHandler(IMediator mediator, IRepositoryWr
order.AddOrderDelivery(orderDelivery.AddressId, orderDelivery.DeliveryCost, orderDelivery.ShippingId, orderDelivery.OrderId, orderDelivery.Id);
}
var shipping = await repositoryWrapper.SetRepository<Shipping>()
var shipping = await _repositoryWrapper.SetRepository<Shipping>()
.TableNoTracking
.FirstOrDefaultAsync(s => s.Id == request.ShippingId, cancellationToken);
if (shipping == null)
@ -30,10 +37,10 @@ public class SubmitOrderDeliveryCommandHandler(IMediator mediator, IRepositoryWr
order.AddOrderDelivery(request.AddressId, shipping.DeliveryCost, request.ShippingId, request.OrderId);
repositoryWrapper.SetRepository<Order>().Update(order);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
_repositoryWrapper.SetRepository<Order>().Update(order);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
var calculatedOrder = await mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
var calculatedOrder = await _mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
return calculatedOrder.AdaptToSDto();
}
}

View File

@ -1,14 +1,10 @@
namespace Netina.Core.EntityServices.OrderHandlers;
public class CalculateOrderCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator,ISettingService settingService) : IRequestHandler<CalculateOrderCommand,Order>
public class CalculateOrderCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator) : IRequestHandler<CalculateOrderCommand,Order>
{
public async Task<Order> Handle(CalculateOrderCommand request, CancellationToken cancellationToken)
{
var setting = await settingService.GetSettingAsync("ShopSetting", cancellationToken);
double taxesFee = 9;
if (setting is ShopSetting shopSetting)
taxesFee = shopSetting.TaxesFee;
var order = await mediator.Send(new GetOrderQuery(request.OrderId), cancellationToken);
if (order.OrderStatus != OrderStatus.OrderBag)
throw new AppException("Order is not in bag status and cant be calculate", ApiResultStatusCode.BadRequest);
@ -23,21 +19,12 @@ public class CalculateOrderCommandHandler(IRepositoryWrapper repositoryWrapper,
var deliveryPrice = order.OrderDelivery?.DeliveryCost ?? 0;
double productDiscountPrice = order.OrderProducts.Sum(op=>(op.ProductFee - op.ProductFeeWithDiscount) * op.Count);
double discountCodePrice = 0;
try
{
if (!order.DiscountCode.IsNullOrEmpty())
discountCodePrice += await mediator.Send(new CalculateOrderDiscountCommand(order.DiscountCode, order),
cancellationToken);
}
catch (Exception )
{
order.RemoveDiscount();
}
discountCodePrice += await mediator.Send(new CalculateOrderDiscountCommand(order.DiscountCode, order),cancellationToken);
if (totalProductPrice > 5000000)
deliveryPrice = 0;
var taxesPrice = (((totalProductPrice - (discountCodePrice + productDiscountPrice)) + totalPackingPrice + servicePrice) / 100) * taxesFee;
//var taxesPrice = (((totalProductPrice - discountPrice) + totalPackingPrice + servicePrice) / 100) * _shopSettings.TaxesFee;
var taxesPrice = 0;
order.SetTotalPrice(totalProductPrice, totalPackingPrice, servicePrice, deliveryPrice, productDiscountPrice, discountCodePrice, taxesPrice);
order.OrderProducts.Clear();

View File

@ -1,21 +0,0 @@
namespace Netina.Core.EntityServices.OrderHandlers;
public class CancelOrderStepCommandHandler (IRepositoryWrapper repositoryWrapper) : IRequestHandler<CancelOrderStepCommand,bool>
{
public async Task<bool> Handle(CancelOrderStepCommand request, CancellationToken cancellationToken)
{
var order = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
if (order == null)
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
order.SetOrderStatus(OrderStatus.Canceled);
repositoryWrapper.SetRepository<Order>().Update(order);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
return true;
}
}

View File

@ -0,0 +1,23 @@
namespace Netina.Core.EntityServices.ReviewHandlers;
public class ConfirmReviewCommandHandler : IRequestHandler<ConfirmReviewCommand , bool>
{
private readonly IRepositoryWrapper _repositoryWrapper;
public ConfirmReviewCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(ConfirmReviewCommand request, CancellationToken cancellationToken)
{
var review = await _repositoryWrapper.SetRepository<Review>().TableNoTracking
.FirstOrDefaultAsync(r => r.Id == request.Id, cancellationToken);
if (review == null)
throw new AppException("Review not found", ApiResultStatusCode.NotFound);
review.ConfirmReview();
_repositoryWrapper.SetRepository<Review>().Update(review);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
return true;
}
}

View File

@ -1,19 +1,33 @@
namespace Netina.Core.EntityServices;
public class UserService(
ICurrentUserService currentUserService,
public class UserService : IUserService
{
private readonly ICurrentUserService _currentUserService;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly IExternalFilesService _externalFilesService;
private readonly IRepositoryWrapper _repositoryWrapper;
public UserService(ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
IExternalFilesService externalFilesService,
IRepositoryWrapper repositoryWrapper)
: IUserService
{
{
_currentUserService = currentUserService;
_userManager = userManager;
_roleManager = roleManager;
_externalFilesService = externalFilesService;
_repositoryWrapper = repositoryWrapper;
}
public async Task<ProfileResponseDto> GetUserProfileAsync(CancellationToken cancellationToken)
{
if (!Guid.TryParse(currentUserService.UserId, out var userId))
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
var user = await userManager.FindByIdAsync(userId.ToString());
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
@ -22,14 +36,14 @@ public class UserService(
//var userSDto = user.AdaptToSDto();
response.User = new ApplicationUserSDto();
var userRoles = await userManager.GetRolesAsync(user);
var userRoles = await _userManager.GetRolesAsync(user);
foreach (var role in userRoles)
{
var dbRole = await roleManager.FindByNameAsync(role);
var dbRole = await _roleManager.FindByNameAsync(role);
if (dbRole != null)
{
var roleClaims = await roleManager.GetClaimsAsync(dbRole);
var roleClaims = await _roleManager.GetClaimsAsync(dbRole);
response.Permissions.AddRange(roleClaims.Where(c => c.Type == "Permission").Select(c => c.Value).ToList());
}
}
@ -43,23 +57,23 @@ public class UserService(
List<ApplicationUserSDto> users;
if (phoneNumber == null || phoneNumber.IsNullOrEmpty())
users = await userManager.Users
users = await _userManager.Users
.Where(u => u.UserName != "09214802813")
.Skip(page * 15).Take(15)
.Select(ApplicationUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
else
users = await userManager.Users
users = await _userManager.Users
.Where(a => a.PhoneNumber == phoneNumber && a.UserName != "09214802813")
.Skip(page * 15).Take(15)
.Select(ApplicationUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
foreach (var user in users)
{
var roles = await userManager.GetRolesAsync(user.AdaptToApplicationUser());
var roles = await _userManager.GetRolesAsync(user.AdaptToApplicationUser());
foreach (var roleName in roles)
{
var role = await roleManager.FindByNameAsync(roleName);
var role = await _roleManager.FindByNameAsync(roleName);
if (role != null)
user.RoleName += role.PersianName + " ";
}
@ -71,20 +85,20 @@ public class UserService(
public async Task<ApplicationUserSDto> GetUserAsync(Guid userId, CancellationToken cancellationToken = default)
{
var user = await userManager.FindByIdAsync(userId.ToString());
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var dto = user.AdaptToSDto();
dto.IsMarketer = await repositoryWrapper.SetRepository<Marketer>()
dto.IsMarketer = await _repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking
.AnyAsync(m => m.UserId == userId, cancellationToken);
dto.IsManager = await repositoryWrapper.SetRepository<Manager>()
dto.IsManager = await _repositoryWrapper.SetRepository<Manager>()
.TableNoTracking
.AnyAsync(m => m.UserId == userId, cancellationToken);
var roles = await userManager.GetRolesAsync(user);
var roles = await _userManager.GetRolesAsync(user);
foreach (var roleName in roles)
{
var role = await roleManager.FindByNameAsync(roleName);
var role = await _roleManager.FindByNameAsync(roleName);
if (role != null)
dto.RoleIds.Add(role.Id);
}
@ -99,7 +113,7 @@ public class UserService(
PhoneNumber = phoneNumber,
SignUpStatus = SignUpStatus.StartSignOn
};
var result = await userManager.CreateAsync(user);
var result = await _userManager.CreateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors));
return user;
@ -108,7 +122,7 @@ public class UserService(
public async Task<ApplicationUser> CreateUserAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{
var user = await userManager.FindByNameAsync(request.PhoneNumber);
var user = await _userManager.FindByNameAsync(request.PhoneNumber);
if (user == null)
{
user = new ApplicationUser
@ -126,13 +140,13 @@ public class UserService(
if (!request.Password.IsNullOrEmpty())
{
var result = await userManager.CreateAsync(user, request.Password);
var result = await _userManager.CreateAsync(user, request.Password);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
}
else
{
var result = await userManager.CreateAsync(user);
var result = await _userManager.CreateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
}
@ -141,31 +155,31 @@ public class UserService(
{
foreach (var roleId in request.RoleIds)
{
var role = await roleManager.FindByIdAsync(roleId.ToString());
var role = await _roleManager.FindByIdAsync(roleId.ToString());
if (role is { Name: not null })
await userManager.AddToRoleAsync(user, role.Name);
await _userManager.AddToRoleAsync(user, role.Name);
}
}
var customer = await repositoryWrapper.SetRepository<Customer>()
var customer = await _repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == user.Id, cancellationToken);
if (customer != null)
{
repositoryWrapper.SetRepository<Customer>()
_repositoryWrapper.SetRepository<Customer>()
.Add(new Customer
{
UserId = user.Id
});
await repositoryWrapper.SaveChangesAsync(default);
await _repositoryWrapper.SaveChangesAsync(default);
}
repositoryWrapper.SetRepository<Manager>()
_repositoryWrapper.SetRepository<Manager>()
.Add(new Manager
{
UserId = user.Id
});
await repositoryWrapper.SaveChangesAsync(default);
await _repositoryWrapper.SaveChangesAsync(default);
}
return user;
}
@ -175,7 +189,7 @@ public class UserService(
if (request.UserId == Guid.Empty)
throw new AppException("Wrong authorize token , UserId needed");
var user = await userManager.FindByIdAsync(request.UserId.ToString());
var user = await _userManager.FindByIdAsync(request.UserId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
user.LastName = request.LastName;
@ -188,29 +202,29 @@ public class UserService(
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp);
user.Gender = request.Gender;
var result = await userManager.UpdateAsync(user);
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
if (!request.Password.IsNullOrEmpty())
{
if (await userManager.HasPasswordAsync(user))
await userManager.RemovePasswordAsync(user);
if (await _userManager.HasPasswordAsync(user))
await _userManager.RemovePasswordAsync(user);
var addPassResult = await userManager.AddPasswordAsync(user, request.Password);
var addPassResult = await _userManager.AddPasswordAsync(user, request.Password);
if (!addPassResult.Succeeded)
throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description)));
}
if (request.RoleIds.Count > 0)
{
var userRoles = await userManager.GetRolesAsync(user);
await userManager.RemoveFromRolesAsync(user, userRoles);
var userRoles = await _userManager.GetRolesAsync(user);
await _userManager.RemoveFromRolesAsync(user, userRoles);
foreach (var roleId in request.RoleIds)
{
var role = await roleManager.FindByIdAsync(roleId.ToString());
var role = await _roleManager.FindByIdAsync(roleId.ToString());
if (role is { Name: not null })
{
await userManager.AddToRoleAsync(user, role.Name);
await _userManager.AddToRoleAsync(user, role.Name);
}
}
}
@ -220,10 +234,10 @@ public class UserService(
public async Task<bool> EditUserProfileAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{
if (currentUserService.UserId == null)
if (_currentUserService.UserId == null)
throw new AppException("Wrong authorize token , UserId needed");
var user = await userManager.FindByIdAsync(currentUserService.UserId);
var user = await _userManager.FindByIdAsync(_currentUserService.UserId);
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
user.LastName = request.LastName;
@ -236,15 +250,15 @@ public class UserService(
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp);
user.Gender = request.Gender;
var result = await userManager.UpdateAsync(user);
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
if (!request.Password.IsNullOrEmpty())
{
if (await userManager.HasPasswordAsync(user))
await userManager.RemovePasswordAsync(user);
if (await _userManager.HasPasswordAsync(user))
await _userManager.RemovePasswordAsync(user);
var addPassResult = await userManager.AddPasswordAsync(user, request.Password);
var addPassResult = await _userManager.AddPasswordAsync(user, request.Password);
if (!addPassResult.Succeeded)
throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description)));
}
@ -254,34 +268,34 @@ public class UserService(
public async Task<bool> RemoveUserAsync(Guid userId, CancellationToken cancellationToken)
{
var user = await userManager.FindByIdAsync(userId.ToString());
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var roles = await userManager.GetRolesAsync(user);
await userManager.RemoveFromRolesAsync(user, roles);
var removeResult = await userManager.DeleteAsync(user);
var roles = await _userManager.GetRolesAsync(user);
await _userManager.RemoveFromRolesAsync(user, roles);
var removeResult = await _userManager.DeleteAsync(user);
if (!removeResult.Succeeded)
throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description)));
var customer = await repositoryWrapper.SetRepository<Customer>()
var customer = await _repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (customer != null)
{
repositoryWrapper.SetRepository<Customer>()
_repositoryWrapper.SetRepository<Customer>()
.Delete(customer);
await repositoryWrapper.SaveChangesAsync(default);
await _repositoryWrapper.SaveChangesAsync(default);
}
var manager = await repositoryWrapper.SetRepository<Manager>()
var manager = await _repositoryWrapper.SetRepository<Manager>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (manager != null)
{
repositoryWrapper.SetRepository<Manager>()
_repositoryWrapper.SetRepository<Manager>()
.Delete(manager);
await repositoryWrapper.SaveChangesAsync(default);
await _repositoryWrapper.SaveChangesAsync(default);
}
return true;
@ -289,26 +303,26 @@ public class UserService(
public async Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default)
{
if (!Guid.TryParse(currentUserService.UserId, out var userId))
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
var user = await userManager.FindByIdAsync(userId.ToString());
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
var manager = await repositoryWrapper.SetRepository<Manager>()
var manager = await _repositoryWrapper.SetRepository<Manager>()
.TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
var currentVersion = await externalFilesService.GetAdminChangeLogAsync(cancellationToken);
var currentVersion = await _externalFilesService.GetAdminChangeLogAsync(cancellationToken);
if (manager != null)
{
if (!(manager.LatestVersionUsed < currentVersion.VersionNumber)) return currentVersion;
currentVersion.IsNewVersion = true;
manager.LatestVersionUsed = currentVersion.VersionNumber;
repositoryWrapper.SetRepository<Manager>()
_repositoryWrapper.SetRepository<Manager>()
.Update(manager);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
}
return currentVersion;
@ -317,7 +331,7 @@ public class UserService(
public async Task<List<ApplicationRole>> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default)
{
var roles = await roleManager.Roles
var roles = await _roleManager.Roles
.Where(r => r.Name != "RootAdmin")
.Skip(page * 15)
.Take(15)
@ -329,9 +343,9 @@ public class UserService(
{
IQueryable<ApplicationRole> roles;
if (roleName != null)
roles = roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer" && r.PersianName.Trim().ToLower().Contains(roleName));
roles = _roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer" && r.PersianName.Trim().ToLower().Contains(roleName));
else
roles = roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer");
roles = _roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer");
if (page != null)
roles = roles.Skip(page.Value * 15).Take(15);
else
@ -341,13 +355,13 @@ public class UserService(
public async Task<RoleActionRequestDto> GetRoleAsync(Guid roleId, CancellationToken cancellationToken = default)
{
var role = (await roleManager.FindByIdAsync(roleId.ToString()));
var role = (await _roleManager.FindByIdAsync(roleId.ToString()));
if (role == null)
throw new AppException("نقش پیدا نشد", ApiResultStatusCode.NotFound);
var roleDto = role.Adapt<RoleActionRequestDto>();
roleDto.RoleId = roleId;
roleDto.Permissions = (await roleManager.GetClaimsAsync(role))
roleDto.Permissions = (await _roleManager.GetClaimsAsync(role))
.Where(c => c.Type == CustomClaimType.Permission)
.Select(c => c.Value)
.ToList();
@ -366,12 +380,12 @@ public class UserService(
Description = request.Description,
Name = $"{request.EnglishName}"
};
var createRoleResult = await roleManager.CreateAsync(applicationRole);
var createRoleResult = await _roleManager.CreateAsync(applicationRole);
if (!createRoleResult.Succeeded)
throw new AppException(string.Join('|', createRoleResult.Errors));
foreach (var claim in request.Permissions)
await roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
return applicationRole;
}
@ -379,7 +393,7 @@ public class UserService(
{
if (request.EnglishName.IsNullOrEmpty())
throw new AppException("لطفا نام انگلیسی را وارد کنید");
var applicationRole = await roleManager.FindByIdAsync(request.RoleId.ToString());
var applicationRole = await _roleManager.FindByIdAsync(request.RoleId.ToString());
if (applicationRole == null)
throw new AppException("نقش پیدا نشد");
@ -388,20 +402,20 @@ public class UserService(
applicationRole.Description = request.Description;
applicationRole.Name = $"{request.EnglishName}";
var createRoleResult = await roleManager.UpdateAsync(applicationRole);
var createRoleResult = await _roleManager.UpdateAsync(applicationRole);
if (!createRoleResult.Succeeded)
throw new AppException(string.Join('|', createRoleResult.Errors));
var roleClaims = (await roleManager.GetClaimsAsync(applicationRole)).Where(c => c.Type == CustomClaimType.Permission).ToList();
var roleClaims = (await _roleManager.GetClaimsAsync(applicationRole)).Where(c => c.Type == CustomClaimType.Permission).ToList();
foreach (var roleClaim in roleClaims.ToList())
{
var removeResult = await roleManager.RemoveClaimAsync(applicationRole, roleClaim);
var removeResult = await _roleManager.RemoveClaimAsync(applicationRole, roleClaim);
if (!removeResult.Succeeded)
throw new AppException(string.Join(" | ", removeResult.Errors.Select(e => e.Description)));
}
foreach (var claim in request.Permissions)
{
var addResult = await roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
var addResult = await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
if (!addResult.Succeeded)
throw new AppException(string.Join(" | ", addResult.Errors.Select(e => e.Description)));
}
@ -411,18 +425,18 @@ public class UserService(
public async Task<bool> RemoveRoleAsync(Guid roleId, CancellationToken cancellationToken = default)
{
var applicationRole = await roleManager.FindByIdAsync(roleId.ToString());
var applicationRole = await _roleManager.FindByIdAsync(roleId.ToString());
if (applicationRole == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var claims = await roleManager.GetClaimsAsync(applicationRole);
var claims = await _roleManager.GetClaimsAsync(applicationRole);
foreach (var claim in claims)
await roleManager.RemoveClaimAsync(applicationRole, claim);
var users = await userManager.GetUsersInRoleAsync(applicationRole.Name);
await _roleManager.RemoveClaimAsync(applicationRole, claim);
var users = await _userManager.GetUsersInRoleAsync(applicationRole.Name);
foreach (var user in users)
await userManager.RemoveFromRoleAsync(user, applicationRole.Name);
await _userManager.RemoveFromRoleAsync(user, applicationRole.Name);
var removeResult = await roleManager.DeleteAsync(applicationRole);
var removeResult = await _roleManager.DeleteAsync(applicationRole);
if (!removeResult.Succeeded)
throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description)));
return true;

View File

@ -1,11 +1,18 @@
namespace Netina.Core.Models.Api;
public class ApiResult(bool isSuccess, ApiResultStatusCode statusCode, string message = null)
public class ApiResult
{
public bool IsSuccess { get; set; } = isSuccess;
public ApiResultStatusCode StatusCode { get; set; } = statusCode;
public ApiResult(bool isSuccess, ApiResultStatusCode statusCode, string message = null)
{
IsSuccess = isSuccess;
StatusCode = statusCode;
Message = message ?? statusCode.ToDisplay();
}
public bool IsSuccess { get; set; }
public ApiResultStatusCode StatusCode { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Message { get; set; } = message ?? statusCode.ToDisplay();
public string Message { get; set; }
#region Implicit Operators
@ -54,12 +61,17 @@ public class ApiResult(bool isSuccess, ApiResultStatusCode statusCode, string me
#endregion
}
public class ApiResult<TData>(bool isSuccess, ApiResultStatusCode statusCode, TData data, string message = null)
: ApiResult(isSuccess, statusCode, message)
public class ApiResult<TData> : ApiResult
where TData : class
{
public ApiResult(bool isSuccess, ApiResultStatusCode statusCode, TData data, string message = null)
: base(isSuccess, statusCode, message)
{
Data = data;
}
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public TData Data { get; set; } = data;
public TData Data { get; set; }
#region Implicit Operators

View File

@ -7,12 +7,12 @@ public static class SiteMapUIds
public const string BlogCategories = "B5FF333DC4FF4BB4A309CE3AA32CE45A";
public const string Pages = "B463B6C4CC53432C822D79934F528D3E";
public static List<string> AllSiteMapsUIds =>
[
public static List<string> AllSiteMapsUIds => new List<string>
{
BlogCategories,
Categories,
Blogs,
Brands,
Pages
];
};
}

View File

@ -4,7 +4,6 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
@ -13,9 +12,9 @@
<PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" />
<PackageReference Include="Autofac.Extras.Quartz" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Quartz" Version="3.13.0" />
<PackageReference Include="Syncfusion.Pdf.Net.Core" Version="27.1.50" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
<PackageReference Include="Quartz" Version="3.8.1" />
<PackageReference Include="Syncfusion.Pdf.Net.Core" Version="24.1.41" />
</ItemGroup>
@ -27,6 +26,7 @@
<ItemGroup>
<Folder Include="CoreServices\WebSiteServices\" />
<Folder Include="EntityServices\ProductHandlers\" />
<Folder Include="EntityServices\ReviewHandlers\" />
<Folder Include="Models\Api\" />
<Folder Include="Models\Scraper\" />
<Folder Include="Utilities\" />

View File

@ -3,11 +3,20 @@ using Quartz;
namespace Netina.Core.QuartzServices;
public class JobScheduler(IScheduler scheduler, ILogger<JobScheduler> logger)
public class JobScheduler
{
private readonly IScheduler _scheduler;
private readonly ILogger<JobScheduler> _logger;
public JobScheduler(IScheduler scheduler, ILogger<JobScheduler> logger)
{
_scheduler = scheduler;
_logger = logger;
}
public void Start()
{
scheduler.Start();
_scheduler.Start();
IJobDetail job = JobBuilder.Create<SiteMapScheduledJob>()
.WithIdentity("SiteMapJob", "admin")
@ -24,10 +33,10 @@ public class JobScheduler(IScheduler scheduler, ILogger<JobScheduler> logger)
DayOfWeek.Friday))
.StartNow()
.Build();
var offset = scheduler.ScheduleJob(job, trigger);
var offset = _scheduler.ScheduleJob(job, trigger);
logger.LogInformation($"======== Table Schedulers Set For {offset.Result.ToString()} IN {DateTime.Now.ToString()} ===========");
_logger.LogInformation($"======== Table Schedulers Set For {offset.Result.ToString()} IN {DateTime.Now.ToString()} ===========");
}
}

View File

@ -3,11 +3,20 @@ using Quartz;
namespace Netina.Core.QuartzServices;
public class SiteMapScheduledJob(ILogger<SiteMapScheduledJob> logger, ISiteMapService siteMapService) : IJob
public class SiteMapScheduledJob : IJob
{
private readonly ILogger<SiteMapScheduledJob> _logger;
private readonly ISiteMapService _siteMapService;
public SiteMapScheduledJob(ILogger<SiteMapScheduledJob> logger,ISiteMapService siteMapService)
{
_logger = logger;
_siteMapService = siteMapService;
}
public async Task Execute(IJobExecutionContext context)
{
await siteMapService.CreateSiteMapAsync();
logger.LogInformation($"Site Map Job Done At : {DateTime.Now}");
await _siteMapService.CreateSiteMapAsync();
_logger.LogInformation($"Site Map Job Done At : {DateTime.Now}");
}
}

View File

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

View File

@ -1,27 +0,0 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateCommentCommand(
string Title,
string Content,
float Rate,
bool IsBuyer,
bool IsAdmin,
Guid? ParentId,
Guid? BlogId = null,
Guid? ProductId = null,
Guid? UserId = null) : IRequest<Guid>;
public sealed record UpdateCommentCommand(
Guid Id,
string Title,
string Content,
float Rate,
bool IsBuyer,
bool IsAdmin,
Guid? ParentId,
Guid? BlogId = null,
Guid? ProductId = null,
Guid? UserId = null) : IRequest<Guid>;
public sealed record ConfirmCommentCommand(Guid Id) : IRequest<Guid>;
public sealed record DeleteCommentCommand(Guid Id) : IRequest<Guid>;

View File

@ -21,8 +21,7 @@ bool IsForInvitation,
bool IsSpecialOffer,
bool IsForFirstPurchase,
Guid ProductId,
Guid CategoryId,
Guid BrandId) : IRequest<DiscountLDto>;
Guid CategoryId) : IRequest<DiscountLDto>;
public sealed record UpdateDiscountCommand(
Guid Id,
@ -47,11 +46,9 @@ public sealed record UpdateDiscountCommand(
bool IsSpecialOffer,
bool IsForFirstPurchase,
Guid ProductId,
Guid CategoryId,
Guid BrandId) : IRequest<bool>;
Guid CategoryId) : IRequest<bool>;
public sealed record DeleteDiscountCommand(Guid Id) : IRequest<bool>;
public sealed record CalculateOrderDiscountCommand(string DiscountCode, Order Order) : IRequest<double>;
public sealed record CheckUserDiscountFirstUseCommand(string DiscountCode) : IRequest<bool>;

View File

@ -1,15 +0,0 @@
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

@ -6,7 +6,7 @@ public sealed record CheckOrderBagCommand(List<CheckOrderBagRequestItem> OrderBa
public sealed record AddToOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>;
public sealed record RemoveFromOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>;
public sealed record SubmitDiscountActionCommand(Guid OrderId,string? DiscountCode) : IRequest<OrderSDto>;
public sealed record SubmitDiscountCommand(Guid OrderId,string DiscountCode) : IRequest<OrderSDto>;
public sealed record SubmitOrderDeliveryCommand(Guid AddressId, Guid OrderId, Guid ShippingId) : IRequest<OrderSDto>;
public sealed record SubmitOrderBagCommand(List<OrderBagRequestDto> RequestDtos) : IRequest<OrderSDto>;

View File

@ -4,7 +4,6 @@ public sealed record CreateBaseOrderCommand(Guid UserId) : IRequest<Order>;
public sealed record CalculateOrderCommand(Guid OrderId , bool NamoosiCalculate = false) : IRequest<Order>;
public sealed record ConfirmOrderStepCommand(Guid OrderId , OrderStatus NextOrderStatus,string? TrackingCode) : IRequest<bool>;
public sealed record CancelOrderStepCommand(Guid OrderId) : IRequest<bool>;
public sealed record GetOrderInvoiceCommand(Guid OrderId) : IRequest<byte[]>;
public sealed record DeleteOrderCommand(Guid OrderId) : IRequest<bool>;

View File

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

View File

@ -1,26 +1,24 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateProductCommand(
string PersianName,
string EnglishName,
string Summery,
string ExpertCheck,
string Tags,
string Warranty,
bool BeDisplayed,
double Cost,
double PackingCost,
int Stock,
bool HasExpressDelivery,
int MaxOrderCount,
bool IsSpecialOffer,
Guid BrandId,
Guid CategoryId,
DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<ProductLDto>;
string PersianName,
string EnglishName,
string Summery,
string ExpertCheck,
string Tags,
string Warranty,
bool BeDisplayed,
double Cost,
double PackingCost,
int Stock,
bool HasExpressDelivery,
int MaxOrderCount,
bool IsSpecialOffer,
Guid BrandId,
Guid CategoryId,
DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files):IRequest<ProductLDto>;
public sealed record UpdateProductCommand(
Guid Id,
@ -41,13 +39,9 @@ public sealed record UpdateProductCommand(
Guid CategoryId,
DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
List<StorageFileSDto> Files) : 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 ChangeProductDisplayedCommand(Guid Id,bool BeDisplayed) : IRequest<bool>;
public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>;

View File

@ -0,0 +1,6 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateReviewCommand(string Title, string Comment, float Rate, bool IsBuyer, Guid ProductId, Guid UserId) : IRequest<ReviewSDto>;
public sealed record UpdateReviewCommand(Guid Id,string Title, string Comment, float Rate, bool IsBuyer, Guid ProductId, Guid UserId): IRequest<bool>;
public sealed record ConfirmReviewCommand(Guid Id) : IRequest<bool>;
public sealed record DeleteReviewCommand(Guid Id) : IRequest<bool>;

View File

@ -1,33 +0,0 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateSubProductCommand(
Guid ParentId,
ProductDiversity Diversity,
string DiversityValue,
string DiversitySecondaryValue,
string DiversityDescription,
string PersianName,
double Cost,
double PackingCost,
int Stock,
bool HasExpressDelivery,
int MaxOrderCount,
List<StorageFileSDto> Files) : IRequest<Guid>;
public sealed record UpdateSubProductCommand(
Guid Id,
Guid ParentId,
ProductDiversity Diversity,
string DiversityValue,
string DiversitySecondaryValue,
string DiversityDescription,
string PersianName,
double Cost,
double PackingCost,
int Stock,
bool HasExpressDelivery,
int MaxOrderCount,
List<StorageFileSDto> Files) : IRequest<Guid>;
public sealed record DeleteSubProductCommand(Guid Id) : IRequest<bool>;

View File

@ -1,4 +0,0 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetCommentsQuery(int Page = 0,int Count = Refers.SizeM ,Guid? ProductId = null, Guid? BlogId = null) : IRequest<List<CommentSDto>>;
public record GetCommentQuery(Guid Id) : IRequest<CommentLDto>;

View File

@ -1,3 +0,0 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetCustomersQuery(int Page = 0, int Count = Refers.SizeM) : IRequest<List<CustomerSDto>>;

View File

@ -1,4 +0,0 @@
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

@ -4,4 +4,4 @@ public sealed record GetOrderLDtoQuery(Guid Id) : IRequest<OrderLDto>;
public sealed record GetUserOrdersQuery(Guid CustomerId = default) : IRequest<List<OrderSDto>>;
public sealed record GetOrderQuery(Guid Id) : IRequest<Order>;
public sealed record GetOrdersQuery(OrderQueryDateFilter? DateFilter, OrderStatus? OrderStatus,long? SelectedDate,string? FactorCode,bool OrderBags, int Page = 0) : IRequest<List<OrderSDto>>;
public sealed record GetOrdersQuery(OrderQueryDateFilter? DateFilter, OrderStatus? OrderStatus,long? SelectedDate,string? FactorCode, int Page = 0) : IRequest<List<OrderSDto>>;

View File

@ -7,7 +7,7 @@ public sealed record GetProductsQuery(
bool? IsActive,
bool? SpecialOffer,
int Page = 0 ,
string? ProductName = null,
string? ProductName = default,
QuerySortBy SortBy = QuerySortBy.None ,
Guid CategoryId = default ,
double MinPrice = -1 ,

View File

@ -0,0 +1,4 @@
namespace Netina.Domain.CommandQueries.Queries;
public record GetReviewsQuery(int Page = 0) : IRequest<List<ReviewSDto>>;
public record GetReviewQuery(Guid Id) : IRequest<ReviewLDto>;

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