feat : add version 0.25.27.48 , add CS system
parent
5f615ea13b
commit
0e2b99d85e
|
@ -17,7 +17,7 @@
|
||||||
"TaxesFee": 9
|
"TaxesFee": 9
|
||||||
},
|
},
|
||||||
"SiteSettings": {
|
"SiteSettings": {
|
||||||
"BaseUrl": "http://localhost:32770",
|
"BaseUrl": "http://192.168.1.12:32770",
|
||||||
"WebSiteUrl": "https://vesmeh.com",
|
"WebSiteUrl": "https://vesmeh.com",
|
||||||
"AdminPanelBaseUrl": "https://admin.vesmeh.com",
|
"AdminPanelBaseUrl": "https://admin.vesmeh.com",
|
||||||
"StorageBaseUrl": "https://storage.vesmeh.com",
|
"StorageBaseUrl": "https://storage.vesmeh.com",
|
||||||
|
|
|
@ -22,10 +22,6 @@ public class DiscountController : ICarterModule
|
||||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts))
|
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts, ApplicationPermission.ViewDiscounts))
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
group.MapGet("corporate", GetCorporateDiscountAsync)
|
|
||||||
.WithDisplayName("GetDiscount")
|
|
||||||
.HasApiVersion(1.0);
|
|
||||||
|
|
||||||
group.MapPost("", Post)
|
group.MapPost("", Post)
|
||||||
.HasApiVersion(1.0)
|
.HasApiVersion(1.0)
|
||||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
|
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
|
||||||
|
@ -39,10 +35,6 @@ public class DiscountController : ICarterModule
|
||||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
|
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageDiscounts));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IResult> GetCorporateDiscountAsync([FromQuery] Guid? corporateUserId, [FromServices] IMediator mediator, CancellationToken cancellationToken)
|
|
||||||
=> TypedResults.Ok(await mediator.Send(
|
|
||||||
new CreateSaleCooperationDiscount(CorporateUserId: corporateUserId ?? default), cancellationToken));
|
|
||||||
|
|
||||||
// GET:Get All Entity
|
// GET:Get All Entity
|
||||||
private async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator,
|
private async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using MD.PersianDateTime.Standard;
|
using MD.PersianDateTime.Standard;
|
||||||
using Netina.Common.Models.Api;
|
|
||||||
using Netina.Core.BaseServices.Abstracts;
|
|
||||||
|
|
||||||
namespace Netina.Api.Controller;
|
namespace Netina.Api.Controller;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
using Netina.Domain.MartenEntities.Settings;
|
||||||
|
|
||||||
|
namespace Netina.Api.Controller;
|
||||||
|
|
||||||
|
public class MarketerController : ICarterModule
|
||||||
|
{
|
||||||
|
public void AddRoutes(IEndpointRouteBuilder app)
|
||||||
|
{
|
||||||
|
var group = app.NewVersionedApi("Marketer")
|
||||||
|
.MapGroup("api/marketer")
|
||||||
|
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());
|
||||||
|
|
||||||
|
group.MapGet("", GetMarketersAsync)
|
||||||
|
.WithDisplayName("GetAllMarketers")
|
||||||
|
.RequireAuthorization(builder=>builder.RequireClaim(CustomClaimType.Permission,ApplicationPermission.ManageUsers , ApplicationPermission.ViewUsers))
|
||||||
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
group.MapGet("profile", GetMarketerProfileAsync)
|
||||||
|
.WithDisplayName("GetAllMarketers")
|
||||||
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
group.MapPost("signup", SignUpMarketerAsync)
|
||||||
|
.WithDisplayName("SignUpMarketer")
|
||||||
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
group.MapGet("signup/contract", GetSignUpMarketerContractAsync)
|
||||||
|
.WithDisplayName("SignUpMarketerContract")
|
||||||
|
.HasApiVersion(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IResult> GetMarketerProfileAsync(IMediator mediator, CancellationToken cancellationToken)
|
||||||
|
=> TypedResults.Ok(await mediator.Send(new GetMarketerProfileQuery(), cancellationToken));
|
||||||
|
|
||||||
|
private async Task<IResult> GetSignUpMarketerContractAsync([FromServices] ISettingService settingService,CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var setting = await settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken);
|
||||||
|
if (setting is MarketerSetting marketerSetting)
|
||||||
|
return TypedResults.Ok(marketerSetting.ContractTerms);
|
||||||
|
throw new AppException("MarketerSetting not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IResult> SignUpMarketerAsync([FromBody] SignUpMarketerCommand request, [FromServices] IMediator mediator, CancellationToken cancellationToken)
|
||||||
|
=> TypedResults.Ok(await mediator.Send(request, cancellationToken));
|
||||||
|
|
||||||
|
private async Task<IResult> GetMarketersAsync([FromQuery] int page, [FromServices] IMediator mediator, CancellationToken cancellationToken)
|
||||||
|
=> TypedResults.Ok(await mediator.Send(new GetMarketersQuery(page), cancellationToken));
|
||||||
|
}
|
|
@ -6,8 +6,8 @@
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<InvariantGlobalization>true</InvariantGlobalization>
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
<AssemblyVersion>0.24.27.47</AssemblyVersion>
|
<AssemblyVersion>0.25.27.48</AssemblyVersion>
|
||||||
<FileVersion>0.24.27.47</FileVersion>
|
<FileVersion>0.25.27.48</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -8,7 +8,7 @@ string env = builder.Environment.IsDevelopment() == true ? "Development" : "Prod
|
||||||
builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
|
builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
|
||||||
if (builder.Environment.IsDevelopment())
|
if (builder.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
string projectName = "Hamyan";
|
string projectName = "Vesmeh";
|
||||||
builder.Configuration.AddJsonFile($"AppSettings/appsettings.json").AddJsonFile($"AppSettings/appsettings.{env}{projectName}.json");
|
builder.Configuration.AddJsonFile($"AppSettings/appsettings.json").AddJsonFile($"AppSettings/appsettings.{env}{projectName}.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ public class ExceptionHandlerMiddleware
|
||||||
});
|
});
|
||||||
|
|
||||||
if (httpStatusCode == HttpStatusCode.InternalServerError)
|
if (httpStatusCode == HttpStatusCode.InternalServerError)
|
||||||
context.Response.StatusCode = 501;
|
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
else
|
else
|
||||||
context.Response.StatusCode = (int)httpStatusCode;
|
context.Response.StatusCode = (int)httpStatusCode;
|
||||||
context.Response.ContentType = "application/json";
|
context.Response.ContentType = "application/json";
|
||||||
|
@ -174,7 +174,7 @@ public class ExceptionHandlerMiddleware
|
||||||
});
|
});
|
||||||
|
|
||||||
if (httpStatusCode == HttpStatusCode.InternalServerError)
|
if (httpStatusCode == HttpStatusCode.InternalServerError)
|
||||||
context.Response.StatusCode = 501;
|
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
else
|
else
|
||||||
context.Response.StatusCode = (int)httpStatusCode;
|
context.Response.StatusCode = (int)httpStatusCode;
|
||||||
context.Response.ContentType = "application/json";
|
context.Response.ContentType = "application/json";
|
||||||
|
|
|
@ -36,6 +36,9 @@ namespace Netina.Common.Models.Api
|
||||||
|
|
||||||
|
|
||||||
[Display(Name = "در ارسال درخواست به سرورهای دیگر مشکلی رخ داده است")]
|
[Display(Name = "در ارسال درخواست به سرورهای دیگر مشکلی رخ داده است")]
|
||||||
RefitError = 8
|
RefitError = 8,
|
||||||
|
|
||||||
|
[Display(Name = "بازاریاب پیدا نشد یا ثبت نام نکرده است")]
|
||||||
|
MarketerNotFound = 9,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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>
|
||||||
|
@ -12,9 +12,9 @@
|
||||||
<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="7.5.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" />
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
using Netina.Common.Models.Api;
|
namespace Netina.Core.CoreServices;
|
||||||
using Netina.Common.Models.Exception;
|
|
||||||
using Netina.Core.CoreServices.Abstracts;
|
|
||||||
using Netina.Domain;
|
|
||||||
using Netina.Domain.MartenEntities.Settings;
|
|
||||||
using Netina.Repository.Repositories.Marten;
|
|
||||||
|
|
||||||
namespace Netina.Core.CoreServices;
|
|
||||||
|
|
||||||
|
|
||||||
public class SettingService : ISettingService
|
public class SettingService : ISettingService
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
namespace Netina.Core.EntityServices.MarketerHandlers;
|
||||||
|
|
||||||
namespace Netina.Repository.Handlers.Discounts;
|
public class CreateMarketerDiscountCommandHandler : IRequestHandler<CreateMarketerDiscountCommand, string>
|
||||||
|
|
||||||
public class CreateSaleCooperationDiscountHandler : IRequestHandler<CreateSaleCooperationDiscount,string>
|
|
||||||
{
|
{
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||||
private readonly ICurrentUserService _currentUserService;
|
private readonly ICurrentUserService _currentUserService;
|
||||||
|
private readonly ISettingService _settingService;
|
||||||
|
|
||||||
public CreateSaleCooperationDiscountHandler(UserManager<ApplicationUser> userManager,IRepositoryWrapper repositoryWrapper,ICurrentUserService currentUserService)
|
public CreateMarketerDiscountCommandHandler(UserManager<ApplicationUser> userManager,
|
||||||
|
IRepositoryWrapper repositoryWrapper,
|
||||||
|
ICurrentUserService currentUserService,
|
||||||
|
ISettingService settingService)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_repositoryWrapper = repositoryWrapper;
|
_repositoryWrapper = repositoryWrapper;
|
||||||
_currentUserService = currentUserService;
|
_currentUserService = currentUserService;
|
||||||
|
_settingService = settingService;
|
||||||
}
|
}
|
||||||
public async Task<string> Handle(CreateSaleCooperationDiscount request, CancellationToken cancellationToken)
|
public async Task<string> Handle(CreateMarketerDiscountCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var userId = request.CorporateUserId;
|
var userId = request.MarketerUserId;
|
||||||
if (userId == default)
|
if (userId == default)
|
||||||
{
|
{
|
||||||
if (_currentUserService.UserId == null)
|
if (_currentUserService.UserId == null)
|
||||||
|
@ -34,16 +37,20 @@ public class CreateSaleCooperationDiscountHandler : IRequestHandler<CreateSaleCo
|
||||||
|
|
||||||
if (marketer == null)
|
if (marketer == null)
|
||||||
throw new AppException("Marketer not found", ApiResultStatusCode.NotFound);
|
throw new AppException("Marketer not found", ApiResultStatusCode.NotFound);
|
||||||
|
|
||||||
var foundedDiscount = await _repositoryWrapper.SetRepository<Discount>()
|
var foundedDiscount = await _repositoryWrapper.SetRepository<Discount>()
|
||||||
.TableNoTracking
|
.TableNoTracking
|
||||||
.FirstOrDefaultAsync(d => d.IsForSaleCooperation && d.MarketerId == marketer.Id, cancellationToken);
|
.FirstOrDefaultAsync(d => d.IsForSaleCooperation && d.MarketerId == marketer.Id, cancellationToken);
|
||||||
if (foundedDiscount == null)
|
if (foundedDiscount == null)
|
||||||
{
|
{
|
||||||
|
var setting = await _settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken);
|
||||||
|
int discountPercent = 10;
|
||||||
|
if (setting is MarketerSetting marketerSetting)
|
||||||
|
discountPercent = marketerSetting.DiscountPercent;
|
||||||
|
|
||||||
var code = StringExtensions.GetId();
|
var code = StringExtensions.GetId();
|
||||||
foundedDiscount = Discount.Create(code,$"کد مخصوص همکاری در فروش برای کاربر - {user.FirstName} {user.LastName}", 10, 0, true,
|
foundedDiscount = Discount.Create(code, $"کد مخصوص همکاری در فروش برای کاربر - {user.FirstName} {user.LastName}", discountPercent, 0, true,
|
||||||
DiscountAmountType.Percent, DiscountType.All, 0, true, DateTime.Today, DateTime.Today.AddYears(10), 0,
|
DiscountAmountType.Percent, DiscountType.All, 0, true, DateTime.Today, DateTime.Today.AddYears(10), 0,
|
||||||
false, 0, false, true, 0, false, false,false);
|
false, 0, false, true, 0, false, false, false);
|
||||||
foundedDiscount.SetCorporate(marketer.Id);
|
foundedDiscount.SetCorporate(marketer.Id);
|
||||||
|
|
||||||
_repositoryWrapper.SetRepository<Discount>().Add(foundedDiscount);
|
_repositoryWrapper.SetRepository<Discount>().Add(foundedDiscount);
|
|
@ -0,0 +1,72 @@
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace Netina.Core.EntityServices.MarketerHandlers;
|
||||||
|
|
||||||
|
public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfileQuery, MarketerProfileResponseDto>
|
||||||
|
{
|
||||||
|
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||||
|
private readonly ICurrentUserService _currentUserService;
|
||||||
|
private readonly ISettingService _settingService;
|
||||||
|
|
||||||
|
public GetMarketerProfileQueryHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService,ISettingService settingService)
|
||||||
|
{
|
||||||
|
_repositoryWrapper = repositoryWrapper;
|
||||||
|
_currentUserService = currentUserService;
|
||||||
|
_settingService = settingService;
|
||||||
|
}
|
||||||
|
public async Task<MarketerProfileResponseDto> Handle(GetMarketerProfileQuery request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
Guid marketerId;
|
||||||
|
Marketer? marketer;
|
||||||
|
if (request.MarketerId != null)
|
||||||
|
{
|
||||||
|
marketerId = request.MarketerId.Value;
|
||||||
|
marketer = await _repositoryWrapper.SetRepository<Marketer>()
|
||||||
|
.TableNoTracking
|
||||||
|
.FirstOrDefaultAsync(m => m.Id == marketerId, cancellationToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_currentUserService.UserId == null)
|
||||||
|
throw new BaseApiException("User id is null");
|
||||||
|
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
|
||||||
|
throw new BaseApiException("User id is wrong");
|
||||||
|
marketer = await _repositoryWrapper.SetRepository<Marketer>()
|
||||||
|
.TableNoTracking
|
||||||
|
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (marketer == null)
|
||||||
|
throw new BaseApiException(ApiResultStatusCode.MarketerNotFound,"Marketer not found" ,HttpStatusCode.NotFound);
|
||||||
|
|
||||||
|
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;
|
||||||
|
if (setting == null)
|
||||||
|
throw new BaseApiException("MarketerSetting is null");
|
||||||
|
|
||||||
|
|
||||||
|
var response = new MarketerProfileResponseDto();
|
||||||
|
|
||||||
|
var orderCount = await _repositoryWrapper.SetRepository<Order>()
|
||||||
|
.TableNoTracking
|
||||||
|
.CountAsync(o => o.DiscountCode == discount.Code, cancellationToken);
|
||||||
|
response.OrderCount = orderCount;
|
||||||
|
|
||||||
|
var newTotalProductPrice = await _repositoryWrapper.SetRepository<Order>()
|
||||||
|
.TableNoTracking
|
||||||
|
.Where(o => o.DiscountCode == discount.Code && o.OrderAt.Date > marketer.LastSettlement.Date)
|
||||||
|
.SumAsync(o => o.TotalProductsPrice, cancellationToken);
|
||||||
|
response.Balance = (long)(newTotalProductPrice / 100) * setting.ProfitPercent;
|
||||||
|
response.DiscountCode = discount.Code;
|
||||||
|
response.LastSettlementAt = marketer.LastSettlement;
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
namespace Netina.Core.EntityServices.MarketerHandlers;
|
||||||
|
|
||||||
|
public class SignUpMarketerCommandHandler : IRequestHandler<SignUpMarketerCommand,MarketerProfileResponseDto>
|
||||||
|
{
|
||||||
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
private readonly ICurrentUserService _currentUserService;
|
||||||
|
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||||
|
|
||||||
|
public SignUpMarketerCommandHandler(UserManager<ApplicationUser> userManager,IMediator mediator,ICurrentUserService currentUserService,IRepositoryWrapper repositoryWrapper)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_mediator = mediator;
|
||||||
|
_currentUserService = currentUserService;
|
||||||
|
_repositoryWrapper = repositoryWrapper;
|
||||||
|
}
|
||||||
|
public async Task<MarketerProfileResponseDto> Handle(SignUpMarketerCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_currentUserService.UserId == null)
|
||||||
|
throw new AppException("User id is null");
|
||||||
|
if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
|
||||||
|
throw new AppException("User id is wrong");
|
||||||
|
|
||||||
|
var user = await _userManager.FindByIdAsync(_currentUserService.UserId);
|
||||||
|
if (user == null)
|
||||||
|
throw new AppException("User not found");
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
marketer = new Marketer
|
||||||
|
{
|
||||||
|
UserId = user.Id,
|
||||||
|
FatherName = request.FatherName,
|
||||||
|
Shaba = request.Shaba,
|
||||||
|
};
|
||||||
|
_repositoryWrapper.SetRepository<Marketer>()
|
||||||
|
.Add(marketer);
|
||||||
|
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||||
|
|
||||||
|
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDate);
|
||||||
|
user.NationalId = request.NationalId;
|
||||||
|
await _userManager.UpdateAsync(user);
|
||||||
|
|
||||||
|
await _mediator.Send(new CreateMarketerDiscountCommand(userId), cancellationToken);
|
||||||
|
|
||||||
|
return await _mediator.Send(new GetMarketerProfileQuery(marketer.Id), cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace Netina.Core.EntityServices.MarketerHandlers.Validators;
|
||||||
|
|
||||||
|
public class SignUpMarketerCommandValidator : AbstractValidator<SignUpMarketerCommand>
|
||||||
|
{
|
||||||
|
public SignUpMarketerCommandValidator()
|
||||||
|
{
|
||||||
|
RuleFor(command => command.FatherName)
|
||||||
|
.NotNull()
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("نام پدر را وارد کنید");
|
||||||
|
|
||||||
|
RuleFor(command => command.BirthDate)
|
||||||
|
.NotNull()
|
||||||
|
.NotEqual(0)
|
||||||
|
.WithMessage("تاریخ تولد را وارد کنید");
|
||||||
|
|
||||||
|
RuleFor(command => command.Shaba)
|
||||||
|
.NotNull()
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("شماره شبا را وارد کنید");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,4 @@
|
||||||
using Netina.Common.Extensions;
|
namespace Netina.Core.EntityServices;
|
||||||
using Netina.Common.Models.Api;
|
|
||||||
using Netina.Common.Models.Exception;
|
|
||||||
using Netina.Core.Abstracts;
|
|
||||||
using Netina.Core.EntityServices.Abstracts;
|
|
||||||
using Netina.Domain.Dtos.RequestDtos;
|
|
||||||
using Netina.Domain.Dtos.ResponseDtos;
|
|
||||||
using Netina.Domain.Dtos.SmallDtos;
|
|
||||||
using Netina.Domain.Entities.Users;
|
|
||||||
using Netina.Domain.Enums;
|
|
||||||
using Netina.Domain.Models.Claims;
|
|
||||||
using Netina.Repository.Abstracts;
|
|
||||||
using Netina.Repository.Repositories.Base.Contracts;
|
|
||||||
|
|
||||||
namespace Netina.Core.EntityServices;
|
|
||||||
|
|
||||||
|
|
||||||
public class UserService : IUserService
|
public class UserService : IUserService
|
||||||
|
@ -103,6 +89,12 @@ public class UserService : IUserService
|
||||||
if (user == null)
|
if (user == null)
|
||||||
throw new AppException("User not found", ApiResultStatusCode.NotFound);
|
throw new AppException("User not found", ApiResultStatusCode.NotFound);
|
||||||
var dto = user.AdaptToSDto();
|
var dto = user.AdaptToSDto();
|
||||||
|
dto.IsMarketer = await _repositoryWrapper.SetRepository<Marketer>()
|
||||||
|
.TableNoTracking
|
||||||
|
.AnyAsync(m => m.UserId == userId, cancellationToken);
|
||||||
|
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)
|
foreach (var roleName in roles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,6 @@ public sealed record UpdateDiscountCommand(
|
||||||
Guid ProductId,
|
Guid ProductId,
|
||||||
Guid CategoryId) : IRequest<bool>;
|
Guid CategoryId) : IRequest<bool>;
|
||||||
|
|
||||||
public sealed record CreateSaleCooperationDiscount(Guid CorporateUserId) : IRequest<string>;
|
|
||||||
|
|
||||||
public sealed record DeleteDiscountCommand(Guid Id) : IRequest<bool>;
|
public sealed record DeleteDiscountCommand(Guid Id) : IRequest<bool>;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace Netina.Domain.CommandQueries.Commands;
|
||||||
|
|
||||||
|
public sealed record SignUpMarketerCommand(string FatherName , long BirthDate, string Shaba , string NationalId) : IRequest<MarketerProfileResponseDto>;
|
||||||
|
|
||||||
|
public sealed record CreateMarketerDiscountCommand(Guid MarketerUserId) : IRequest<string>;
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace Netina.Domain.CommandQueries.Queries;
|
||||||
|
|
||||||
|
public sealed record GetMarketerProfileQuery(Guid? MarketerId = null) : IRequest<MarketerProfileResponseDto>;
|
||||||
|
|
||||||
|
public sealed record GetMarketersQuery(int Page , string? PhoneNumber = null , string? FullName = null) : IRequest<List<MarketerSDto>>;
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Netina.Domain.Dtos.ResponseDtos;
|
||||||
|
|
||||||
|
public class MarketerProfileResponseDto
|
||||||
|
{
|
||||||
|
public string DiscountCode { get; set; } = string.Empty;
|
||||||
|
public DateTime LastSettlementAt { get; set; }
|
||||||
|
public int OrderCount { get; set; }
|
||||||
|
public long Balance { get; set; }
|
||||||
|
}
|
|
@ -14,6 +14,9 @@ public class ApplicationUserSDto : BaseDto<ApplicationUserSDto, ApplicationUser>
|
||||||
public string FullName => FirstName + " " + LastName;
|
public string FullName => FirstName + " " + LastName;
|
||||||
public string RoleName { get; set; } = string.Empty;
|
public string RoleName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool IsMarketer { get; set; }
|
||||||
|
public bool IsManager { get; set; }
|
||||||
|
|
||||||
public List<Guid> RoleIds { get; set; } = new();
|
public List<Guid> RoleIds { get; set; } = new();
|
||||||
public long BirthDateTimeStamp => BirthDate.Year > 1970 ? DateTimeExtensions.DateTimeToUnixTimeStamp(BirthDate) : 0;
|
public long BirthDateTimeStamp => BirthDate.Year > 1970 ? DateTimeExtensions.DateTimeToUnixTimeStamp(BirthDate) : 0;
|
||||||
}
|
}
|
|
@ -54,6 +54,8 @@ namespace Netina.Domain.Mappers
|
||||||
SignUpStatus = p4.SignUpStatus,
|
SignUpStatus = p4.SignUpStatus,
|
||||||
NationalId = p4.NationalId,
|
NationalId = p4.NationalId,
|
||||||
Email = p4.Email,
|
Email = p4.Email,
|
||||||
|
IsMarketer = p4.Marketer != null,
|
||||||
|
IsManager = p4.Manager != null,
|
||||||
Id = p4.Id
|
Id = p4.Id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -73,6 +75,8 @@ namespace Netina.Domain.Mappers
|
||||||
result.SignUpStatus = p5.SignUpStatus;
|
result.SignUpStatus = p5.SignUpStatus;
|
||||||
result.NationalId = p5.NationalId;
|
result.NationalId = p5.NationalId;
|
||||||
result.Email = p5.Email;
|
result.Email = p5.Email;
|
||||||
|
result.IsMarketer = p5.Marketer != null;
|
||||||
|
result.IsManager = p5.Manager != null;
|
||||||
result.Id = p5.Id;
|
result.Id = p5.Id;
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
@ -87,6 +91,8 @@ namespace Netina.Domain.Mappers
|
||||||
SignUpStatus = p7.SignUpStatus,
|
SignUpStatus = p7.SignUpStatus,
|
||||||
NationalId = p7.NationalId,
|
NationalId = p7.NationalId,
|
||||||
Email = p7.Email,
|
Email = p7.Email,
|
||||||
|
IsMarketer = p7.Marketer != null,
|
||||||
|
IsManager = p7.Manager != null,
|
||||||
Id = p7.Id
|
Id = p7.Id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ public class MapsterRegister : IRegister
|
||||||
public void Register(TypeAdapterConfig config)
|
public void Register(TypeAdapterConfig config)
|
||||||
{
|
{
|
||||||
config.NewConfig<Blog, BlogSDto>()
|
config.NewConfig<Blog, BlogSDto>()
|
||||||
.Map("MainImage", o => o.Files.Count > 0 && o.Files.Any(f=>f.IsPrimary) ? o.Files.FirstOrDefault(f=>f.IsPrimary)!.FileName : string.Empty)
|
.Map("MainImage", o => o.Files.Count > 0 && o.Files.Any(f => f.IsPrimary) ? o.Files.FirstOrDefault(f => f.IsPrimary)!.FileName : string.Empty)
|
||||||
.TwoWays();
|
.TwoWays();
|
||||||
|
|
||||||
config.NewConfig<Blog, BlogLDto>()
|
config.NewConfig<Blog, BlogLDto>()
|
||||||
|
@ -36,7 +36,7 @@ public class MapsterRegister : IRegister
|
||||||
.TwoWays();
|
.TwoWays();
|
||||||
|
|
||||||
config.NewConfig<Product, ProductSDto>()
|
config.NewConfig<Product, ProductSDto>()
|
||||||
.Map("MainImage",o=>o.Files.FirstOrDefault(f=>f.IsPrimary) != null ? o.Files.FirstOrDefault(f => f.IsPrimary).FileLocation : o.Files.Count>0 ? o.Files.FirstOrDefault().FileLocation : string.Empty)
|
.Map("MainImage", o => o.Files.FirstOrDefault(f => f.IsPrimary) != null ? o.Files.FirstOrDefault(f => f.IsPrimary).FileLocation : o.Files.Count > 0 ? o.Files.FirstOrDefault().FileLocation : string.Empty)
|
||||||
.Map("CategoryName", o => o.Category == null ? null : o.Category.Name)
|
.Map("CategoryName", o => o.Category == null ? null : o.Category.Name)
|
||||||
.Map("BrandName", o => o.Brand == null ? null : o.Brand.PersianName)
|
.Map("BrandName", o => o.Brand == null ? null : o.Brand.PersianName)
|
||||||
.IgnoreNullValues(false)
|
.IgnoreNullValues(false)
|
||||||
|
@ -100,6 +100,10 @@ public class MapsterRegister : IRegister
|
||||||
|
|
||||||
private void ConfigUserMappers(TypeAdapterConfig config)
|
private void ConfigUserMappers(TypeAdapterConfig config)
|
||||||
{
|
{
|
||||||
|
config.NewConfig<ApplicationUser, ApplicationUserSDto>()
|
||||||
|
.Map("IsMarketer", o => o.Marketer != null)
|
||||||
|
.Map("IsManager", o => o.Manager != null)
|
||||||
|
.TwoWays();
|
||||||
|
|
||||||
config.NewConfig<Manager, ManagerSDto>()
|
config.NewConfig<Manager, ManagerSDto>()
|
||||||
.Map("PhoneNumber", o => o.User != null ? o.User.PhoneNumber : string.Empty)
|
.Map("PhoneNumber", o => o.User != null ? o.User.PhoneNumber : string.Empty)
|
||||||
|
|
|
@ -4,4 +4,5 @@ public class MarketerSetting
|
||||||
{
|
{
|
||||||
public int ProfitPercent { get; set; }
|
public int ProfitPercent { get; set; }
|
||||||
public string ContractTerms { get; set; } = string.Empty;
|
public string ContractTerms { get; set; } = string.Empty;
|
||||||
|
public int DiscountPercent { get; set; }
|
||||||
}
|
}
|
|
@ -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>
|
||||||
|
@ -14,9 +14,9 @@
|
||||||
<PackageReference Include="MediatR" Version="12.2.0" />
|
<PackageReference Include="MediatR" Version="12.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.4" />
|
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="8.0.4" />
|
||||||
<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>
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Netina.Common.Models.Api;
|
|
||||||
using Netina.Common.Models.Exception;
|
|
||||||
using Netina.Domain.CommandQueries.Queries;
|
|
||||||
using Netina.Domain.Dtos.SmallDtos;
|
|
||||||
using Netina.Domain.Entities.Users;
|
|
||||||
using Netina.Repository.Abstracts;
|
|
||||||
using Netina.Repository.Repositories.Base.Contracts;
|
|
||||||
|
|
||||||
namespace Netina.Repository.Handlers.Addresses;
|
namespace Netina.Repository.Handlers.Addresses;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Netina.Domain.CommandQueries.Commands;
|
|
||||||
using Netina.Domain.Enums;
|
|
||||||
|
|
||||||
namespace Netina.Repository.Handlers.Discounts.Validators;
|
namespace Netina.Repository.Handlers.Discounts.Validators;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Netina.Repository.Handlers.Marketers;
|
||||||
|
|
||||||
|
public class GetMarketersQueryHandler : IRequestHandler<GetMarketersQuery,List<MarketerSDto>>
|
||||||
|
{
|
||||||
|
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||||
|
|
||||||
|
public GetMarketersQueryHandler(IRepositoryWrapper repositoryWrapper)
|
||||||
|
{
|
||||||
|
_repositoryWrapper = repositoryWrapper;
|
||||||
|
}
|
||||||
|
public async Task<List<MarketerSDto>> Handle(GetMarketersQuery request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var query = _repositoryWrapper.SetRepository<Marketer>()
|
||||||
|
.TableNoTracking;
|
||||||
|
|
||||||
|
return await query.OrderByDescending(q => q.CreatedAt)
|
||||||
|
.Skip(request.Page * 20)
|
||||||
|
.Take(20)
|
||||||
|
.Select(MarketerMapper.ProjectToSDto)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue