Compare commits

...

3 Commits

19 changed files with 167 additions and 95 deletions

View File

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

View File

@ -1,4 +1,5 @@
using Netina.Domain.Enums; using Netina.Domain.Dtos.ResponseDtos;
using Netina.Domain.Enums;
namespace Netina.Api.Controllers; namespace Netina.Api.Controllers;
@ -18,6 +19,49 @@ public class FileController : ICarterModule
.WithDisplayName("UploadFileAsync") .WithDisplayName("UploadFileAsync")
.HasApiVersion(1.0); .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) public async Task<IResult> GetFilesAsync([FromQuery]StorageFileType? fileType,[FromServices] IStorageService storageService, CancellationToken cancellationToken)

View File

@ -24,6 +24,11 @@ public class OrderController : ICarterModule
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0); .HasApiVersion(1.0);
group.MapPost("{id}/cancel", CancelOrderStepAsync)
.WithDisplayName("ConfirmOrderStep")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
.HasApiVersion(1.0);
group.MapDelete("{id}", DeleteAsync) group.MapDelete("{id}", DeleteAsync)
.WithDisplayName("DeleteOneOrder") .WithDisplayName("DeleteOneOrder")
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders)) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
@ -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) 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)); => 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, public async Task<IResult> GetAllAsync(IMediator mediator,
[FromQuery]string? factorCode, [FromQuery]string? factorCode,
[FromQuery]long? selectedDate, [FromQuery]long? selectedDate,

View File

@ -11,35 +11,35 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <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="Asp.Versioning.Http" Version="8.1.0" />
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" /> <PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
<PackageReference Include="Carter" Version="8.0.0" /> <PackageReference Include="Carter" Version="8.2.1" />
<PackageReference Include="FluentValidation" Version="11.9.0" /> <PackageReference Include="FluentValidation" Version="11.9.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.0" /> <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.0" />
<PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="12.0.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.NewtonsoftJson" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.4" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Autofac" Version="8.0.0" /> <PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" /> <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Elmah.Io.AspNetCore.Serilog" Version="5.0.17" /> <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.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Sentry.Serilog" Version="4.4.0" /> <PackageReference Include="Sentry.Serilog" Version="4.9.0" />
<PackageReference Include="Serilog" Version="3.1.1" /> <PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.3.0" /> <PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.3.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="7.0.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.AspNetCore" Version="10.2.0" />
<PackageReference Include="StackExchange.Redis.Extensions.Core" 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="StackExchange.Redis.Extensions.Newtonsoft" Version="10.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.1" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" /> <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>
<ItemGroup> <ItemGroup>

View File

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

View File

@ -5,6 +5,9 @@ namespace Netina.Common.Extensions
{ {
public static class StringExtensions public static class StringExtensions
{ {
public static bool IsNullOrEmpty(this string value)
=> string.IsNullOrEmpty(value);
public static string GetSlug(string title) public static string GetSlug(string title)
{ {
return HttpUtility.UrlEncode(title.Replace(' ', '-')); return HttpUtility.UrlEncode(title.Replace(' ', '-'));

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<!--<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@ -11,10 +11,10 @@
<PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" /> <PackageReference Include="MD.PersianDateTime.Standard" Version="2.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <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>--> </ItemGroup>
<PropertyGroup> <!--<PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@ -25,7 +25,7 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" />
</ItemGroup> </ItemGroup>-->
<ItemGroup> <ItemGroup>
<Using Include="MD.PersianDateTime.Standard" /> <Using Include="MD.PersianDateTime.Standard" />

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

@ -12,8 +12,8 @@
<PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" /> <PackageReference Include="AspNetCoreRateLimit.Redis" Version="2.0.0" />
<PackageReference Include="Autofac.Extras.Quartz" Version="10.0.0" /> <PackageReference Include="Autofac.Extras.Quartz" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Quartz" Version="3.8.1" /> <PackageReference Include="Quartz" Version="3.12.0" />
<PackageReference Include="Syncfusion.Pdf.Net.Core" Version="26.1.35" /> <PackageReference Include="Syncfusion.Pdf.Net.Core" Version="26.1.35" />
</ItemGroup> </ItemGroup>

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 CalculateOrderCommand(Guid OrderId , bool NamoosiCalculate = false) : IRequest<Order>;
public sealed record ConfirmOrderStepCommand(Guid OrderId , OrderStatus NextOrderStatus,string? TrackingCode) : IRequest<bool>; 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 GetOrderInvoiceCommand(Guid OrderId) : IRequest<byte[]>;
public sealed record DeleteOrderCommand(Guid OrderId) : IRequest<bool>; public sealed record DeleteOrderCommand(Guid OrderId) : IRequest<bool>;

View File

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

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<!--<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@ -11,12 +11,12 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Mapster" Version="7.4.0" /> <PackageReference Include="Mapster" Version="7.4.0" />
<PackageReference Include="Mapster.Core" Version="1.2.1" /> <PackageReference Include="Mapster.Core" Version="1.2.1" />
<PackageReference Include="MediatR" Version="12.2.0" /> <PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.4" /> <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.7" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" /> <PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
</ItemGroup>--> </ItemGroup>
<PropertyGroup> <!--<PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@ -32,7 +32,7 @@
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" /> <PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
</ItemGroup> </ItemGroup>-->
<ItemGroup> <ItemGroup>

View File

@ -8,8 +8,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Marten" Version="7.8.0" /> <PackageReference Include="Marten" Version="7.26.1" />
<PackageReference Include="AWSSDK.S3" Version="3.7.307.19" /> <PackageReference Include="AWSSDK.S3" Version="3.7.400.2" />
<PackageReference Include="Refit" Version="7.0.0" /> <PackageReference Include="Refit" Version="7.0.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,15 +1,22 @@
namespace Netina.Repository.Handlers.Discounts; using Microsoft.EntityFrameworkCore;
public class CreateDiscountCommandHandler : IRequestHandler<CreateDiscountCommand , DiscountLDto> namespace Netina.Repository.Handlers.Discounts;
{
private readonly IRepositoryWrapper _repositoryWrapper;
public CreateDiscountCommandHandler(IRepositoryWrapper repositoryWrapper) public class CreateDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<CreateDiscountCommand, DiscountLDto>
{ {
_repositoryWrapper = repositoryWrapper;
}
public async Task<DiscountLDto> Handle(CreateDiscountCommand request, CancellationToken cancellationToken) public async Task<DiscountLDto> Handle(CreateDiscountCommand request, CancellationToken cancellationToken)
{ {
if (request.HasCode)
{
var foundDiscount = await repositoryWrapper.SetRepository<Discount>()
.TableNoTracking
.Where(d => d.Code == request.Code)
.FirstOrDefaultAsync(cancellationToken);
if (foundDiscount != null)
throw new BaseApiException(ApiResultStatusCode.BadRequest, "کد تخفیف مورد نظر تکراری می باشد");
}
switch (request.Type) switch (request.Type)
{ {
case DiscountType.All: case DiscountType.All:
@ -17,14 +24,14 @@ public class CreateDiscountCommandHandler : IRequestHandler<CreateDiscountComman
request.HasCode, request.AmountType, request.Type, request.Count,request.IsImmortal, request.StartDate, request.HasCode, request.AmountType, request.Type, request.Count,request.IsImmortal, request.StartDate,
request.ExpireDate, request.PriceFloor, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.ExpireDate, request.PriceFloor, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling,
request.IsInfinity, request.UseCount, request.IsForInvitation,request.IsForFirstPurchase,request.IsSpecialOffer); request.IsInfinity, request.UseCount, request.IsForInvitation,request.IsForFirstPurchase,request.IsSpecialOffer);
_repositoryWrapper.SetRepository<Discount>().Add(ent); repositoryWrapper.SetRepository<Discount>().Add(ent);
break; break;
case DiscountType.Category: case DiscountType.Category:
var catDis = CategoryDiscount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode, var catDis = CategoryDiscount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count,request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count,request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation,request.IsForFirstPurchase,request.IsSpecialOffer, request.CategoryId); request.IsForInvitation,request.IsForFirstPurchase,request.IsSpecialOffer, request.CategoryId);
_repositoryWrapper.SetRepository<CategoryDiscount>().Add(catDis); repositoryWrapper.SetRepository<CategoryDiscount>().Add(catDis);
break; break;
case DiscountType.Product: case DiscountType.Product:
@ -32,17 +39,17 @@ public class CreateDiscountCommandHandler : IRequestHandler<CreateDiscountComman
request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation,request.IsForFirstPurchase, request.IsSpecialOffer,request.ProductId); request.IsForInvitation,request.IsForFirstPurchase, request.IsSpecialOffer,request.ProductId);
_repositoryWrapper.SetRepository<ProductDiscount>().Add(productDis); repositoryWrapper.SetRepository<ProductDiscount>().Add(productDis);
break; break;
default: default:
var def = Discount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode, var def = Discount.Create(request.Code,request.Description, request.DiscountPercent, request.DiscountAmount, request.HasCode,
request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor, request.AmountType, request.Type, request.Count, request.IsImmortal, request.StartDate, request.ExpireDate, request.PriceFloor,
request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount, request.HasPriceFloor, request.PriceCeiling, request.HasPriceCeiling, request.IsInfinity, request.UseCount,
request.IsForInvitation, request.IsForFirstPurchase,request.IsSpecialOffer); request.IsForInvitation, request.IsForFirstPurchase,request.IsSpecialOffer);
_repositoryWrapper.SetRepository<Discount>().Add(def); repositoryWrapper.SetRepository<Discount>().Add(def);
break; break;
} }
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
return request.Adapt<DiscountLDto>(); return request.Adapt<DiscountLDto>();
} }
} }

View File

@ -2,20 +2,15 @@
namespace Netina.Repository.Handlers.Discounts; namespace Netina.Repository.Handlers.Discounts;
public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountCommand, bool> public class UpdateDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
: IRequestHandler<UpdateDiscountCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
public UpdateDiscountCommandHandler(IRepositoryWrapper repositoryWrapper)
{
_repositoryWrapper = repositoryWrapper;
}
public async Task<bool> Handle(UpdateDiscountCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(UpdateDiscountCommand request, CancellationToken cancellationToken)
{ {
switch (request.Type) switch (request.Type)
{ {
case DiscountType.All: case DiscountType.All:
var ent = await _repositoryWrapper.SetRepository<Discount>().TableNoTracking.FirstOrDefaultAsync(d=>d.Id==request.Id,cancellationToken); var ent = await repositoryWrapper.SetRepository<Discount>().TableNoTracking.FirstOrDefaultAsync(d=>d.Id==request.Id,cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Discount not found", ApiResultStatusCode.NotFound); throw new AppException("Discount not found", ApiResultStatusCode.NotFound);
var newEnt = Discount.Create(request.Code,request.Description, var newEnt = Discount.Create(request.Code,request.Description,
@ -27,10 +22,10 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
newEnt.Id = ent.Id; newEnt.Id = ent.Id;
newEnt.CreatedAt = ent.CreatedAt; newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy; newEnt.CreatedBy = ent.CreatedBy;
_repositoryWrapper.SetRepository<Discount>().Update(newEnt); repositoryWrapper.SetRepository<Discount>().Update(newEnt);
break; break;
case DiscountType.Category: case DiscountType.Category:
var catEnt = await _repositoryWrapper.SetRepository<CategoryDiscount>().TableNoTracking.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken); var catEnt = await repositoryWrapper.SetRepository<CategoryDiscount>().TableNoTracking.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken);
if (catEnt == null) if (catEnt == null)
throw new AppException("Discount not found", ApiResultStatusCode.NotFound); throw new AppException("Discount not found", ApiResultStatusCode.NotFound);
@ -43,11 +38,11 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
catDis.Id = catEnt.Id; catDis.Id = catEnt.Id;
catDis.CreatedAt = catEnt.CreatedAt; catDis.CreatedAt = catEnt.CreatedAt;
catDis.CreatedBy = catEnt.CreatedBy; catDis.CreatedBy = catEnt.CreatedBy;
_repositoryWrapper.SetRepository<CategoryDiscount>().Update(catDis); repositoryWrapper.SetRepository<CategoryDiscount>().Update(catDis);
break; break;
case DiscountType.Product: case DiscountType.Product:
var productEnt = await _repositoryWrapper.SetRepository<ProductDiscount>().TableNoTracking.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken); var productEnt = await repositoryWrapper.SetRepository<ProductDiscount>().TableNoTracking.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken);
if (productEnt == null) if (productEnt == null)
throw new AppException("Discount not found", ApiResultStatusCode.NotFound); throw new AppException("Discount not found", ApiResultStatusCode.NotFound);
@ -60,10 +55,10 @@ public class UpdateDiscountCommandHandler : IRequestHandler<UpdateDiscountComman
productDis.Id = productEnt.Id; productDis.Id = productEnt.Id;
productDis.CreatedAt = productEnt.CreatedAt; productDis.CreatedAt = productEnt.CreatedAt;
productDis.CreatedBy = productEnt.CreatedBy; productDis.CreatedBy = productEnt.CreatedBy;
_repositoryWrapper.SetRepository<ProductDiscount>().Update(productDis); repositoryWrapper.SetRepository<ProductDiscount>().Update(productDis);
break; break;
} }
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
return true; return true;
} }
} }

View File

@ -2,19 +2,12 @@
namespace Netina.Repository.Handlers.Products; namespace Netina.Repository.Handlers.Products;
public class GetProductQueryHandler : IRequestHandler<GetProductQuery, GetProductResponseDto> public class GetProductQueryHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<GetProductQuery, GetProductResponseDto>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public GetProductQueryHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<GetProductResponseDto> Handle(GetProductQuery request, CancellationToken cancellationToken) public async Task<GetProductResponseDto> Handle(GetProductQuery request, CancellationToken cancellationToken)
{ {
var ent = await _repositoryWrapper.SetRepository<Product>().TableNoTracking var ent = await repositoryWrapper.SetRepository<Product>().TableNoTracking
.Where(b => b.Id == request.Id) .Where(b => b.Id == request.Id)
.Select(ProductMapper.ProjectToLDto) .Select(ProductMapper.ProjectToLDto)
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
@ -22,7 +15,7 @@ public class GetProductQueryHandler : IRequestHandler<GetProductQuery, GetProduc
if (ent == null) if (ent == null)
throw new AppException("Product not found", ApiResultStatusCode.NotFound); throw new AppException("Product not found", ApiResultStatusCode.NotFound);
await _mediator.Send(new CalculateProductDiscountCommand(ent), cancellationToken); await mediator.Send(new CalculateProductDiscountCommand(ent), cancellationToken);
var response = new GetProductResponseDto var response = new GetProductResponseDto
{ {

View File

@ -2,19 +2,12 @@
namespace Netina.Repository.Handlers.Products; namespace Netina.Repository.Handlers.Products;
public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand, bool> public class UpdateProductCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
: IRequestHandler<UpdateProductCommand, bool>
{ {
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IMediator _mediator;
public UpdateProductCommandHandler(IRepositoryWrapper repositoryWrapper,IMediator mediator)
{
_repositoryWrapper = repositoryWrapper;
_mediator = mediator;
}
public async Task<bool> Handle(UpdateProductCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(UpdateProductCommand request, CancellationToken cancellationToken)
{ {
var ent = await _repositoryWrapper.SetRepository<Product>().TableNoTracking var ent = await repositoryWrapper.SetRepository<Product>().TableNoTracking
.FirstOrDefaultAsync(e => e.Id == request.Id, cancellationToken); .FirstOrDefaultAsync(e => e.Id == request.Id, cancellationToken);
if (ent == null) if (ent == null)
throw new AppException("Product not found", ApiResultStatusCode.NotFound); throw new AppException("Product not found", ApiResultStatusCode.NotFound);
@ -34,14 +27,14 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
newEnt.CreatedAt = ent.CreatedAt; newEnt.CreatedAt = ent.CreatedAt;
newEnt.CreatedBy = ent.CreatedBy; newEnt.CreatedBy = ent.CreatedBy;
var dbSpecifications = await _repositoryWrapper.SetRepository<Specification>().TableNoTracking var dbSpecifications = await repositoryWrapper.SetRepository<Specification>().TableNoTracking
.Where(s => s.ProductId == ent.Id).ToListAsync(cancellationToken); .Where(s => s.ProductId == ent.Id).ToListAsync(cancellationToken);
foreach (var dbSpecification in dbSpecifications) foreach (var dbSpecification in dbSpecifications)
{ {
if (request.Specifications.FirstOrDefault(s => s.Id != dbSpecification.Id) == null) if (request.Specifications.FirstOrDefault(s => s.Id != dbSpecification.Id) == null)
{ {
_repositoryWrapper.SetRepository<Specification>().Delete(dbSpecification); repositoryWrapper.SetRepository<Specification>().Delete(dbSpecification);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
} }
foreach (var specification in request.Specifications.Where(s => s.Id == default)) foreach (var specification in request.Specifications.Where(s => s.Id == default))
@ -51,14 +44,14 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
var dbFiles = await _repositoryWrapper.SetRepository<ProductStorageFile>().TableNoTracking var dbFiles = await repositoryWrapper.SetRepository<ProductStorageFile>().TableNoTracking
.Where(s => s.ProductId == ent.Id).ToListAsync(cancellationToken); .Where(s => s.ProductId == ent.Id).ToListAsync(cancellationToken);
foreach (var dbFile in dbFiles) foreach (var dbFile in dbFiles)
{ {
if (request.Files.FirstOrDefault(s => s.Id == dbFile.Id)==null) if (request.Files.FirstOrDefault(s => s.Id == dbFile.Id)==null)
{ {
_repositoryWrapper.SetRepository<ProductStorageFile>().Delete(dbFile); repositoryWrapper.SetRepository<ProductStorageFile>().Delete(dbFile);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
} }
} }
foreach (var file in request.Files.Where(f=>f.Id==default)) foreach (var file in request.Files.Where(f=>f.Id==default))
@ -67,8 +60,8 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
} }
_repositoryWrapper.SetRepository<Product>().Update(newEnt); repositoryWrapper.SetRepository<Product>().Update(newEnt);
await _repositoryWrapper.SaveChangesAsync(cancellationToken); await repositoryWrapper.SaveChangesAsync(cancellationToken);
if (request.IsSpecialOffer) if (request.IsSpecialOffer)
{ {
@ -81,12 +74,12 @@ public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand,
if (request.SpecialOffer.Id == default) if (request.SpecialOffer.Id == default)
{ {
var discountRequest = discount.Adapt<CreateDiscountCommand>(); var discountRequest = discount.Adapt<CreateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken); await mediator.Send(discountRequest, cancellationToken);
} }
else else
{ {
var discountRequest = discount.Adapt<UpdateDiscountCommand>(); var discountRequest = discount.Adapt<UpdateDiscountCommand>();
await _mediator.Send(discountRequest, cancellationToken); await mediator.Send(discountRequest, cancellationToken);
} }
} }

View File

@ -9,21 +9,21 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="FuzzySharp" Version="2.0.2" /> <PackageReference Include="FuzzySharp" Version="2.0.2" />
<PackageReference Include="MediatR" Version="12.2.0" /> <PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="FluentValidation" Version="11.9.0" /> <PackageReference Include="FluentValidation" Version="11.9.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Pluralize.NET" Version="1.0.2" /> <PackageReference Include="Pluralize.NET" Version="1.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.4" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="StackExchange.Redis" Version="2.7.33" /> <PackageReference Include="StackExchange.Redis" Version="2.7.33" />
<PackageReference Include="StackExchange.Redis.Extensions.Core" Version="10.2.0" /> <PackageReference Include="StackExchange.Redis.Extensions.Core" Version="10.2.0" />
</ItemGroup> </ItemGroup>

View File

@ -8,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.60" /> <PackageReference Include="HtmlAgilityPack" Version="1.11.62" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Refit" Version="7.0.0" /> <PackageReference Include="Refit" Version="7.0.0" />
<PackageReference Include="Refit.Newtonsoft.Json" Version="7.0.0" /> <PackageReference Include="Refit.Newtonsoft.Json" Version="7.0.0" />