subProduct
Amir Hossein Khademi 2024-09-11 19:59:51 +03:30
commit ea4f17a5d9
181 changed files with 1735 additions and 1775 deletions

View File

@ -1 +1 @@
1.0.9.11
1.2.11.13

View File

@ -1,8 +1,8 @@
{
"ConnectionStrings": {
"PostgresServer": "Host=185.220.227.246;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;"
"Postgres": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopDB",
"MartenDB": "Host=pg-0;Username=postgres;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=NetinaShopMartenDB"
},
"Logging": {
"LogLevel": {

View File

@ -11,23 +11,26 @@ public class BlogCategoryController : ICarterModule
.MapGroup($"api/blog/category");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllCategories")
.WithDisplayName("Get BlogCategories")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetBlogCategory")
.WithDisplayName("Get BlogCategory")
.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,5 @@
using Marten.Events;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options;
using Netina.Domain.Entities.Blogs;
using Netina.Domain.Entities.Products;
using System.Web;
namespace Netina.Api.Controllers;
@ -15,33 +13,36 @@ public class BlogController : ICarterModule
.MapGroup($"api/blog");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllBlogs")
.WithDisplayName("Get Blogs")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetBlog")
.WithDisplayName("Get Blog")
.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.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("GetBlogNewLink")
.WithDisplayName("Get Blog NewLink")
.HasApiVersion(1.0);
}

View File

@ -11,23 +11,26 @@ public class BrandController : ICarterModule
.MapGroup($"api/brand");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllBrands")
.WithDisplayName("Get Brands")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetBlogBrand")
.WithDisplayName("Get Brand")
.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

@ -9,25 +9,28 @@ public class DiscountController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllDiscounts")
.WithDisplayName("Get Discounts")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetDiscount")
.WithDisplayName("Get Discount")
.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 Cities")
.WithDisplayName("Get Provinces")
.HasApiVersion(1.0);
}

View File

@ -0,0 +1,56 @@
namespace Netina.Api.Controllers;
public class FaqController : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
var group = app.NewVersionedApi("Faq")
.MapGroup("api/faq");
group.MapGet("/slug", GetFaqBySlugAsync)
.WithDisplayName("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,4 +1,5 @@
using Netina.Domain.Enums;
using Netina.Domain.Dtos.ResponseDtos;
using Netina.Domain.Enums;
namespace Netina.Api.Controllers;
@ -10,14 +11,57 @@ public class FileController : ICarterModule
.MapGroup("api/file");
group.MapGet("", GetFilesAsync)
.WithDisplayName("GetFilesAsync")
.WithDisplayName("Get Files")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageFiles, ApplicationPermission.ViewFiles))
.HasApiVersion(1.0);
group.MapPost("", UploadFileAsync)
.WithDisplayName("UploadFileAsync")
.WithDisplayName("Upload File")
.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,10 +9,7 @@ public class HealthController : ICarterModule
var group = app.NewVersionedApi("Health")
.MapGroup("health");
group.MapGet("", GetHealth)
.WithDisplayName("GetHealth")
.HasApiVersion(1.0);
group.MapGet("/error/test", () => { throw new Exception("Error test message");})
.WithDisplayName("GetHealth")
.WithDisplayName("Get Health")
.HasApiVersion(1.0);
}

View File

@ -11,20 +11,20 @@ public class MarketerController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetMarketersAsync)
.WithDisplayName("GetAllMarketers")
.WithDisplayName("Get Marketers")
.RequireAuthorization(builder=>builder.RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageUsers , ApplicationPermission.ViewUsers))
.HasApiVersion(1.0);
group.MapGet("profile", GetMarketerProfileAsync)
.WithDisplayName("GetAllMarketers")
.WithDisplayName("Get Marketer Profile")
.HasApiVersion(1.0);
group.MapPost("signup", SignUpMarketerAsync)
.WithDisplayName("SignUpMarketer")
.WithDisplayName("SignUp Marketer")
.HasApiVersion(1.0);
group.MapGet("signup/contract", GetSignUpMarketerContractAsync)
.WithDisplayName("SignUpMarketerContract")
.WithDisplayName("Get Marketer Contract")
.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 All Members")
.WithDisplayName("Get 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("GetUserCurrentOrderBag")
.WithDisplayName("Get User Current OrderBag")
.HasApiVersion(1.0);
group.MapPost("check", CheckOrderBagAsync)
.WithDisplayName("CheckOrderBag")
.WithDisplayName("Check OrderBag")
.AllowAnonymous()
.HasApiVersion(1.0);
group.MapPost("add", AddProductToBagAsync)
.WithDisplayName("AddProductToBag")
.WithDisplayName("Add Product To OrderBag")
.HasApiVersion(1.0);
group.MapDelete("remove", RemoveFromOrderBagAsync)
.WithDisplayName("RemoveFromOrderBag")
.WithDisplayName("Remove From OrderBag")
.HasApiVersion(1.0);
group.MapPost("submit", SubmitOrderBagAsync)
.WithDisplayName("SubmitOrderBag")
.WithDisplayName("Submit OrderBag")
.HasApiVersion(1.0);
group.MapPost("discount/{orderId}", DiscountActionOrderBagAsync)
.WithDisplayName("DiscountActionOrderBag")
.WithDisplayName("Add Discount To OrderBag")
.HasApiVersion(1.0);
group.MapPost("shipping/{orderId}", AddShippingToOrderBagAsync)
.WithDisplayName("AddShippingToOrderBag")
.WithDisplayName("Add Shipping To OrderBag")
.HasApiVersion(1.0);
group.MapPost("payment/{orderId}", SubmitOrderPaymentAsync)
.WithDisplayName("SubmitOrderPayment")
.WithDisplayName("Submit Order Payment")
.HasApiVersion(1.0);
}

View File

@ -10,27 +10,32 @@ public class OrderController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllOrders")
.WithDisplayName("Get Orders")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders , ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetOneOrder")
.WithDisplayName("Get Order")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapPost("{id}/confirm", ConfirmOrderStepAsync)
.WithDisplayName("ConfirmOrderStep")
.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")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync)
.WithDisplayName("DeleteOneOrder")
.WithDisplayName("Delete Order")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapGet("{id}/invoice", GetOrderInvoiceAsync)
.WithDisplayName("GetOrderInvoice")
.WithDisplayName("Get Order Invoice")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.AllowAnonymous()
.HasApiVersion(1.0);
@ -40,6 +45,9 @@ 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,

View File

@ -12,6 +12,13 @@ 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")
@ -31,7 +38,6 @@ public class PageController : ICarterModule
.HasApiVersion(1.0)
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManagePages));
group.MapDelete("{id}", DeletePageByIdAsync)
.WithDisplayName("Delete Page")
.HasApiVersion(1.0)
@ -39,6 +45,12 @@ 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));

View File

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

View File

@ -9,22 +9,25 @@ public class ProductCategoryController : ICarterModule
.MapGroup($"api/product/category");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllCategories")
.WithDisplayName("Get ProductCategories")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetCategory")
.WithDisplayName("Get ProductCategory")
.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,26 +11,35 @@ public class ProductController : ICarterModule
.MapGroup($"api/product");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllProducts")
.WithDisplayName("Get Products")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetProducts")
.WithDisplayName("Get Product")
.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.MapPut("{productId}", ChangeDisplayedAsync)
group.MapPut("{productId}/displayed", ChangeDisplayedAsync)
.WithDisplayName("Change Product Display")
.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.MapDelete("{id}", Delete)
.WithDisplayName("Delete Product")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageProducts))
.HasApiVersion(1.0);
}
@ -65,6 +74,9 @@ public class ProductController : ICarterModule
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

@ -8,27 +8,27 @@ public class ProductReviewController : ICarterModule
.MapGroup("product/review");
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetOneAsync")
.WithDisplayName("Get ProductReview")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews,ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllAsync")
.WithDisplayName("Get ProductReview")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllReviews, ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
group.MapPost("", PostAsync)
.WithDisplayName("PostReview")
.WithDisplayName("Create ProductReview")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview, ApplicationPermission.AddReview))
.HasApiVersion(1.0);
group.MapPut("confirm/{id}", ConfirmAsync)
.WithDisplayName("ConfirmAsync")
.WithDisplayName("Confirm ProductReview")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ConfirmReview, ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync)
.WithDisplayName("DeleteAsync")
.WithDisplayName("Delete ProductReview")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageReview))
.HasApiVersion(1.0);
}

View File

@ -11,29 +11,32 @@ public class RoleController : ICarterModule
.MapGroup($"api/user/role");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllRoles")
.WithDisplayName("Get Roles")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
group.MapGet("permission", GetAllPermissions)
.WithDisplayName("GetAllPermissions")
.WithDisplayName("Get Permissions")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewRoles, ApplicationPermission.ManageRoles))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetRole")
.WithDisplayName("Get Role")
.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("GetDigiProducts")
.WithDisplayName("Get DigiProducts")
.HasApiVersion(1.0);
group.MapPost("digi/{productId}", AddProductToShopAsync)
.WithDisplayName("AddProductToShop")
.WithDisplayName("Add DigiProduct To Shop")
.HasApiVersion(1.0);
}

View File

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

View File

@ -2,17 +2,11 @@
using Netina.Domain.Entities.Blogs;
namespace Netina.Api.Controllers;
public class SeedController : ICarterModule
public class SeedController(IWebHostEnvironment environment) : 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");
@ -78,13 +72,14 @@ public class SeedController : ICarterModule
var baseCat = await mediator.Send(new CreateProductCategoryCommand("دسته بندی نشده", "محصولات دسته بندی نشده",
true,
default,
new List<StorageFileSDto>()),cancellationToken);
new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()),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>()), cancellationToken);
new List<StorageFileSDto>(),new Dictionary<string, string>(),new Dictionary<string, string>()), cancellationToken);
categories.Add(requestDto.BaseCategoryId,lDto);
}
@ -97,13 +92,18 @@ public class SeedController : 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>()), cancellationToken);
var baseBrand = await mediator.Send(new CreateBrandCommand("بدون برند","NoBrand",
"محصولات بدون برند",
false,
string.Empty,
new List<StorageFileSDto>(),
new Dictionary<string, string>(),
new Dictionary<string, string>()), 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>()), cancellationToken);
string.Empty, new List<StorageFileSDto>(),new Dictionary<string, string>(),new Dictionary<string, string>()), cancellationToken);
brands.Add(requestDto.BaseBrandId,sDto);
}

View File

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

View File

@ -9,23 +9,26 @@ public class ShippingController : ICarterModule
.MapGroup($"api/warehouse/shipping");
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllShipping")
.WithDisplayName("Get Shipping")
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetShipping")
.WithDisplayName("Get Shipping")
.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

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

View File

@ -12,44 +12,47 @@ public class UserController : ICarterModule
.MapGroup($"api/user");
group.MapGet("info", GetUserInfoAsync)
.WithDisplayName("GetUserInfo")
.WithDisplayName("Get UserInfo")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
.HasApiVersion(1.0);
group.MapGet("", GetAllAsync)
.WithDisplayName("GetAllUsers")
.WithDisplayName("Get Users")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0);
group.MapGet("{id}", GetAsync)
.WithDisplayName("GetUser")
.WithDisplayName("Get User")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewUsers, ApplicationPermission.ManageUsers))
.HasApiVersion(1.0);
group.MapGet("/order", GetUserOrdersAsync)
.WithDisplayName("GetUserOrders")
.WithDisplayName("Get UserOrders By JWT")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewMineOrders))
.HasApiVersion(1.0);
group.MapGet("{id}/order", GetUserOrdersByIdAsync)
.WithDisplayName("GetUserOrders")
.WithDisplayName("Get UserOrders")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders))
.HasApiVersion(1.0);
group.MapGet("/changelog", GetChangeLogAsync)
.WithDisplayName("GetChangeLog")
.WithDisplayName("Get ChangeLog")
.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,4 +1,7 @@
namespace Netina.Api.Controllers;
using Netina.Domain.Enums;
using Netina.Domain.MartenEntities.Settings;
namespace Netina.Api.Controllers;
public class WebSiteController : ICarterModule
{
@ -9,8 +12,38 @@ 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

@ -6,40 +6,40 @@
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<AssemblyVersion>1.0.9.11</AssemblyVersion>
<FileVersion>1.0.9.11</FileVersion>
<AssemblyVersion>1.2.11.13</AssemblyVersion>
<FileVersion>1.2.11.13</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.7" />
<PackageReference Include="Asp.Versioning.Http" Version="8.1.0" />
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
<PackageReference Include="Carter" Version="8.0.0" />
<PackageReference Include="Carter" Version="8.1.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">
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<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.AspNetCore.Authentication.JwtBearer" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<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.4.0" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Sentry.Serilog" Version="4.9.0" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.3.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="7.0.0" />
@ -48,11 +48,11 @@
<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.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.7.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.4" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
</ItemGroup>
<ItemGroup>

View File

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

View File

@ -3,24 +3,17 @@ using Netina.Repository.Abstracts;
namespace Netina.Api.Services;
public class CurrentUserService : ICurrentUserService
public class CurrentUserService(IHttpContextAccessor httpContextAccessor) : ICurrentUserService
{
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 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();
@ -28,7 +21,7 @@ public class CurrentUserService : ICurrentUserService
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)
{
@ -52,9 +45,9 @@ public class CurrentUserService : ICurrentUserService
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,7 +1,4 @@
using Netina.Common.Models.Api;
using Netina.Core.Models.Api;
namespace Netina.Api.WebFramework.Bases;
namespace Netina.Api.WebFramework.Bases;
public class ApiResultFactory
{

View File

@ -1,23 +1,13 @@
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;
namespace Netina.Api.WebFramework.Bases;
public class CrudEndpoint<TEntity,TGetAllQuery,TGetOneQuery,TCreateCommand,TUpdateCommand,TDeleteCommand> where TEntity : ApiEntity, new()
public class CrudEndpoint<TEntity, TGetAllQuery, TGetOneQuery, TCreateCommand, TUpdateCommand, TDeleteCommand>(
string endpointName)
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")
@ -83,16 +73,11 @@ public class BaseController : ControllerBase
}
[Authorize(AuthenticationSchemes = "Bearer")]
public class CrudController<TDto, TEntity> : BaseController
public class CrudController<TDto, TEntity>(IRepositoryWrapper repositoryWrapper) : BaseController
where TDto : BaseDto<TDto, TEntity>, new()
where TEntity : ApiEntity, new()
{
protected readonly IRepositoryWrapper _repositoryWrapper;
public CrudController(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
protected readonly IRepositoryWrapper _repositoryWrapper = repositoryWrapper;
// GET:Get All Entity
[HttpGet]
@ -168,15 +153,10 @@ public class CrudController<TDto, TEntity> : BaseController
}
[Authorize(AuthenticationSchemes = "Bearer")]
public class CrudController<TEntity> : BaseController
public class CrudController<TEntity>(IRepositoryWrapper repositoryWrapper) : BaseController
where TEntity : ApiEntity, new()
{
protected readonly IRepositoryWrapper _repositoryWrapper;
public CrudController(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
protected readonly IRepositoryWrapper _repositoryWrapper = repositoryWrapper;
// GET:Get All Entity
[HttpGet]

View File

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

View File

@ -10,22 +10,11 @@ public static class ExceptionHandlerMiddlewareExtensions
}
}
public class ExceptionHandlerMiddleware
public class ExceptionHandlerMiddleware(
RequestDelegate next,
IWebHostEnvironment env,
ILogger<ExceptionHandlerMiddleware> logger)
{
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;
@ -34,15 +23,17 @@ public class ExceptionHandlerMiddleware
try
{
await _next(context);
await next(context);
}
catch (BaseApiException exception)
{
_logger.LogError(exception, exception.Message);
httpStatusCode = exception.HttpStatusCode;
logger.LogError(exception, exception.Message);
httpStatusCode = exception.ApiStatusCode == ApiResultStatusCode.NotFound ? HttpStatusCode.NotFound :
exception.ApiStatusCode == ApiResultStatusCode.BadRequest ?
HttpStatusCode.BadRequest : exception.HttpStatusCode;
apiStatusCode = exception.ApiStatusCode;
if (_env.IsDevelopment())
if (env.IsDevelopment())
{
var dic = new Dictionary<string, string>
{
@ -80,19 +71,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;
@ -103,9 +94,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)
{
@ -183,7 +174,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,28 +8,19 @@ public static class PerformanceMiddlewareExtensions
}
}
public class PerformanceMiddleware
public class PerformanceMiddleware(
RequestDelegate next,
ILogger<ExceptionHandlerMiddleware> logger)
{
private readonly ILogger<ExceptionHandlerMiddleware> _logger;
private readonly RequestDelegate _next;
private readonly Stopwatch _timer;
public PerformanceMiddleware(
RequestDelegate next,
ILogger<ExceptionHandlerMiddleware> logger)
{
_next = next;
_logger = logger;
_timer = new Stopwatch();
}
private readonly Stopwatch _timer = new();
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

@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
using Netina.Common.Extensions;
using Pluralize.NET;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
@ -139,17 +138,12 @@ public class SetVersionInPaths : IDocumentFilter
}
}
public class UnauthorizedResponsesOperationFilter : IOperationFilter
public class UnauthorizedResponsesOperationFilter(
bool includeUnauthorizedAndForbiddenResponses,
string schemeName = "Bearer")
: IOperationFilter
{
private readonly bool includeUnauthorizedAndForbiddenResponses;
private readonly string schemeName;
public UnauthorizedResponsesOperationFilter(bool includeUnauthorizedAndForbiddenResponses,
string schemeName = "Bearer")
{
this.includeUnauthorizedAndForbiddenResponses = includeUnauthorizedAndForbiddenResponses;
this.schemeName = schemeName;
}
private readonly string schemeName = schemeName;
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{

View File

@ -1,13 +1,21 @@
using System.Web;
using System.Xml.Linq;
using System.Net;
using System.Web;
namespace Netina.Common.Extensions
{
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string value)
=> string.IsNullOrEmpty(value);
public static string GetSlug(string title)
{
return HttpUtility.UrlEncode(title.Replace(' ', '-'));
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;
}
public static string ToPriceWhitPriceType(this long price, string priceType)
{

View File

@ -1,25 +1,16 @@
namespace Netina.Common.Models.Entity
{
[AttributeUsage(AttributeTargets.Class)]
public class PageClassDisplay : Attribute
public class PageClassDisplay(string name, string description) : Attribute
{
private readonly string _description;
private readonly string _name;
public PageClassDisplay(string name, string description)
{
_name = name;
_description = description;
}
public string GetName()
{
return _name;
return name;
}
public string GetDescription()
{
return _description;
return description;
}
}
}

View File

@ -11,7 +11,7 @@
<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="7.5.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" />
</ItemGroup>
<!--<PropertyGroup>

View File

@ -6,4 +6,7 @@ public interface IPageService : IScopedDependency
Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default);
Task<bool> CreatePageAsync(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,53 +1,32 @@
namespace Netina.Core.BaseServices;
public class AccountService : IAccountService
public class AccountService(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> userSignInManager,
IJwtService jwtService,
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
ISmsService smsService,
IUserService managerUserService)
: 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,
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
ISmsService smsService,
IUserService managerUserService)
{
_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;
}
@ -56,7 +35,7 @@ public class AccountService : IAccountService
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;
@ -67,23 +46,23 @@ public class AccountService : IAccountService
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);
@ -91,11 +70,11 @@ public class AccountService : IAccountService
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)
@ -104,7 +83,7 @@ public class AccountService : IAccountService
{
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));
}
@ -113,9 +92,9 @@ public class AccountService : IAccountService
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)
@ -132,19 +111,19 @@ public class AccountService : IAccountService
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);
}
@ -153,8 +132,8 @@ public class AccountService : IAccountService
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,38 +2,31 @@
namespace Netina.Core.BaseServices;
public class DashboardService : IDashboardService
public class DashboardService(IRepositoryWrapper repositoryWrapper, UserManager<ApplicationUser> userManager)
: 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;
@ -45,19 +38,19 @@ public class DashboardService : IDashboardService
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,21 +1,14 @@
namespace Netina.Core.BaseServices;
public class JwtService : IJwtService
public class JwtService(
IOptionsSnapshot<SiteSettings> siteSettings,
SignInManager<ApplicationUser> userSignInManager,
RoleManager<ApplicationRole> roleManager)
: IJwtService
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly SiteSettings _siteSettings;
private readonly SiteSettings _siteSettings = siteSettings.Value;
public JwtService(
IOptionsSnapshot<SiteSettings> siteSettings,
SignInManager<ApplicationUser> userSignInManager,
RoleManager<ApplicationRole> roleManager)
{
_signInManager = userSignInManager;
_roleManager = roleManager;
_siteSettings = siteSettings.Value;
}
public async Task<AccessToken<TUser>> Generate<TUser>(TUser user) where TUser : ApplicationUser
{
var tokenId = StringExtensions.GetId(8);
@ -89,7 +82,7 @@ public class JwtService : IJwtService
private async Task<List<Claim>> GetClaims<TUser>(TUser baseUser, string jwtId) where TUser : ApplicationUser
{
var clFac = (await _signInManager.ClaimsFactory.CreateAsync(baseUser));
var clFac = (await userSignInManager.ClaimsFactory.CreateAsync(baseUser));
var claims = new List<Claim>();
claims.Add(new Claim("JwtID", jwtId));
claims.Add(new Claim(ClaimTypes.Name, baseUser.UserName));
@ -108,10 +101,10 @@ public class JwtService : IJwtService
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

@ -1,28 +1,25 @@
using Netina.Domain.MartenEntities.Pages;
using Netina.Core.BaseServices.Abstracts;
using Netina.Domain.MartenEntities.Pages;
namespace Netina.Core.BaseServices;
public class PageService : IPageService
public class PageService(
IMartenRepositoryWrapper martenRepositoryWrapperWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: IPageService
{
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 _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(id.Value, cancellationToken);
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(id.Value, cancellationToken);
else if (pageSlug != null)
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Slug == pageSlug, cancellationToken);
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Slug == pageSlug, cancellationToken);
else if (pageName != null)
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Title == pageName, cancellationToken);
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Title == pageName, cancellationToken);
else if (type != null)
page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Type == type, cancellationToken);
page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(entity => entity.Type == type, cancellationToken);
if (page == null)
throw new AppException("Page not found", ApiResultStatusCode.NotFound);
@ -45,7 +42,7 @@ public class PageService : IPageService
public async Task<List<BasePageSDto>> GetPagesAsync(CancellationToken cancellationToken = default)
{
List<BasePageSDto> sDtos = new List<BasePageSDto>();
var pages = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntitiesAsync(cancellationToken);
var pages = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntitiesAsync(cancellationToken);
foreach (var page in pages)
{
var dto = new BasePageSDto
@ -79,23 +76,49 @@ public class PageService : IPageService
Type = entity.Type,
Slug = entity.Slug,
CreatedAt = DateTime.Now,
CreatedBy = _currentUserService.UserName ?? string.Empty
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 _martenRepositoryWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
await martenRepositoryWrapperWrapper.SetRepository<BasePage>().AddOrUpdateEntityAsync(basePage, cancellationToken);
return true;
}
public async Task<bool> DeletePageAsync(Guid id, CancellationToken cancellationToken = default)
{
var page = await _martenRepositoryWrapper.SetRepository<BasePage>().GetEntityAsync(p => p.Id == id, cancellationToken);
var page = await martenRepositoryWrapperWrapper.SetRepository<BasePage>().GetEntityAsync(p => p.Id == id, cancellationToken);
if (page == null)
throw new AppException("Page not found", ApiResultStatusCode.NotFound);
await _martenRepositoryWrapper.SetRepository<BasePage>().RemoveEntityAsync(page, cancellationToken);
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)
return newLink.NewUrl;
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");
}
}

View File

@ -1,21 +1,14 @@

public class SettingService : ISettingService
public class SettingService(IMartenRepositoryWrapper martenRepositoryWrapper) : 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)
@ -34,7 +27,7 @@ public class SettingService : ISettingService
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)
@ -51,7 +44,7 @@ public class SettingService : ISettingService
baseSetting.JsonData = JsonConvert.SerializeObject(settingObj.Deserialize(type));
}
await _martenRepositoryWrapper.SetRepository<BaseSetting>()
await martenRepositoryWrapper.SetRepository<BaseSetting>()
.AddOrUpdateEntityAsync(baseSetting, cancellationToken);
}
}

View File

@ -6,23 +6,15 @@ using Netina.Domain.Entities.ProductCategories;
namespace Netina.Core.BaseServices;
public class SiteMapService : ISiteMapService
public class SiteMapService(
IOptionsSnapshot<SiteSettings> snapshot,
IUploadFileService uploadFileService,
IRepositoryWrapper repositoryWrapper,
IPageService pageService)
: ISiteMapService
{
private readonly IUploadFileService _uploadFileService;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IPageService _pageService;
private readonly SiteSettings _siteSetting;
private readonly SiteSettings _siteSetting = snapshot.Value;
public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot,
IUploadFileService uploadFileService,
IRepositoryWrapper repositoryWrapper,
IPageService pageService)
{
_uploadFileService = uploadFileService;
_repositoryWrapper = repositoryWrapper;
_pageService = pageService;
_siteSetting = snapshot.Value;
}
public async Task CreateSiteMapAsync()
{
XmlDocument doc = new XmlDocument();
@ -38,11 +30,11 @@ public class SiteMapService : ISiteMapService
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();
@ -96,7 +88,7 @@ public class SiteMapService : ISiteMapService
doc.WriteTo(writer);
writer.Flush();
byte[] byteArray = stream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = byteArray,
ContentType = "text/xml",
@ -118,7 +110,7 @@ public class SiteMapService : ISiteMapService
{
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);
@ -170,7 +162,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -184,7 +176,7 @@ public class SiteMapService : ISiteMapService
{
var siteMapsUId = SiteMapUIds.Brands;
var brands = await _repositoryWrapper.SetRepository<Brand>()
var brands = await repositoryWrapper.SetRepository<Brand>()
.TableNoTracking
.ToListAsync();
@ -238,7 +230,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -253,7 +245,7 @@ public class SiteMapService : ISiteMapService
{
var siteMapsUId = SiteMapUIds.Categories;
var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
var categories = await repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.ToListAsync();
@ -307,7 +299,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -321,7 +313,7 @@ public class SiteMapService : ISiteMapService
private async Task CreateProductsSiteMapsAsync()
{
var products = await _repositoryWrapper.SetRepository<Product>()
var products = await repositoryWrapper.SetRepository<Product>()
.TableNoTracking
.Select(ProductMapper.ProjectToSDto)
.ToListAsync();
@ -400,7 +392,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -417,7 +409,7 @@ public class SiteMapService : ISiteMapService
private async Task CreateBlogsSiteMapsAsync()
{
var blogs = await _repositoryWrapper.SetRepository<Blog>()
var blogs = await repositoryWrapper.SetRepository<Blog>()
.TableNoTracking
.Select(BlogMapper.ProjectToSDto)
.ToListAsync();
@ -530,7 +522,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",
@ -548,7 +540,7 @@ public class SiteMapService : ISiteMapService
{
var siteMapsUId = SiteMapUIds.BlogCategories;
var blogCategories = await _repositoryWrapper.SetRepository<BlogCategory>()
var blogCategories = await repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking
.ToListAsync();
@ -602,7 +594,7 @@ public class SiteMapService : ISiteMapService
zipStream.Close();
var siteMapArray = compressedStream.ToArray();
await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
await uploadFileService.UploadFileByteAsync(new FileUploadRequest
{
FileBytes = siteMapArray,
ContentType = "text/plain",

View File

@ -1,21 +1,17 @@
namespace Netina.Core.CoreServices.SearchServices;
public class GetEmallsProductsQueryHandler : IRequestHandler<GetEmallsProductsQuery, EmallsResponseDto>
public class GetEmallsProductsQueryHandler(
IRepositoryWrapper repositoryWrapper,
IMediator mediator,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetEmallsProductsQuery, EmallsResponseDto>
{
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;
}
private readonly SiteSettings _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
@ -37,7 +33,7 @@ public class GetEmallsProductsQueryHandler : IRequestHandler<GetEmallsProductsQu
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)
{
@ -62,7 +58,7 @@ public class GetEmallsProductsQueryHandler : IRequestHandler<GetEmallsProductsQu
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,27 +2,22 @@
namespace Netina.Core.CoreServices.SearchServices;
public class GetThumbSearchProductsQueryHandler : IRequestHandler<GetThumbSearchProductsQuery, SearchResponseDto>
public class GetThumbSearchProductsQueryHandler(IRepositoryWrapper repositoryWrapper)
: 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,21 +1,17 @@
namespace Netina.Core.CoreServices.SearchServices;
public class GetTorobProductsQueryHandler : IRequestHandler<GetTorobProductsQuery, List<TorobProductResponseDto>>
public class GetTorobProductsQueryHandler(
IRepositoryWrapper repositoryWrapper,
IMediator mediator,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetTorobProductsQuery, List<TorobProductResponseDto>>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
private readonly SiteSettings _siteSetting;
private readonly SiteSettings _siteSetting = optionsSnapshot.Value;
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
@ -37,7 +33,7 @@ public class GetTorobProductsQueryHandler : IRequestHandler<GetTorobProductsQuer
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)
{

View File

@ -2,22 +2,17 @@
namespace Netina.Core.CoreServices.WebSiteServices;
public class GetWebSiteNavBarCommandHandler : IRequestHandler<GetWebSiteNavBarCommand , List<NavMenuItem>>
public class GetWebSiteNavBarCommandHandler(
IRepositoryWrapper repositoryWrapper,
ISettingService settingService,
IOptionsSnapshot<SiteSettings> optionsSnapshot)
: IRequestHandler<GetWebSiteNavBarCommand, List<NavMenuItem>>
{
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;
}
private readonly SiteSettings _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>();
@ -30,7 +25,7 @@ public class GetWebSiteNavBarCommandHandler : IRequestHandler<GetWebSiteNavBarCo
if (navBarSetting.ShowBlogCategories)
{
var baseCategories = await _repositoryWrapper.SetRepository<BlogCategory>()
var baseCategories = await repositoryWrapper.SetRepository<BlogCategory>()
.TableNoTracking
.OrderByDescending(c => c.CreatedAt)
.Select(BlogCategoryMapper.ProjectToSDto)
@ -54,7 +49,7 @@ public class GetWebSiteNavBarCommandHandler : IRequestHandler<GetWebSiteNavBarCo
}
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,21 +1,16 @@
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrderDiscountCommand , double>
public class CalculateOrderDiscountCommandHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: 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);
@ -25,14 +20,14 @@ public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrd
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 customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == firstPurchaseUserId, cancellationToken);
if (customer == null)
throw new BaseApiException(ApiResultStatusCode.NotFound, "Customer not found");
var userOrderCount = await _repositoryWrapper.SetRepository<Order>()
var userOrderCount = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.CountAsync(f => f.CustomerId == customer.Id && f.DiscountCode == discount.Code, cancellationToken);
if (userOrderCount > 0)
@ -51,7 +46,7 @@ public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrd
}
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())
@ -62,7 +57,7 @@ public class CalculateOrderDiscountCommandHandler : IRequestHandler<CalculateOrd
}
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);

View File

@ -1,15 +1,8 @@
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateProductDiscountCommand, bool>
public class CalculateProductDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
: 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)
@ -30,7 +23,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
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);
@ -42,7 +35,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
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);
@ -53,7 +46,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
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)
@ -85,7 +78,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
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);
@ -97,7 +90,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
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);
@ -108,7 +101,7 @@ public class CalculateProductDiscountCommandHandler : IRequestHandler<CalculateP
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)

View File

@ -1,28 +1,22 @@
namespace Netina.Core.EntityServices.DiscountHandlers;
public class CheckUserDiscountFirstUseCommandHandler : IRequestHandler<CheckUserDiscountFirstUseCommand, bool>
public class CheckUserDiscountFirstUseCommandHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: IRequestHandler<CheckUserDiscountFirstUseCommand, bool>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly ICurrentUserService _currentUserService;
public CheckUserDiscountFirstUseCommandHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService)
{
_repositoryWrapper = repositoryWrapper;
_currentUserService = currentUserService;
}
public async Task<bool> Handle(CheckUserDiscountFirstUseCommand request, CancellationToken cancellationToken)
{
if (_currentUserService.UserId != null && Guid.TryParse(_currentUserService.UserId, out Guid userId))
if (currentUserService.UserId != null && Guid.TryParse(currentUserService.UserId, out Guid userId))
{
var customer = await _repositoryWrapper.SetRepository<Customer>()
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>()
var discountedUserOrder = await repositoryWrapper.SetRepository<Order>()
.TableNoTracking
.FirstOrDefaultAsync(f => f.CustomerId == customer.Id && f.DiscountCode == request.DiscountCode,
cancellationToken);

View File

@ -1,48 +1,38 @@
namespace Netina.Core.EntityServices.MarketerHandlers;
public class CreateMarketerDiscountCommandHandler : IRequestHandler<CreateMarketerDiscountCommand, string>
public class CreateMarketerDiscountCommandHandler(
UserManager<ApplicationUser> userManager,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: 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)
{
_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;
@ -53,8 +43,8 @@ public class CreateMarketerDiscountCommandHandler : IRequestHandler<CreateMarket
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,18 +2,12 @@
namespace Netina.Core.EntityServices.MarketerHandlers;
public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfileQuery, MarketerProfileResponseDto>
public class GetMarketerProfileQueryHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
ISettingService settingService)
: 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;
@ -21,17 +15,17 @@ public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfile
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);
@ -40,26 +34,26 @@ public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfile
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,36 +1,29 @@
namespace Netina.Core.EntityServices.MarketerHandlers;
public class SignUpMarketerCommandHandler : IRequestHandler<SignUpMarketerCommand,MarketerProfileResponseDto>
public class SignUpMarketerCommandHandler(
UserManager<ApplicationUser> userManager,
IMediator mediator,
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper)
: 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
{
@ -38,16 +31,16 @@ public class SignUpMarketerCommandHandler : IRequestHandler<SignUpMarketerComman
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,31 +1,24 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class AddToOrderBagCommandHandler : IRequestHandler<AddToOrderBagCommand, OrderSDto>
public class AddToOrderBagCommandHandler(
IMediator mediator,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: 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);
@ -35,16 +28,16 @@ public class AddToOrderBagCommandHandler : IRequestHandler<AddToOrderBagCommand,
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, 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,22 +1,15 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class CheckOrderBagCommandHandler : IRequestHandler<CheckOrderBagCommand , List<CheckOrderBagResponseItem>>
public class CheckOrderBagCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: 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)
@ -35,7 +28,7 @@ public class CheckOrderBagCommandHandler : IRequestHandler<CheckOrderBagCommand
}
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,25 +1,19 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class GetUserOrderBagQueryHandler : IRequestHandler<GetUserOrderBagQuery,Order>
public class GetUserOrderBagQueryHandler(
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService,
IMediator mediator)
: 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)
@ -28,20 +22,20 @@ public class GetUserOrderBagQueryHandler : IRequestHandler<GetUserOrderBagQuery,
{
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,29 +1,23 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class RemoveFromOrderBagCommandHandler : IRequestHandler<RemoveFromOrderBagCommand, OrderSDto>
public class RemoveFromOrderBagCommandHandler(
ICurrentUserService currentUserService,
IRepositoryWrapper repositoryWrapper,
IMediator mediator)
: 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);
@ -37,9 +31,9 @@ public class RemoveFromOrderBagCommandHandler : IRequestHandler<RemoveFromOrderB
}
_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,18 +1,11 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitDiscountActionCommandHandler : IRequestHandler<SubmitDiscountActionCommand, OrderSDto>
public class SubmitDiscountActionCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<SubmitDiscountActionCommand, OrderSDto>
{
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public SubmitDiscountActionCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<OrderSDto> Handle(SubmitDiscountActionCommand 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)
@ -20,13 +13,13 @@ public class SubmitDiscountActionCommandHandler : IRequestHandler<SubmitDiscount
if (request.DiscountCode != null)
{
var discount = await _repositoryWrapper.SetRepository<Discount>()
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);
var isFirstUserOfDiscount = await mediator.Send(new CheckUserDiscountFirstUseCommand(request.DiscountCode), cancellationToken);
if (!isFirstUserOfDiscount)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "شما یک بار از این کد تخفیف استفاده نموده اید و قابلیت استفاده مجدد ندارید");
@ -36,9 +29,9 @@ public class SubmitDiscountActionCommandHandler : IRequestHandler<SubmitDiscount
else
order.RemoveDiscount();
_repositoryWrapper.SetRepository<Order>().Update(order);
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
var calculateOrder = await _mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);
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,31 +1,24 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitOrderBagCommandHandler : IRequestHandler<SubmitOrderBagCommand,OrderSDto>
public class SubmitOrderBagCommandHandler(
IMediator mediator,
IRepositoryWrapper repositoryWrapper,
ICurrentUserService currentUserService)
: 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);
@ -35,7 +28,7 @@ public class SubmitOrderBagCommandHandler : IRequestHandler<SubmitOrderBagComman
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, requestDto.Count);
@ -45,15 +38,15 @@ public class SubmitOrderBagCommandHandler : IRequestHandler<SubmitOrderBagComman
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,26 +2,19 @@
namespace Netina.Core.EntityServices.OrderBagHandlers;
public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeliveryCommand, OrderSDto>
public class SubmitOrderDeliveryCommandHandler(IMediator mediator, IRepositoryWrapper repositoryWrapper)
: 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)
@ -29,7 +22,7 @@ public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeli
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)
@ -37,10 +30,10 @@ public class SubmitOrderDeliveryCommandHandler : IRequestHandler<SubmitOrderDeli
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

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

@ -1,23 +1,18 @@
namespace Netina.Core.EntityServices.ReviewHandlers;
public class ConfirmReviewCommandHandler : IRequestHandler<ConfirmReviewCommand , bool>
public class ConfirmReviewCommandHandler(IRepositoryWrapper repositoryWrapper)
: 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
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);
repositoryWrapper.SetRepository<Review>().Update(review);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
return true;
}
}

View File

@ -1,33 +1,19 @@
namespace Netina.Core.EntityServices;
public class UserService : IUserService
public class UserService(
ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
IExternalFilesService externalFilesService,
IRepositoryWrapper repositoryWrapper)
: 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)
{
_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);
@ -36,14 +22,14 @@ public class UserService : IUserService
//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());
}
}
@ -57,23 +43,23 @@ public class UserService : IUserService
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 + " ";
}
@ -85,20 +71,20 @@ public class UserService : IUserService
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);
}
@ -113,7 +99,7 @@ public class UserService : IUserService
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;
@ -122,7 +108,7 @@ public class UserService : IUserService
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
@ -140,13 +126,13 @@ public class UserService : IUserService
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)));
}
@ -155,31 +141,31 @@ public class UserService : IUserService
{
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;
}
@ -189,7 +175,7 @@ public class UserService : IUserService
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;
@ -202,29 +188,29 @@ public class UserService : IUserService
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);
}
}
}
@ -234,10 +220,10 @@ public class UserService : IUserService
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;
@ -250,15 +236,15 @@ public class UserService : IUserService
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)));
}
@ -268,34 +254,34 @@ public class UserService : IUserService
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;
@ -303,26 +289,26 @@ public class UserService : IUserService
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;
@ -331,7 +317,7 @@ public class UserService : IUserService
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)
@ -343,9 +329,9 @@ public class UserService : IUserService
{
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
@ -355,13 +341,13 @@ public class UserService : IUserService
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();
@ -380,12 +366,12 @@ public class UserService : IUserService
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;
}
@ -393,7 +379,7 @@ public class UserService : IUserService
{
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("نقش پیدا نشد");
@ -402,20 +388,20 @@ public class UserService : IUserService
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)));
}
@ -425,18 +411,18 @@ public class UserService : IUserService
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,18 +1,11 @@
namespace Netina.Core.Models.Api;
public class ApiResult
public class ApiResult(bool isSuccess, ApiResultStatusCode statusCode, string message = null)
{
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; }
public bool IsSuccess { get; set; } = isSuccess;
public ApiResultStatusCode StatusCode { get; set; } = statusCode;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Message { get; set; }
public string Message { get; set; } = message ?? statusCode.ToDisplay();
#region Implicit Operators
@ -61,17 +54,12 @@ public class ApiResult
#endregion
}
public class ApiResult<TData> : ApiResult
public class ApiResult<TData>(bool isSuccess, ApiResultStatusCode statusCode, TData data, string message = null)
: ApiResult(isSuccess, statusCode, message)
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; }
public TData Data { get; set; } = data;
#region Implicit Operators

View File

@ -12,8 +12,8 @@
<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.4" />
<PackageReference Include="Quartz" Version="3.8.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Quartz" Version="3.12.0" />
<PackageReference Include="Syncfusion.Pdf.Net.Core" Version="26.1.35" />
</ItemGroup>

View File

@ -3,20 +3,11 @@ using Quartz;
namespace Netina.Core.QuartzServices;
public class JobScheduler
public class JobScheduler(IScheduler scheduler, ILogger<JobScheduler> logger)
{
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")
@ -33,10 +24,10 @@ public class JobScheduler
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,20 +3,11 @@ using Quartz;
namespace Netina.Core.QuartzServices;
public class SiteMapScheduledJob : IJob
public class SiteMapScheduledJob(ILogger<SiteMapScheduledJob> logger, ISiteMapService siteMapService) : 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,8 +1,23 @@
namespace Netina.Domain.CommandQueries.Commands;
public sealed record CreateBrandCommand(string PersianName,string EnglishName, string Description , bool HasSpecialPage , string PageUrl, List<StorageFileSDto> Files) : IRequest<Guid>;
public sealed record CreateBrandCommand(string PersianName,
string EnglishName,
string Description ,
bool HasSpecialPage ,
string PageUrl,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<Guid>;
public sealed record UpdateBrandCommand(Guid Id,string PersianName, string EnglishName, string Description, bool HasSpecialPage, string PageUrl, List<StorageFileSDto> Files) : IRequest<bool>;
public sealed record UpdateBrandCommand(Guid Id,
string PersianName,
string EnglishName,
string Description,
bool HasSpecialPage,
string PageUrl,
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record DeleteBrandCommand(Guid Id) : IRequest<bool>;

View File

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

View File

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

View File

@ -1,24 +1,26 @@
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):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,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<ProductLDto>;
public sealed record UpdateProductCommand(
Guid Id,
@ -39,9 +41,13 @@ public sealed record UpdateProductCommand(
Guid CategoryId,
DiscountSDto SpecialOffer,
List<SpecificationSDto> Specifications,
List<StorageFileSDto> Files) : IRequest<bool>;
List<StorageFileSDto> Files,
Dictionary<string, string> Faqs,
Dictionary<string, string> MetaTags) : IRequest<bool>;
public sealed record ChangeProductDisplayedCommand(Guid Id,bool BeDisplayed) : IRequest<bool>;
public sealed record ChangeProductDisplayedCommand(Guid Id, bool BeDisplayed) : IRequest<bool>;
public sealed record ChangeProductCostCommand(Guid Id, double Cost) : IRequest<bool>;
public sealed record DeleteProductCommand(Guid Id) : IRequest<bool>;

View File

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

View File

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

View File

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

View File

@ -0,0 +1,6 @@
namespace Netina.Domain.Dtos.ResponseDtos;
public class CkEditorFileUploadResponseDto
{
public string url { get; set; } = string.Empty;
}

View File

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

View File

@ -1,6 +1,4 @@
using Microsoft.IdentityModel.Tokens;
namespace Netina.Domain.Dtos.SmallDtos;
namespace Netina.Domain.Dtos.SmallDtos;
public class StorageFileSDto : BaseDto<StorageFileSDto , StorageFile>
{

View File

@ -1,6 +1,4 @@
using Microsoft.IdentityModel.Tokens;
namespace Netina.Domain.Entities.Blogs;
namespace Netina.Domain.Entities.Blogs;
public partial class Blog
{

View File

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

View File

@ -1,6 +1,4 @@
using System.Web;
namespace Netina.Domain.Entities.ProductCategories;
namespace Netina.Domain.Entities.ProductCategories;
public partial class ProductCategory
{

View File

@ -1,7 +1,4 @@
using System.Web;
using System.Xml.Linq;
namespace Netina.Domain.Entities.Products;
namespace Netina.Domain.Entities.Products;
public partial class Product
{

View File

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

View File

@ -0,0 +1,15 @@
namespace Netina.Domain.Enums;
public enum BannerSection
{
[Display(Name = "هیچ کدام")]
None = 0,
[Display(Name = "بنر تخفیف بالای سایت")]
TopOff = 1,
[Display(Name = "بنر تخفیف بالای سایت - موبایل")]
TopOffSm = 2,
[Display(Name = "بنر اسلایدری")]
Slider = 10,
[Display(Name = "بنر اسلایدری - موبایل")]
SliderSm = 11,
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,11 +9,7 @@ public class NavMenuSetting
public class NavMenuItem
{
public NavMenuItem()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public Guid Id { get; set; } = Guid.NewGuid();
public string Title { get; set; } = string.Empty;
public string Url { get; set; } = string.Empty;
public Guid ParentId { get; set; }

View File

@ -0,0 +1,17 @@
namespace Netina.Domain.MartenEntities.Settings;
public class PageSetting
{
public List<RedirectItem> RedirectItems { get; set; } = new();
public List<DeletedPageItem> DeletedPages { get; set; } = new();
}
public class DeletedPageItem
{
public string Url { get; set; } = string.Empty;
}
public class RedirectItem
{
public string OldUrl { get; set; } = string.Empty;
public string NewUrl { get; set; } = string.Empty;
}

View File

@ -0,0 +1,29 @@
namespace Netina.Domain.MartenEntities.Settings;
public class BannerItemModel
{
public string ImageLocation { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string Link { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public BannerSection Section { get; set; }
}
public class CatalogItemModel
{
public Guid Id { get; set; }
public string PersianName { get; set; } = string.Empty;
public string EnglishName { get; set; } = string.Empty;
public string Query { get; set; } = string.Empty;
public string ImageLocation { get; set; } = string.Empty;
public int Row { get; set; }
public bool IsMain { get; set; }
public Guid ParentId { get; set; }
public string ParentName { get; set; } = string.Empty;
}
public class PersonalizationSetting
{
public List<BannerItemModel> Banners { get; set; } = new();
public List<CatalogItemModel> Catalog { get; set; } = new();
}

View File

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

View File

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

View File

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

View File

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

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