feat : add payment , zarinpal gateway
add payment entity , add zarinpal gateway and ready for testrelease
parent
8d8ab5dc8f
commit
879b59f0bd
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||
// Use hover for the description of the existing attributes
|
||||
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md.
|
||||
"name": ".NET Core Launch (web)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/NetinaShop.Api/bin/Debug/net8.0/NetinaShop.Api.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/NetinaShop.Api",
|
||||
"stopAtEntry": false,
|
||||
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/NetinaShop.sln",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/NetinaShop.sln",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"--project",
|
||||
"${workspaceFolder}/NetinaShop.sln"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -51,8 +51,7 @@ public class OrderBagController : ICarterModule
|
|||
=> TypedResults.Ok(await mediator.Send(new SubmitDiscountCommand(orderId, discountCode), cancellationToken));
|
||||
|
||||
public async Task<IResult> AddShippingToOrderBagAsync(Guid orderId, [FromBody] SubmitOrderDeliveryCommand request, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(
|
||||
await mediator.Send(new SubmitOrderDeliveryCommand(request.Address, request.PostalCode,
|
||||
=> TypedResults.Ok( await mediator.Send(new SubmitOrderDeliveryCommand(request.Address, request.PostalCode,
|
||||
request.ReceiverPhoneNumber, request.ReceiverFullName, orderId, request.ShippingId), cancellationToken));
|
||||
|
||||
public async Task<IResult> SubmitOrderPaymentAsync(Guid orderId, [FromQuery] OrderPaymentMethod paymentMethod, IMediator mediator, CancellationToken cancellationToken)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace NetinaShop.Api.Controller;
|
||||
using NetinaShop.Domain.Enums;
|
||||
|
||||
namespace NetinaShop.Api.Controller;
|
||||
public class OrderController : ICarterModule
|
||||
{
|
||||
public void AddRoutes(IEndpointRouteBuilder app)
|
||||
|
@ -21,11 +23,14 @@ public class OrderController : ICarterModule
|
|||
|
||||
}
|
||||
|
||||
public async Task<IResult> GetAllAsync(IMediator mediator, [FromQuery] int page = 0, CancellationToken cancellationToken = default)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetOrdersQuery(page), cancellationToken));
|
||||
public async Task<IResult> GetAllAsync(IMediator mediator, [FromQuery]long? selectedDate, [FromQuery] OrderStatus? orderStatus, [FromQuery] OrderQueryDateFilter? dateFilter, [FromQuery] int page = 0, CancellationToken cancellationToken = default)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetOrdersQuery(Page:page, SelectedDate: selectedDate, OrderStatus:orderStatus, DateFilter:dateFilter), cancellationToken));
|
||||
|
||||
public async Task<IResult> GetAsync(IMediator mediator,Guid id, CancellationToken cancellationToken = default)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetOrderLDtoQuery(id), cancellationToken));
|
||||
public async Task<IResult> GetAsync(IMediator mediator, Guid id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var order = await mediator.Send(new GetOrderLDtoQuery(id), cancellationToken);
|
||||
return TypedResults.Ok(order);
|
||||
}
|
||||
|
||||
public async Task<IResult> DeleteAsync(IMediator mediator, Guid id, CancellationToken cancellationToken = default)
|
||||
=> TypedResults.Ok(await mediator.Send(new DeleteOrderCommand(id), cancellationToken));
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
using TypedResults = Microsoft.AspNetCore.Http.TypedResults;
|
||||
|
||||
namespace NetinaShop.Api.Controller;
|
||||
|
||||
public class PaymentController : ICarterModule
|
||||
{
|
||||
|
||||
public virtual void AddRoutes(IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.NewVersionedApi("AccountingPayment")
|
||||
.MapGroup($"api/accounting/pay");
|
||||
|
||||
group.MapGet("", GetAllAsync)
|
||||
.WithDisplayName("GetPayments")
|
||||
.RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
//group.MapGet("{id}", GetAsync)
|
||||
// .WithDisplayName("GetShipping")
|
||||
// .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser())
|
||||
// .HasApiVersion(1.0);
|
||||
|
||||
group.MapGet("verify", VerifyPaymentAsync)
|
||||
.HasApiVersion(1.0);
|
||||
}
|
||||
|
||||
// GET:Get All Entity
|
||||
public async Task<IResult> GetAllAsync([FromQuery] int page, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetPaymentsQuery(page), cancellationToken));
|
||||
|
||||
// GET:Get An Entity By Id
|
||||
public async Task<IResult> GetAsync(Guid id, IMediator mediator, CancellationToken cancellationToken)
|
||||
=> TypedResults.Ok(await mediator.Send(new GetShippingQuery(id), cancellationToken));
|
||||
|
||||
// POST:Create Entity
|
||||
public async Task<IResult> VerifyPaymentAsync([FromQuery] string Authority, [FromQuery] string Status, IPaymentService paymentService,ILogger<PaymentController> logger, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Status == "OK")
|
||||
{
|
||||
var result = await paymentService.VerifyPaymentAsync(authority: Authority, cancellationToken);
|
||||
return TypedResults.Redirect("");
|
||||
}
|
||||
else
|
||||
{
|
||||
return TypedResults.Redirect("");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e.Message);
|
||||
return TypedResults.Redirect("");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -13,7 +13,7 @@ public static class LoggerConfig
|
|||
o.MinimumEventLevel = LogEventLevel.Error;
|
||||
o.Dsn = "https://592b7fbb29464442a8e996247abe857f@watcher.igarson.app/7";
|
||||
})
|
||||
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", Serilog.Events.LogEventLevel.Error)
|
||||
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", Serilog.Events.LogEventLevel.Information)
|
||||
.CreateLogger();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
using System.Security.Cryptography;
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using NetinaShop.Repository.Migrations;
|
||||
using Refit;
|
||||
|
||||
namespace NetinaShop.Api.WebFramework.MiddleWares;
|
||||
|
||||
|
@ -73,7 +75,8 @@ public class ExceptionHandlerMiddleware
|
|||
{
|
||||
message = exception.Message;
|
||||
}
|
||||
if(exception.AdditionalData==null)
|
||||
|
||||
if (exception.AdditionalData == null)
|
||||
await WriteToResponseAsync();
|
||||
else
|
||||
await WriteToResponseWithObjectAsync(exception.AdditionalData);
|
||||
|
@ -90,7 +93,17 @@ public class ExceptionHandlerMiddleware
|
|||
SetUnAuthorizeResponse(exception);
|
||||
await WriteToResponseAsync();
|
||||
}
|
||||
catch (ApiException apiException)
|
||||
{
|
||||
_logger.LogError(apiException, apiException.Message);
|
||||
|
||||
httpStatusCode = HttpStatusCode.InternalServerError;
|
||||
apiStatusCode = ApiResultStatusCode.RefitError;
|
||||
|
||||
message = apiException.Message;
|
||||
|
||||
await WriteToResponseAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.LogError(exception, exception.Message);
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
namespace NetinaShop.Core.Abstracts;
|
||||
|
||||
public interface IPaymentService : IScopedDependency
|
||||
{
|
||||
Task<string> GetPaymentLinkAsync(double amount, string factorNumber, Guid orderId, Guid userId, string phoneNumber, string fullName, CancellationToken cancellationToken = default);
|
||||
Task<string> VerifyPaymentAsync(string authority, CancellationToken cancellationToken = default);
|
||||
}
|
|
@ -14,26 +14,45 @@ public class SubmitOrderPaymentCommandHandler : IRequestHandler<SubmitOrderPayme
|
|||
}
|
||||
public async Task<SubmitOrderPaymentResponseDto> Handle(SubmitOrderPaymentCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var order = await _repositoryWrapper.SetRepository<Order>()
|
||||
.TableNoTracking
|
||||
.FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
|
||||
await _mediator.Send(new CalculateOrderCommand(request.OrderId, true), cancellationToken);
|
||||
|
||||
if (order == null)
|
||||
var orderSDto = await _repositoryWrapper.SetRepository<Order>()
|
||||
.TableNoTracking
|
||||
.Where(o => o.Id == request.OrderId)
|
||||
.Select(OrderMapper.ProjectToSDto)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (orderSDto == null)
|
||||
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
|
||||
|
||||
var order = orderSDto.AdaptToOrder();
|
||||
|
||||
var response = new SubmitOrderPaymentResponseDto();
|
||||
|
||||
if (request.PaymentMethod == OrderPaymentMethod.OnlinePayment)
|
||||
{
|
||||
response.NeedToPayOnline = true;
|
||||
response.PaymentUrl = await _paymentService.GetPaymentLinkAsync(order.Id, order.TotalPrice, $"پرداخت سفارش {order.Id}");
|
||||
if (request.HasPaid)
|
||||
{
|
||||
response.NeedToPayOnline = false;
|
||||
order.SetSubmitOrder(request.PaymentMethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.NeedToPayOnline = true;
|
||||
response.PaymentUrl = await _paymentService.GetPaymentLinkAsync(orderSDto.TotalPrice, orderSDto.FactorCode, orderSDto.Id, orderSDto.UserId, orderSDto.UserPhoneNumber, orderSDto.UserFullName, cancellationToken);
|
||||
}
|
||||
}
|
||||
else if (request.PaymentMethod == OrderPaymentMethod.Cash)
|
||||
else if (request.PaymentMethod == OrderPaymentMethod.PayOnDoor)
|
||||
{
|
||||
response.NeedToPayOnline = false;
|
||||
order.SetSubmitOrder(request.PaymentMethod);
|
||||
_repositoryWrapper.SetRepository<Order>().Update(order);
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
|
||||
await _mediator.Send(new CreatePaymentCommand(order.FactorCode, order.TotalPrice,
|
||||
$"پرداخت نقدی سفارش {order.FactorCode}", string.Empty, string.Empty, string.Empty,
|
||||
PaymentType.PayOnDoor, PaymentStatus.Paid, order.Id
|
||||
, order.UserId), cancellationToken);
|
||||
}
|
||||
else if (request.PaymentMethod == OrderPaymentMethod.CardTransfer)
|
||||
{
|
||||
|
@ -41,6 +60,11 @@ public class SubmitOrderPaymentCommandHandler : IRequestHandler<SubmitOrderPayme
|
|||
order.SetSubmitOrder(request.PaymentMethod);
|
||||
_repositoryWrapper.SetRepository<Order>().Update(order);
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
|
||||
await _mediator.Send(new CreatePaymentCommand(order.FactorCode, order.TotalPrice,
|
||||
$"پرداخت نقدی سفارش {order.FactorCode}", string.Empty, string.Empty, string.Empty,
|
||||
PaymentType.CardTransfer, PaymentStatus.Paid, order.Id
|
||||
, order.UserId), cancellationToken);
|
||||
}
|
||||
|
||||
return response;
|
||||
|
|
|
@ -10,5 +10,5 @@ public sealed record RemoveFromOrderBagCommand(List<OrderBagRequestDto> RequestD
|
|||
public sealed record SubmitDiscountCommand(Guid OrderId,string DiscountCode) : IRequest<bool>;
|
||||
public sealed record SubmitOrderDeliveryCommand(string Address, string PostalCode, string ReceiverPhoneNumber, string ReceiverFullName, Guid OrderId, Guid ShippingId) : IRequest<bool>;
|
||||
|
||||
public sealed record SubmitOrderPaymentCommand(Guid OrderId, OrderPaymentMethod PaymentMethod) : IRequest<SubmitOrderPaymentResponseDto>;
|
||||
public sealed record SubmitOrderPaymentCommand(Guid OrderId, OrderPaymentMethod PaymentMethod , bool HasPaid = false) : IRequest<SubmitOrderPaymentResponseDto>;
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
namespace NetinaShop.Domain.CommandQueries.Commands;
|
||||
|
||||
public sealed record CreatePaymentCommand(string FactorNumber, double Amount, string Description, string TransactionCode, string CardPan, string Authority, PaymentType Type, PaymentStatus Status, Guid OrderId, Guid UserId) : IRequest<bool>;
|
||||
public sealed record UpdatePaymentCommand(Guid Id,string FactorNumber, double Amount, string Description, string TransactionCode, string CardPan, string Authority, PaymentType Type, PaymentStatus Status, Guid OrderId, Guid UserId) : IRequest<bool>;
|
|
@ -3,4 +3,4 @@
|
|||
public sealed record GetOrderLDtoQuery(Guid Id) : IRequest<OrderLDto>;
|
||||
|
||||
public sealed record GetOrderQuery(Guid Id) : IRequest<Order>;
|
||||
public sealed record GetOrdersQuery(int Page = 0) : IRequest<List<OrderSDto>>;
|
||||
public sealed record GetOrdersQuery(OrderQueryDateFilter? DateFilter, OrderStatus? OrderStatus,long? SelectedDate, int Page = 0) : IRequest<List<OrderSDto>>;
|
|
@ -0,0 +1,4 @@
|
|||
namespace NetinaShop.Domain.CommandQueries.Queries;
|
||||
|
||||
public sealed record GetPaymentQuery(Guid Id = default , string? Authority = null) : IRequest<PaymentSDto>;
|
||||
public sealed record GetPaymentsQuery(int Page = 0) : IRequest<List<PaymentSDto>>;
|
|
@ -1,6 +1,7 @@
|
|||
namespace NetinaShop.Domain.Dtos.LargDtos;
|
||||
public class OrderLDto : BaseDto<OrderLDto,Order>
|
||||
{
|
||||
public string FactorCode { get; set; } = string.Empty;
|
||||
public long TotalPrice { get; set; }
|
||||
public long DeliveryPrice { get; set; }
|
||||
public long TaxesPrice { get; set; }
|
||||
|
@ -14,9 +15,25 @@ public class OrderLDto : BaseDto<OrderLDto,Order>
|
|||
public DateTime OrderAt { get; set; }
|
||||
public int PreparingMinute { get; set; }
|
||||
public string DiscountCode { get; set; } = string.Empty;
|
||||
public long TotalPriceWithoutDiscount => TotalPrice + DiscountPrice;
|
||||
|
||||
public List<OrderProductSDto> OrderProducts { get; internal set; } = new();
|
||||
public string UserFullName { get; set; } = string.Empty;
|
||||
public string UserPhoneNumber { get; set; } = string.Empty;
|
||||
|
||||
public List<OrderDeliverySDto> OrderDeliveries { get; internal set; } = new();
|
||||
public List<OrderProductSDto> OrderProducts { get; set; } = new();
|
||||
|
||||
public List<OrderDeliverySDto> OrderDeliveries { get; set; } = new();
|
||||
|
||||
public List<PaymentSDto> Payments { get; set; } = new();
|
||||
|
||||
public OrderDeliverySDto OrderDelivery
|
||||
{
|
||||
get
|
||||
{
|
||||
if (OrderDeliveries.Count > 0)
|
||||
return OrderDeliveries.FirstOrDefault() ?? new OrderDeliverySDto();
|
||||
return new OrderDeliverySDto();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ public class OrderDeliverySDto : BaseDto<OrderDeliverySDto, OrderDelivery>
|
|||
public string PostalCode { get; set; } = string.Empty;
|
||||
public string ReceiverPhoneNumber { get; set; } = string.Empty;
|
||||
public string ReceiverFullName { get; set; } = string.Empty;
|
||||
public string ShippingMethod { get; set; } = string.Empty;
|
||||
public Guid OrderId { get; set; }
|
||||
public Guid ShippingId { get; internal set; }
|
||||
}
|
||||
|
|
|
@ -2,13 +2,17 @@
|
|||
|
||||
public class OrderProductSDto : BaseDto<OrderProductSDto, OrderProduct>
|
||||
{
|
||||
public int Count { get; internal set; }
|
||||
public float ProductFee { get; internal set; }
|
||||
public float ProductCost { get; internal set; }
|
||||
public OrderStatus OrderProductStatus { get; internal set; }
|
||||
public int Count { get; set; }
|
||||
public double ProductFee { get; set; }
|
||||
public double ProductFeeWithDiscount { get; set; }
|
||||
public bool HasDiscount { get; set; }
|
||||
public double ProductCost { get; set; }
|
||||
public double PackingFee { get; set; }
|
||||
public double PackingCost { get; set; }
|
||||
public OrderStatus OrderProductStatus { get; set; }
|
||||
|
||||
public Guid ProductId { get; internal set; }
|
||||
|
||||
public Guid OrderId { get; internal set; }
|
||||
public Guid ProductId { get; set; }
|
||||
public string ProductName { get; set; } = string.Empty;
|
||||
public Guid OrderId { get; set; }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
namespace NetinaShop.Domain.Dtos.SmallDtos;
|
||||
public class OrderSDto : BaseDto<OrderSDto, Order>
|
||||
{
|
||||
public long TotalPrice { get; set; }
|
||||
public long DeliveryPrice { get; set; }
|
||||
public long TaxesPrice { get; set; }
|
||||
public long ServicePrice { get; set; }
|
||||
public long PackingPrice { get; set; }
|
||||
public long TotalProductsPrice { get; set; }
|
||||
public long DiscountPrice { get; set; }
|
||||
public double TotalPrice { get; set; }
|
||||
public string FactorCode { get; set; } = string.Empty;
|
||||
public double DeliveryPrice { get; set; }
|
||||
public double TaxesPrice { get; set; }
|
||||
public double ServicePrice { get; set; }
|
||||
public double PackingPrice { get; set; }
|
||||
public double TotalProductsPrice { get; set; }
|
||||
public double DiscountPrice { get; set; }
|
||||
public bool IsPayed { get; set; }
|
||||
public OrderStatus OrderStatus { get; set; }
|
||||
public DateTime PayedAt { get; set; }
|
||||
public DateTime DoneAt { get; set; }
|
||||
public DateTime OrderAt { get; set; }
|
||||
public int PreparingMinute { get; set; }
|
||||
public string DiscountCode { get; set; } = string.Empty;
|
||||
public string UserFullName { get; set; } = string.Empty;
|
||||
public string UserPhoneNumber { get; set; } = string.Empty;
|
||||
public Guid UserId { get; internal set; }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
using NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
namespace NetinaShop.Domain.Dtos.SmallDtos;
|
||||
|
||||
public class PaymentSDto : BaseDto<PaymentSDto,Payment>
|
||||
{
|
||||
public string FactorNumber { get; set; } = string.Empty;
|
||||
public double Amount { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string TransactionCode { get; set; } = string.Empty;
|
||||
public string CardPan { get; set; } = string.Empty;
|
||||
public string Authority { get; set; } = string.Empty;
|
||||
public PaymentType Type { get; set; }
|
||||
public PaymentStatus Status { get; set; }
|
||||
|
||||
public Guid OrderId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public string UserFullName { get; set; } = string.Empty;
|
||||
public string UserPhoneNumber { get; set; } = string.Empty;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
namespace NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
public partial class Payment
|
||||
{
|
||||
public static Payment Create(string factorNumber, double amount, string description, string transactionCode, string cardPan, string authority, PaymentType type, PaymentStatus status, Guid orderId, Guid userId)
|
||||
{
|
||||
return new Payment(factorNumber, amount, description, transactionCode, cardPan, authority, type, status, orderId, userId);
|
||||
}
|
||||
|
||||
public void ChangeStatus(PaymentStatus status, string? cardPan = null)
|
||||
{
|
||||
this.Status = status;
|
||||
if (status != PaymentStatus.Paid && cardPan != null)
|
||||
CardPan = cardPan;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
namespace NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
[AdaptTwoWays("[name]LDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)]
|
||||
[AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget)]
|
||||
[AdaptTo("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)]
|
||||
[GenerateMapper]
|
||||
|
||||
public partial class Payment : ApiEntity
|
||||
{
|
||||
public Payment()
|
||||
{
|
||||
|
||||
}
|
||||
public Payment(string factorNumber, double amount, string description, string transactionCode, string cardPan, string authority, PaymentType type, PaymentStatus status, Guid orderId, Guid userId)
|
||||
{
|
||||
FactorNumber = factorNumber;
|
||||
Amount = amount;
|
||||
Description = description;
|
||||
TransactionCode = transactionCode;
|
||||
CardPan = cardPan;
|
||||
Authority = authority;
|
||||
Type = type;
|
||||
Status = status;
|
||||
OrderId = orderId;
|
||||
UserId = userId;
|
||||
}
|
||||
|
||||
public string FactorNumber { get; internal set; } = string.Empty;
|
||||
public double Amount { get; internal set; }
|
||||
public string Description { get; internal set; } = string.Empty;
|
||||
public string TransactionCode { get; internal set; } = string.Empty;
|
||||
public string CardPan { get; internal set; } = string.Empty;
|
||||
public string Authority { get; internal set; } = string.Empty;
|
||||
public PaymentType Type { get; internal set; }
|
||||
public PaymentStatus Status { get; internal set; }
|
||||
|
||||
public Guid OrderId { get; internal set; }
|
||||
public Order? Order { get; internal set; }
|
||||
public Guid UserId { get; internal set; }
|
||||
public ApplicationUser? User { get; internal set; }
|
||||
}
|
|
@ -4,7 +4,8 @@ public partial class Order
|
|||
{
|
||||
public static Order Create(Guid userId)
|
||||
{
|
||||
return new Order(0, 0, 0, 0, 0, 0, 0, false, OrderStatus.OrderBag, DateTime.MinValue, DateTime.MinValue, 0, string.Empty, userId, OrderPaymentMethod.OnlinePayment);
|
||||
var factorNumber = StringExtensions.GetId(10).ToUpper();
|
||||
return new Order(factorNumber, 0, 0, 0, 0, 0, 0, 0, false, OrderStatus.OrderBag, DateTime.MinValue, DateTime.Now, 0, string.Empty, userId, OrderPaymentMethod.OnlinePayment);
|
||||
|
||||
}
|
||||
|
||||
|
@ -62,7 +63,7 @@ public partial class Order
|
|||
OrderAt = DateTime.Now;
|
||||
PaymentMethod = paymentMethod;
|
||||
break;
|
||||
case OrderPaymentMethod.Cash:
|
||||
case OrderPaymentMethod.PayOnDoor:
|
||||
OrderStatus = OrderStatus.Submitted;
|
||||
IsPayed = false;
|
||||
OrderAt = DateTime.Now;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace NetinaShop.Domain.Entities.Orders;
|
||||
using NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
namespace NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
[AdaptTwoWays("[name]LDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)]
|
||||
[AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget)]
|
||||
|
@ -12,6 +14,7 @@ public partial class Order : ApiEntity
|
|||
|
||||
}
|
||||
public Order(
|
||||
string factorCode,
|
||||
double totalPrice,
|
||||
double deliveryPrice,
|
||||
double taxesPrice,
|
||||
|
@ -19,8 +22,16 @@ public partial class Order : ApiEntity
|
|||
double packingPrice,
|
||||
double totalProductsPrice,
|
||||
double discountPrice,
|
||||
bool isPayed, OrderStatus orderStatus, DateTime doneAt, DateTime orderAt, int preparingMinute, string discountCode, Guid userId, OrderPaymentMethod paymentMethod)
|
||||
bool isPayed,
|
||||
OrderStatus orderStatus,
|
||||
DateTime doneAt,
|
||||
DateTime orderAt,
|
||||
int preparingMinute,
|
||||
string discountCode,
|
||||
Guid userId,
|
||||
OrderPaymentMethod paymentMethod)
|
||||
{
|
||||
FactorCode = factorCode;
|
||||
TotalPrice = totalPrice;
|
||||
DeliveryPrice = deliveryPrice;
|
||||
TaxesPrice = taxesPrice;
|
||||
|
@ -38,6 +49,7 @@ public partial class Order : ApiEntity
|
|||
PaymentMethod = paymentMethod;
|
||||
}
|
||||
|
||||
public string FactorCode { get; internal set; } = string.Empty;
|
||||
public double TotalProductsPrice { get; internal set; }
|
||||
public double PackingPrice { get; internal set; }
|
||||
public double ServicePrice { get; internal set; }
|
||||
|
@ -60,4 +72,6 @@ public partial class Order : ApiEntity
|
|||
public List<OrderProduct> OrderProducts { get; internal set; } = new();
|
||||
|
||||
public List<OrderDelivery> OrderDeliveries { get; internal set; } = new();
|
||||
|
||||
public List<Payment> Payments { get; internal set; } = new();
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
namespace NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
[AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget)]
|
||||
[AdaptTo("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Projection)]
|
||||
[GenerateMapper]
|
||||
public partial class OrderProduct : ApiEntity
|
||||
{
|
||||
public OrderProduct()
|
||||
|
@ -32,8 +35,8 @@ public partial class OrderProduct : ApiEntity
|
|||
}
|
||||
public int Count { get; internal set; }
|
||||
public double ProductFee { get; internal set; }
|
||||
public double ProductFeeWithDiscount { get; set; }
|
||||
public bool HasDiscount { get; set; }
|
||||
public double ProductFeeWithDiscount { get; internal set; }
|
||||
public bool HasDiscount { get; internal set; }
|
||||
public double ProductCost { get; internal set; }
|
||||
public double PackingFee { get; internal set; }
|
||||
public double PackingCost { get; internal set; }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
public enum OrderPaymentMethod
|
||||
{
|
||||
[Display(Name = "پرداخت درب محل")]
|
||||
Cash,
|
||||
PayOnDoor,
|
||||
[Display(Name = "پرداخت انلاین")]
|
||||
OnlinePayment,
|
||||
[Display(Name = "پرداخت کارت به کارت")]
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
namespace NetinaShop.Domain.Enums;
|
||||
|
||||
public enum OrderQueryDateFilter
|
||||
{
|
||||
[Display(Name = "امروز")]
|
||||
Today = 0,
|
||||
[Display(Name = "هفته اخیر")]
|
||||
ThisWeek = 1,
|
||||
[Display(Name = "یک ماه اخیر")]
|
||||
ThisMonth = 2,
|
||||
[Display(Name = "تاریخ خاص")]
|
||||
CustomDate = 3,
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
namespace NetinaShop.Domain.Enums;
|
||||
|
||||
public enum PaymentStatus
|
||||
{
|
||||
[Display(Name = "در انتظار پرداخت درگاه")]
|
||||
InPaymentGateway = 0,
|
||||
[Display(Name = "در انتظار پرداخت")]
|
||||
NotPaidYet = 1,
|
||||
[Display(Name = "پرداخت شده")]
|
||||
Paid = 200,
|
||||
[Display(Name = "کنسل شده")]
|
||||
Cancel = 500
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
namespace NetinaShop.Domain.Enums;
|
||||
|
||||
public enum PaymentType
|
||||
{
|
||||
[Display(Name = "نقدی")]
|
||||
Cash,
|
||||
[Display(Name = "کارت به کارت")]
|
||||
CardTransfer,
|
||||
[Display(Name = "آنلاین")]
|
||||
Online,
|
||||
[Display(Name = "در محل")]
|
||||
PayOnDoor
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,140 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using Mapster.Models;
|
||||
using NetinaShop.Domain.Dtos.SmallDtos;
|
||||
using NetinaShop.Domain.Entities.Orders;
|
||||
using NetinaShop.Domain.Entities.Products;
|
||||
|
||||
namespace NetinaShop.Domain.Mappers
|
||||
{
|
||||
public static partial class OrderProductMapper
|
||||
{
|
||||
public static OrderProduct AdaptToOrderProduct(this OrderProductSDto p1)
|
||||
{
|
||||
return p1 == null ? null : new OrderProduct()
|
||||
{
|
||||
Count = p1.Count,
|
||||
ProductFee = p1.ProductFee,
|
||||
ProductFeeWithDiscount = p1.ProductFeeWithDiscount,
|
||||
HasDiscount = p1.HasDiscount,
|
||||
ProductCost = p1.ProductCost,
|
||||
PackingFee = p1.PackingFee,
|
||||
PackingCost = p1.PackingCost,
|
||||
OrderProductStatus = p1.OrderProductStatus,
|
||||
ProductId = p1.ProductId,
|
||||
Product = new Product()
|
||||
{
|
||||
Cost = p1.ProductCost,
|
||||
Id = p1.ProductId
|
||||
},
|
||||
OrderId = p1.OrderId,
|
||||
Order = new Order() {Id = p1.OrderId},
|
||||
Id = p1.Id,
|
||||
CreatedAt = p1.CreatedAt
|
||||
};
|
||||
}
|
||||
public static OrderProduct AdaptTo(this OrderProductSDto p2, OrderProduct p3)
|
||||
{
|
||||
if (p2 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
OrderProduct result = p3 ?? new OrderProduct();
|
||||
|
||||
result.Count = p2.Count;
|
||||
result.ProductFee = p2.ProductFee;
|
||||
result.ProductFeeWithDiscount = p2.ProductFeeWithDiscount;
|
||||
result.HasDiscount = p2.HasDiscount;
|
||||
result.ProductCost = p2.ProductCost;
|
||||
result.PackingFee = p2.PackingFee;
|
||||
result.PackingCost = p2.PackingCost;
|
||||
result.OrderProductStatus = p2.OrderProductStatus;
|
||||
result.ProductId = p2.ProductId;
|
||||
result.Product = funcMain1(new Never(), result.Product, p2);
|
||||
result.OrderId = p2.OrderId;
|
||||
result.Order = funcMain2(new Never(), result.Order, p2);
|
||||
result.Id = p2.Id;
|
||||
result.CreatedAt = p2.CreatedAt;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static OrderProductSDto AdaptToSDto(this OrderProduct p8)
|
||||
{
|
||||
return p8 == null ? null : new OrderProductSDto()
|
||||
{
|
||||
Count = p8.Count,
|
||||
ProductFee = p8.ProductFee,
|
||||
ProductFeeWithDiscount = p8.ProductFeeWithDiscount,
|
||||
HasDiscount = p8.HasDiscount,
|
||||
ProductCost = p8.ProductCost,
|
||||
PackingFee = p8.PackingFee,
|
||||
PackingCost = p8.PackingCost,
|
||||
OrderProductStatus = p8.OrderProductStatus,
|
||||
ProductId = p8.ProductId,
|
||||
ProductName = p8.Product != null ? p8.Product.PersianName : string.Empty,
|
||||
OrderId = p8.OrderId,
|
||||
Id = p8.Id,
|
||||
CreatedAt = p8.CreatedAt
|
||||
};
|
||||
}
|
||||
public static OrderProductSDto AdaptTo(this OrderProduct p9, OrderProductSDto p10)
|
||||
{
|
||||
if (p9 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
OrderProductSDto result = p10 ?? new OrderProductSDto();
|
||||
|
||||
result.Count = p9.Count;
|
||||
result.ProductFee = p9.ProductFee;
|
||||
result.ProductFeeWithDiscount = p9.ProductFeeWithDiscount;
|
||||
result.HasDiscount = p9.HasDiscount;
|
||||
result.ProductCost = p9.ProductCost;
|
||||
result.PackingFee = p9.PackingFee;
|
||||
result.PackingCost = p9.PackingCost;
|
||||
result.OrderProductStatus = p9.OrderProductStatus;
|
||||
result.ProductId = p9.ProductId;
|
||||
result.ProductName = p9.Product != null ? p9.Product.PersianName : string.Empty;
|
||||
result.OrderId = p9.OrderId;
|
||||
result.Id = p9.Id;
|
||||
result.CreatedAt = p9.CreatedAt;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static Expression<Func<OrderProduct, OrderProductSDto>> ProjectToSDto => p11 => new OrderProductSDto()
|
||||
{
|
||||
Count = p11.Count,
|
||||
ProductFee = p11.ProductFee,
|
||||
ProductFeeWithDiscount = p11.ProductFeeWithDiscount,
|
||||
HasDiscount = p11.HasDiscount,
|
||||
ProductCost = p11.ProductCost,
|
||||
PackingFee = p11.PackingFee,
|
||||
PackingCost = p11.PackingCost,
|
||||
OrderProductStatus = p11.OrderProductStatus,
|
||||
ProductId = p11.ProductId,
|
||||
ProductName = p11.Product != null ? p11.Product.PersianName : string.Empty,
|
||||
OrderId = p11.OrderId,
|
||||
Id = p11.Id,
|
||||
CreatedAt = p11.CreatedAt
|
||||
};
|
||||
|
||||
private static Product funcMain1(Never p4, Product p5, OrderProductSDto p2)
|
||||
{
|
||||
Product result = p5 ?? new Product();
|
||||
|
||||
result.Cost = p2.ProductCost;
|
||||
result.Id = p2.ProductId;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private static Order funcMain2(Never p6, Order p7, OrderProductSDto p2)
|
||||
{
|
||||
Order result = p7 ?? new Order();
|
||||
|
||||
result.Id = p2.OrderId;
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using Mapster.Models;
|
||||
using NetinaShop.Domain.Dtos.SmallDtos;
|
||||
using NetinaShop.Domain.Entities.Accounting;
|
||||
using NetinaShop.Domain.Entities.Orders;
|
||||
using NetinaShop.Domain.Entities.Users;
|
||||
|
||||
namespace NetinaShop.Domain.Mappers
|
||||
{
|
||||
public static partial class PaymentMapper
|
||||
{
|
||||
public static Payment AdaptToPayment(this PaymentSDto p1)
|
||||
{
|
||||
return p1 == null ? null : new Payment()
|
||||
{
|
||||
FactorNumber = p1.FactorNumber,
|
||||
Amount = p1.Amount,
|
||||
Description = p1.Description,
|
||||
TransactionCode = p1.TransactionCode,
|
||||
CardPan = p1.CardPan,
|
||||
Authority = p1.Authority,
|
||||
Type = p1.Type,
|
||||
Status = p1.Status,
|
||||
OrderId = p1.OrderId,
|
||||
Order = new Order() {Id = p1.OrderId},
|
||||
UserId = p1.UserId,
|
||||
User = new ApplicationUser()
|
||||
{
|
||||
Id = p1.UserId,
|
||||
PhoneNumber = p1.UserPhoneNumber
|
||||
},
|
||||
Id = p1.Id,
|
||||
CreatedAt = p1.CreatedAt
|
||||
};
|
||||
}
|
||||
public static Payment AdaptTo(this PaymentSDto p2, Payment p3)
|
||||
{
|
||||
if (p2 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Payment result = p3 ?? new Payment();
|
||||
|
||||
result.FactorNumber = p2.FactorNumber;
|
||||
result.Amount = p2.Amount;
|
||||
result.Description = p2.Description;
|
||||
result.TransactionCode = p2.TransactionCode;
|
||||
result.CardPan = p2.CardPan;
|
||||
result.Authority = p2.Authority;
|
||||
result.Type = p2.Type;
|
||||
result.Status = p2.Status;
|
||||
result.OrderId = p2.OrderId;
|
||||
result.Order = funcMain1(new Never(), result.Order, p2);
|
||||
result.UserId = p2.UserId;
|
||||
result.User = funcMain2(new Never(), result.User, p2);
|
||||
result.Id = p2.Id;
|
||||
result.CreatedAt = p2.CreatedAt;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static PaymentSDto AdaptToSDto(this Payment p8)
|
||||
{
|
||||
return p8 == null ? null : new PaymentSDto()
|
||||
{
|
||||
FactorNumber = p8.FactorNumber,
|
||||
Amount = p8.Amount,
|
||||
Description = p8.Description,
|
||||
TransactionCode = p8.TransactionCode,
|
||||
CardPan = p8.CardPan,
|
||||
Authority = p8.Authority,
|
||||
Type = p8.Type,
|
||||
Status = p8.Status,
|
||||
OrderId = p8.OrderId,
|
||||
UserId = p8.UserId,
|
||||
UserFullName = p8.User != null ? p8.User.FirstName + " " + p8.User.LastName : string.Empty,
|
||||
UserPhoneNumber = p8.User != null ? p8.User.PhoneNumber : string.Empty,
|
||||
Id = p8.Id,
|
||||
CreatedAt = p8.CreatedAt
|
||||
};
|
||||
}
|
||||
public static PaymentSDto AdaptTo(this Payment p9, PaymentSDto p10)
|
||||
{
|
||||
if (p9 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
PaymentSDto result = p10 ?? new PaymentSDto();
|
||||
|
||||
result.FactorNumber = p9.FactorNumber;
|
||||
result.Amount = p9.Amount;
|
||||
result.Description = p9.Description;
|
||||
result.TransactionCode = p9.TransactionCode;
|
||||
result.CardPan = p9.CardPan;
|
||||
result.Authority = p9.Authority;
|
||||
result.Type = p9.Type;
|
||||
result.Status = p9.Status;
|
||||
result.OrderId = p9.OrderId;
|
||||
result.UserId = p9.UserId;
|
||||
result.UserFullName = p9.User != null ? p9.User.FirstName + " " + p9.User.LastName : string.Empty;
|
||||
result.UserPhoneNumber = p9.User != null ? p9.User.PhoneNumber : string.Empty;
|
||||
result.Id = p9.Id;
|
||||
result.CreatedAt = p9.CreatedAt;
|
||||
return result;
|
||||
|
||||
}
|
||||
public static Expression<Func<Payment, PaymentSDto>> ProjectToSDto => p11 => new PaymentSDto()
|
||||
{
|
||||
FactorNumber = p11.FactorNumber,
|
||||
Amount = p11.Amount,
|
||||
Description = p11.Description,
|
||||
TransactionCode = p11.TransactionCode,
|
||||
CardPan = p11.CardPan,
|
||||
Authority = p11.Authority,
|
||||
Type = p11.Type,
|
||||
Status = p11.Status,
|
||||
OrderId = p11.OrderId,
|
||||
UserId = p11.UserId,
|
||||
UserFullName = p11.User != null ? p11.User.FirstName + " " + p11.User.LastName : string.Empty,
|
||||
UserPhoneNumber = p11.User != null ? p11.User.PhoneNumber : string.Empty,
|
||||
Id = p11.Id,
|
||||
CreatedAt = p11.CreatedAt
|
||||
};
|
||||
|
||||
private static Order funcMain1(Never p4, Order p5, PaymentSDto p2)
|
||||
{
|
||||
Order result = p5 ?? new Order();
|
||||
|
||||
result.Id = p2.OrderId;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private static ApplicationUser funcMain2(Never p6, ApplicationUser p7, PaymentSDto p2)
|
||||
{
|
||||
ApplicationUser result = p7 ?? new ApplicationUser();
|
||||
|
||||
result.Id = p2.UserId;
|
||||
result.PhoneNumber = p2.UserPhoneNumber;
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
namespace NetinaShop.Domain;
|
||||
using NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
namespace NetinaShop.Domain;
|
||||
|
||||
public class MapsterRegister : IRegister
|
||||
{
|
||||
|
@ -12,6 +14,10 @@ public class MapsterRegister : IRegister
|
|||
.Map("HeaderFileName", o => o.Files.Count > 0 && o.Files.Any(f => f.IsHeader) ? o.Files.FirstOrDefault(f => f.IsHeader)!.FileName : string.Empty)
|
||||
.TwoWays();
|
||||
|
||||
config.NewConfig<OrderDelivery, OrderDeliverySDto>()
|
||||
.Map("ShippingMethod", o => o.Shipping != null ? o.Shipping.Name : string.Empty)
|
||||
.TwoWays();
|
||||
|
||||
config.NewConfig<ProductCategory, ProductCategorySDto>()
|
||||
.Map("ParentName", o => o.Parent != null ? o.Parent.Name : string.Empty)
|
||||
.TwoWays();
|
||||
|
@ -23,6 +29,31 @@ public class MapsterRegister : IRegister
|
|||
.IgnoreNullValues(false)
|
||||
.TwoWays();
|
||||
|
||||
config.NewConfig<Order, OrderSDto>()
|
||||
.Map("UserFullName", o => o.User != null ? o.User.FirstName + " " + o.User.LastName : string.Empty)
|
||||
.Map("UserPhoneNumber", o => o.User != null ? o.User.PhoneNumber : string.Empty)
|
||||
.IgnoreNullValues(false)
|
||||
.TwoWays();
|
||||
|
||||
config.NewConfig<Order, OrderLDto>()
|
||||
.Map("UserFullName", o => o.User != null ? o.User.FirstName + " " + o.User.LastName : string.Empty)
|
||||
.Map("UserPhoneNumber", o => o.User != null ? o.User.PhoneNumber : string.Empty)
|
||||
.IgnoreNullValues(false)
|
||||
.TwoWays();
|
||||
|
||||
config.NewConfig<OrderProduct, OrderProductSDto>()
|
||||
.Map("ProductName", o => o.Product != null ? o.Product.PersianName : string.Empty)
|
||||
.IgnoreNullValues(false)
|
||||
.TwoWays();
|
||||
|
||||
config.NewConfig<Payment, PaymentSDto>()
|
||||
.Map("UserFullName", o => o.User != null ? o.User.FirstName + " " + o.User.LastName : string.Empty)
|
||||
.Map("UserPhoneNumber", o => o.User != null ? o.User.PhoneNumber : string.Empty)
|
||||
.IgnoreNullValues(false)
|
||||
.TwoWays();
|
||||
|
||||
|
||||
|
||||
config.NewConfig<Product, ProductLDto>()
|
||||
.Map("CategoryName", o => o.Category == null ? null : o.Category.Name)
|
||||
.Map("BrandName", o => o.Brand == null ? null : o.Brand.Name)
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
|
||||
public static class RestAddress
|
||||
{
|
||||
public static string BaseKaveNegar { get => "https://api.kavenegar.com/v1/"; }
|
||||
public static string BaseKaveNegar => "https://api.kavenegar.com/v1/";
|
||||
public static string BaseZarinpal => "https://api.zarinpal.com/pg";
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
namespace NetinaShop.Infrastructure.Models.RestApi.Zarinpal;
|
||||
|
||||
public class ZarinaplPaymentLinkRequest
|
||||
{
|
||||
public string merchant_id { get; set; } = string.Empty;
|
||||
public int amount { get; set; }
|
||||
public string callback_url { get; set; } = string.Empty;
|
||||
public string description { get; set; } = string.Empty;
|
||||
public ZarinaplPaymentLinkRequestMetadata metadata { get; set; } = new();
|
||||
|
||||
}
|
||||
|
||||
public class ZarinaplPaymentLinkRequestMetadata
|
||||
{
|
||||
public string mobile { get; set; } = string.Empty;
|
||||
public string email { get; set; } = string.Empty;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
namespace NetinaShop.Infrastructure.Models.RestApi.Zarinpal;
|
||||
|
||||
public class ZarinaplPaymentLinkResponse
|
||||
{
|
||||
public ZarinaplPaymentLinkResponseData data { get; set; }
|
||||
public List<object> errors { get; set; }
|
||||
}
|
||||
|
||||
public class ZarinaplPaymentLinkResponseData
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string message { get; set; } = string.Empty;
|
||||
public string authority { get; set; } = string.Empty;
|
||||
public string fee_type { get; set; } = string.Empty;
|
||||
public int fee { get; set; }
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace NetinaShop.Infrastructure.Models.RestApi.Zarinpal;
|
||||
|
||||
public class ZarinaplPaymentVerifyResponse
|
||||
{
|
||||
|
||||
public ZarinaplPaymentVerifyResponseData data { get; set; }
|
||||
public List<object> errors { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class ZarinaplPaymentVerifyResponseData
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string message { get; set; } = string.Empty;
|
||||
public string card_hash { get; set; } = string.Empty;
|
||||
public string card_pan { get; set; } = string.Empty;
|
||||
public int ref_id { get; set; }
|
||||
public string fee_type { get; set; } = string.Empty;
|
||||
public int fee { get; set; }
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace NetinaShop.Infrastructure.Models.RestApi.Zarinpal;
|
||||
|
||||
public class ZarinaplVerifyPaymentRequest
|
||||
{
|
||||
public string merchant_id { get; set; } = string.Empty;
|
||||
public int amount { get; set; }
|
||||
public string authority { get; set; } = string.Empty;
|
||||
}
|
|
@ -18,11 +18,6 @@
|
|||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Amazon.S3" />
|
||||
<Using Include="Amazon.S3.Model" />
|
||||
|
|
|
@ -5,9 +5,11 @@ namespace NetinaShop.Infrastructure.RestServices;
|
|||
public interface IRestApiWrapper : IScopedDependency
|
||||
{
|
||||
IKaveNegarRestApi KaveNegarRestApi { get; }
|
||||
IZarinpalRestApi ZarinpalRestApi { get; }
|
||||
}
|
||||
|
||||
public class RestApiWrapper : IRestApiWrapper
|
||||
{
|
||||
public IKaveNegarRestApi KaveNegarRestApi => RestService.For<IKaveNegarRestApi>(RestAddress.BaseKaveNegar);
|
||||
public IZarinpalRestApi ZarinpalRestApi => RestService.For<IZarinpalRestApi>(RestAddress.BaseZarinpal);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using NetinaShop.Infrastructure.Models.RestApi.Zarinpal;
|
||||
|
||||
namespace NetinaShop.Infrastructure.RestServices;
|
||||
|
||||
public interface IZarinpalRestApi
|
||||
{
|
||||
|
||||
[Post("/v4/payment/request.json")]
|
||||
Task<ZarinaplPaymentLinkResponse> GetPaymentLinkAsync([Body] ZarinaplPaymentLinkRequest request);
|
||||
[Post("/v4/payment/verify.json")]
|
||||
Task<ZarinaplPaymentVerifyResponse> VerifyPaymentAsync([Body] ZarinaplVerifyPaymentRequest request);
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
using Amazon.Runtime.Internal;
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NetinaShop.Domain.CommandQueries.Commands;
|
||||
using NetinaShop.Domain.CommandQueries.Queries;
|
||||
using NetinaShop.Domain.Entities.Accounting;
|
||||
using NetinaShop.Domain.Entities.Orders;
|
||||
using NetinaShop.Domain.Enums;
|
||||
using NetinaShop.Infrastructure.Models.RestApi.Zarinpal;
|
||||
using NetinaShop.Repository.Repositories.Base.Contracts;
|
||||
|
||||
namespace NetinaShop.Infrastructure.Services;
|
||||
|
||||
public class ZarinpalService : IPaymentService
|
||||
{
|
||||
private readonly IRestApiWrapper _restApiWrapper;
|
||||
private readonly IMediator _mediator;
|
||||
private readonly SiteSettings _siteSettings;
|
||||
public ZarinpalService(IRestApiWrapper restApiWrapper,IOptionsSnapshot<SiteSettings> snapshot,IMediator mediator)
|
||||
{
|
||||
_restApiWrapper = restApiWrapper;
|
||||
_mediator = mediator;
|
||||
_siteSettings = snapshot.Value;
|
||||
}
|
||||
public async Task<string> GetPaymentLinkAsync(double amount,string factorNumber, Guid orderId, Guid userId, string phoneNumber , string fullName , CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new ZarinaplPaymentLinkRequest
|
||||
{
|
||||
description = $"پرداخت {amount.ToString("N0")} ریال توسط {fullName} با شماره تماس {phoneNumber} برای سفارش با شماره {factorNumber}",
|
||||
amount = (int)amount,
|
||||
callback_url = Path.Combine("https://api.vesmook.com", "api", "accounting", "pay", "verify"),
|
||||
merchant_id = "4292b845-b510-4d1d-8ee2-097499b198e5",
|
||||
metadata = new ZarinaplPaymentLinkRequestMetadata { mobile = phoneNumber }
|
||||
};
|
||||
var response = await _restApiWrapper.ZarinpalRestApi.GetPaymentLinkAsync(request);
|
||||
if (response.data.code != 100)
|
||||
throw new AppException($"Exception in get link from zarinpal | {response.data.message}");
|
||||
|
||||
|
||||
var createPaymentResult = await _mediator.Send(new CreatePaymentCommand(factorNumber, amount,
|
||||
request.description, string.Empty, string.Empty,
|
||||
response.data.authority, PaymentType.Online,PaymentStatus.InPaymentGateway, orderId, userId), cancellationToken);
|
||||
|
||||
string link = $"https://www.zarinpal.com/pg/StartPay/{response.data.authority}";
|
||||
return link;
|
||||
}
|
||||
|
||||
public async Task<string> VerifyPaymentAsync(string authority, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var payment = await _mediator.Send(new GetPaymentQuery(Authority: authority), cancellationToken);
|
||||
var request = new ZarinaplVerifyPaymentRequest
|
||||
{
|
||||
amount = (int)payment.Amount,
|
||||
authority = payment.Authority,
|
||||
merchant_id = "4292b845-b510-4d1d-8ee2-097499b198e5"
|
||||
};
|
||||
var response = await _restApiWrapper.ZarinpalRestApi.VerifyPaymentAsync(request);
|
||||
if (response.data.code != 100)
|
||||
throw new AppException($"Exception in get link from zarinpal | {response.data.message}");
|
||||
|
||||
payment.Status = PaymentStatus.Paid;
|
||||
payment.CardPan = response.data.card_pan;
|
||||
payment.TransactionCode = response.data.ref_id.ToString();
|
||||
|
||||
await _mediator.Send(
|
||||
new UpdatePaymentCommand(payment.Id, payment.FactorNumber, payment.Amount, payment.Description,
|
||||
payment.TransactionCode, payment.CardPan, payment.Authority, payment.Type, payment.Status,
|
||||
payment.OrderId, payment.UserId), cancellationToken);
|
||||
|
||||
await _mediator.Send(new SubmitOrderPaymentCommand(payment.OrderId, OrderPaymentMethod.OnlinePayment, true),cancellationToken);
|
||||
|
||||
return payment.TransactionCode;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
namespace NetinaShop.Repository.Abstracts;
|
||||
|
||||
public interface IPaymentService : IScopedDependency
|
||||
{
|
||||
Task<string> GetPaymentLinkAsync(Guid orderId, double amount, string description);
|
||||
Task<bool> VerifiedPaymentAsync(string fishNumber, Guid orderId);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.Accounting;
|
||||
|
||||
public class CreatePaymentCommandHandler : IRequestHandler<CreatePaymentCommand,bool>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public CreatePaymentCommandHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<bool> Handle(CreatePaymentCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
var payment = Payment.Create(request.FactorNumber, request.Amount, request.Description, request.TransactionCode,
|
||||
request.CardPan, request.Authority, request.Type,request.Status, request.OrderId, request.UserId);
|
||||
|
||||
_repositoryWrapper.SetRepository<Payment>()
|
||||
.Add(payment);
|
||||
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.Accounting;
|
||||
|
||||
public class GetPaymentQueryHandler : IRequestHandler<GetPaymentQuery,PaymentSDto>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public GetPaymentQueryHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<PaymentSDto> Handle(GetPaymentQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
PaymentSDto? payment = null;
|
||||
if (request.Authority != null)
|
||||
{
|
||||
payment = await _repositoryWrapper.SetRepository<Payment>()
|
||||
.TableNoTracking
|
||||
.Where(p => p.Authority == request.Authority)
|
||||
.Select(PaymentMapper.ProjectToSDto)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (request.Id == default)
|
||||
throw new Exception("Id is null");
|
||||
|
||||
payment = await _repositoryWrapper.SetRepository<Payment>()
|
||||
.TableNoTracking
|
||||
.Where(p => p.Id == request.Id)
|
||||
.Select(PaymentMapper.ProjectToSDto)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
|
||||
if (payment == null)
|
||||
throw new AppException("Payment not found !", ApiResultStatusCode.NotFound);
|
||||
|
||||
return payment;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.Accounting;
|
||||
|
||||
public class GetPaymentsQueryHandler : IRequestHandler<GetPaymentsQuery,List<PaymentSDto>>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public GetPaymentsQueryHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<List<PaymentSDto>> Handle(GetPaymentsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return await _repositoryWrapper.SetRepository<Payment>()
|
||||
.TableNoTracking
|
||||
.Skip(20 * request.Page)
|
||||
.Take(20)
|
||||
.Select(PaymentMapper.ProjectToSDto)
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using NetinaShop.Domain.Entities.Accounting;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.Accounting;
|
||||
|
||||
public class UpdatePaymentCommandHandler : IRequestHandler<UpdatePaymentCommand,bool>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public UpdatePaymentCommandHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<bool> Handle(UpdatePaymentCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var ent = await _repositoryWrapper.SetRepository<Payment>()
|
||||
.TableNoTracking
|
||||
.FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken);
|
||||
if (ent == null)
|
||||
throw new AppException("Payment not found", ApiResultStatusCode.NotFound);
|
||||
|
||||
var newEnt = Payment.Create(request.FactorNumber, request.Amount, request.Description, request.TransactionCode,
|
||||
request.CardPan, request.Authority, request.Type, request.Status, request.OrderId, request.UserId);
|
||||
newEnt.Id = ent.Id;
|
||||
|
||||
_repositoryWrapper.SetRepository<Payment>()
|
||||
.Update(newEnt);
|
||||
|
||||
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using NetinaShop.Domain.Entities.Orders;
|
||||
|
||||
namespace NetinaShop.Repository.Handlers.Orders;
|
||||
|
||||
public class GetOrderLDtoQueryHandler: IRequestHandler<GetOrderLDtoQuery,OrderLDto>
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public GetOrderLDtoQueryHandler(IRepositoryWrapper repositoryWrapper)
|
||||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public async Task<OrderLDto> Handle(GetOrderLDtoQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (request.Id == default)
|
||||
throw new AppException("Order id is null");
|
||||
var order = await _repositoryWrapper.SetRepository<Order>()
|
||||
.TableNoTracking
|
||||
.Where(o => o.Id == request.Id)
|
||||
.Select(OrderMapper.ProjectToLDto)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
if (order == null)
|
||||
throw new AppException("Order not found", ApiResultStatusCode.NotFound);
|
||||
return order;
|
||||
}
|
||||
}
|
|
@ -10,10 +10,42 @@ public class GetOrdersQueryHandler : IRequestHandler<GetOrdersQuery,List<OrderSD
|
|||
{
|
||||
_repositoryWrapper = repositoryWrapper;
|
||||
}
|
||||
public Task<List<OrderSDto>> Handle(GetOrdersQuery request, CancellationToken cancellationToken)
|
||||
public async Task<List<OrderSDto>> Handle(GetOrdersQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
return _repositoryWrapper.SetRepository<Order>()
|
||||
.TableNoTracking
|
||||
|
||||
IQueryable<Order> orders = _repositoryWrapper.SetRepository<Order>()
|
||||
.TableNoTracking;
|
||||
|
||||
if (request.DateFilter != null)
|
||||
{
|
||||
switch (request.DateFilter)
|
||||
{
|
||||
case OrderQueryDateFilter.CustomDate:
|
||||
if (request.SelectedDate != null)
|
||||
orders = orders.Where(o => o.CreatedAt.Date == DateTimeExtensions.UnixTimeStampToDateTime(request.SelectedDate.Value));
|
||||
else
|
||||
throw new AppException("For custom date you have to send SelectedDate",ApiResultStatusCode.BadRequest);
|
||||
break;
|
||||
case OrderQueryDateFilter.ThisMonth:
|
||||
orders = orders.Where(o => o.CreatedAt.Date >= new DateTime(DateTime.Today.Year,DateTime.Today.Month,1));
|
||||
break;
|
||||
case OrderQueryDateFilter.ThisWeek:
|
||||
orders = orders.Where(o => o.CreatedAt.Date >= DateTime.Today.AddDays(-7));
|
||||
break;
|
||||
case OrderQueryDateFilter.Today:
|
||||
orders = orders.Where(o => o.CreatedAt.Date == DateTime.Today.Date);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (request.OrderStatus != null)
|
||||
orders = orders.Where(o => o.OrderStatus == request.OrderStatus.Value);
|
||||
|
||||
return await orders
|
||||
.OrderByDescending(o=>o.CreatedAt)
|
||||
.Skip(request.Page * 15)
|
||||
.Take(15)
|
||||
.Select(OrderMapper.ProjectToSDto)
|
||||
|
|
1573
NetinaShop.Repository/Migrations/20240210134749_EditOrderAddFactorCode.Designer.cs
generated
100644
1573
NetinaShop.Repository/Migrations/20240210134749_EditOrderAddFactorCode.Designer.cs
generated
100644
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NetinaShop.Repository.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EditOrderAddFactorCode : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "FactorCode",
|
||||
schema: "public",
|
||||
table: "Orders",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FactorCode",
|
||||
schema: "public",
|
||||
table: "Orders");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace NetinaShop.Repository.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddPayment : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Payments",
|
||||
schema: "public",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
FactorNumber = table.Column<string>(type: "text", nullable: false),
|
||||
Amount = table.Column<double>(type: "double precision", nullable: false),
|
||||
Description = table.Column<string>(type: "text", nullable: false),
|
||||
TransactionCode = table.Column<string>(type: "text", nullable: false),
|
||||
CardPan = table.Column<string>(type: "text", nullable: false),
|
||||
Authority = table.Column<string>(type: "text", nullable: false),
|
||||
Type = table.Column<int>(type: "integer", nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false),
|
||||
OrderId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RemovedAt = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
|
||||
CreatedBy = table.Column<string>(type: "text", nullable: true),
|
||||
IsRemoved = table.Column<bool>(type: "boolean", nullable: false),
|
||||
RemovedBy = table.Column<string>(type: "text", nullable: true),
|
||||
ModifiedAt = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
|
||||
ModifiedBy = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Payments", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Payments_Orders_OrderId",
|
||||
column: x => x.OrderId,
|
||||
principalSchema: "public",
|
||||
principalTable: "Orders",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Payments_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalSchema: "public",
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Payments_OrderId",
|
||||
schema: "public",
|
||||
table: "Payments",
|
||||
column: "OrderId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Payments_UserId",
|
||||
schema: "public",
|
||||
table: "Payments",
|
||||
column: "UserId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Payments",
|
||||
schema: "public");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -126,6 +126,77 @@ namespace NetinaShop.Repository.Migrations
|
|||
b.ToTable("Tokens", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NetinaShop.Domain.Entities.Accounting.Payment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<double>("Amount")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<string>("Authority")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CardPan")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FactorNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsRemoved")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime>("ModifiedAt")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("ModifiedBy")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("OrderId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("RemovedAt")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("RemovedBy")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("TransactionCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OrderId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Payments", "public");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NetinaShop.Domain.Entities.Blogs.Blog", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
|
@ -393,6 +464,10 @@ namespace NetinaShop.Repository.Migrations
|
|||
b.Property<DateTime>("DoneAt")
|
||||
.HasColumnType("timestamp without time zone");
|
||||
|
||||
b.Property<string>("FactorCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsPayed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
|
@ -1300,6 +1375,23 @@ namespace NetinaShop.Repository.Migrations
|
|||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NetinaShop.Domain.Entities.Accounting.Payment", b =>
|
||||
{
|
||||
b.HasOne("NetinaShop.Domain.Entities.Orders.Order", "Order")
|
||||
.WithMany("Payments")
|
||||
.HasForeignKey("OrderId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.HasOne("NetinaShop.Domain.Entities.Users.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.Navigation("Order");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NetinaShop.Domain.Entities.Blogs.Blog", b =>
|
||||
{
|
||||
b.HasOne("NetinaShop.Domain.Entities.Blogs.BlogCategory", "Category")
|
||||
|
@ -1531,6 +1623,8 @@ namespace NetinaShop.Repository.Migrations
|
|||
b.Navigation("OrderDeliveries");
|
||||
|
||||
b.Navigation("OrderProducts");
|
||||
|
||||
b.Navigation("Payments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NetinaShop.Domain.Entities.ProductCategories.ProductCategory", b =>
|
||||
|
|
Loading…
Reference in New Issue