feat: Implement manual payment system with gRPC service and related commands/queries
This commit is contained in:
@@ -15,6 +15,7 @@ public class GetAllUserOrderByFilterQueryHandler : IRequestHandler<GetAllUserOrd
|
|||||||
.Include(i => i.User)
|
.Include(i => i.User)
|
||||||
.Include(i => i.FactorDetails)
|
.Include(i => i.FactorDetails)
|
||||||
.ThenInclude(t => t.Product)
|
.ThenInclude(t => t.Product)
|
||||||
|
.Include(i => i.OrderVAT)
|
||||||
.ApplyOrder(sortBy: request.SortBy)
|
.ApplyOrder(sortBy: request.SortBy)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
@@ -61,7 +62,9 @@ public class GetAllUserOrderByFilterQueryHandler : IRequestHandler<GetAllUserOrd
|
|||||||
TrackingCode = x.TrackingCode,
|
TrackingCode = x.TrackingCode,
|
||||||
DeliveryDescription = x.DeliveryDescription,
|
DeliveryDescription = x.DeliveryDescription,
|
||||||
UserFullName = (x.User.FirstName ?? string.Empty) + " " + (x.User.LastName ?? string.Empty),
|
UserFullName = (x.User.FirstName ?? string.Empty) + " " + (x.User.LastName ?? string.Empty),
|
||||||
UserNationalCode = x.User.NationalCode
|
UserNationalCode = x.User.NationalCode,
|
||||||
|
VatAmount = x.OrderVAT != null ? x.OrderVAT.VATAmount : 0,
|
||||||
|
VatPercentage = x.OrderVAT != null ? (double)(x.OrderVAT.VATRate * 100) : 0
|
||||||
})
|
})
|
||||||
.ToListAsync(cancellationToken);
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ public class GetAllUserOrderByFilterResponseDto
|
|||||||
public string? UserFullName { get; set; }
|
public string? UserFullName { get; set; }
|
||||||
// کدملی کاربر
|
// کدملی کاربر
|
||||||
public string? UserNationalCode { get; set; }
|
public string? UserNationalCode { get; set; }
|
||||||
|
// مبلغ مالیات بر ارزش افزوده (ریال)
|
||||||
|
public long VatAmount { get; set; }
|
||||||
|
// درصد مالیات بر ارزش افزوده (مثلاً 9 برای 9٪)
|
||||||
|
public double VatPercentage { get; set; }
|
||||||
}
|
}
|
||||||
public class GetAllUserOrderByFilterResponseModelFactorDetail
|
public class GetAllUserOrderByFilterResponseModelFactorDetail
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public class GetUserOrderQueryHandler : IRequestHandler<GetUserOrderQuery, GetUs
|
|||||||
.Include(i => i.User)
|
.Include(i => i.User)
|
||||||
.Include(i => i.FactorDetails)
|
.Include(i => i.FactorDetails)
|
||||||
.ThenInclude(t => t.Product)
|
.ThenInclude(t => t.Product)
|
||||||
|
.Include(i => i.OrderVAT)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(x => x.Id == request.Id)
|
.Where(x => x.Id == request.Id)
|
||||||
.Select(x => new GetUserOrderResponseDto
|
.Select(x => new GetUserOrderResponseDto
|
||||||
@@ -43,7 +44,15 @@ public class GetUserOrderQueryHandler : IRequestHandler<GetUserOrderQuery, GetUs
|
|||||||
TrackingCode = x.TrackingCode,
|
TrackingCode = x.TrackingCode,
|
||||||
DeliveryDescription = x.DeliveryDescription,
|
DeliveryDescription = x.DeliveryDescription,
|
||||||
UserFullName = (x.User.FirstName ?? string.Empty) + " " + (x.User.LastName ?? string.Empty),
|
UserFullName = (x.User.FirstName ?? string.Empty) + " " + (x.User.LastName ?? string.Empty),
|
||||||
UserNationalCode = x.User.NationalCode
|
UserNationalCode = x.User.NationalCode,
|
||||||
|
VatInfo = x.OrderVAT != null ? new OrderVATInfoDto
|
||||||
|
{
|
||||||
|
VatRate = x.OrderVAT.VATRate,
|
||||||
|
BaseAmount = x.OrderVAT.BaseAmount,
|
||||||
|
VatAmount = x.OrderVAT.VATAmount,
|
||||||
|
TotalAmount = x.OrderVAT.TotalAmount,
|
||||||
|
IsPaid = x.OrderVAT.IsPaid
|
||||||
|
} : null
|
||||||
})
|
})
|
||||||
.FirstOrDefaultAsync(cancellationToken);
|
.FirstOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,38 @@ public class GetUserOrderResponseDto
|
|||||||
public string? UserFullName { get; set; }
|
public string? UserFullName { get; set; }
|
||||||
// کدملی کاربر
|
// کدملی کاربر
|
||||||
public string? UserNationalCode { get; set; }
|
public string? UserNationalCode { get; set; }
|
||||||
|
// اطلاعات مالیات بر ارزش افزوده
|
||||||
|
public OrderVATInfoDto? VatInfo { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
}public class GetUserOrderResponseFactorDetail
|
/// <summary>
|
||||||
|
/// اطلاعات مالیات بر ارزش افزوده
|
||||||
|
/// </summary>
|
||||||
|
public class OrderVATInfoDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// نرخ مالیات (مثلاً 0.09 = 9%)
|
||||||
|
/// </summary>
|
||||||
|
public decimal VatRate { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// مبلغ پایه (قبل از مالیات)
|
||||||
|
/// </summary>
|
||||||
|
public long BaseAmount { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// مبلغ مالیات
|
||||||
|
/// </summary>
|
||||||
|
public long VatAmount { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// مبلغ کل (پایه + مالیات)
|
||||||
|
/// </summary>
|
||||||
|
public long TotalAmount { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// آیا پرداخت شده
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPaid { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetUserOrderResponseFactorDetail
|
||||||
{
|
{
|
||||||
//شناسه
|
//شناسه
|
||||||
public long ProductId { get; set; }
|
public long ProductId { get; set; }
|
||||||
|
|||||||
@@ -48,6 +48,8 @@
|
|||||||
<Protobuf Include="Protos\clubmembership.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
<Protobuf Include="Protos\clubmembership.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
||||||
<Protobuf Include="Protos\networkmembership.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
<Protobuf Include="Protos\networkmembership.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
||||||
<Protobuf Include="Protos\commission.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
<Protobuf Include="Protos\commission.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
||||||
|
<!-- Manual Payment System -->
|
||||||
|
<Protobuf Include="Protos\manualpayment.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
||||||
<!-- Club Discount Shop System - Phase 9 -->
|
<!-- Club Discount Shop System - Phase 9 -->
|
||||||
<Protobuf Include="Protos\discountproduct.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
<Protobuf Include="Protos\discountproduct.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
||||||
<Protobuf Include="Protos\discountcategory.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
<Protobuf Include="Protos\discountcategory.proto" ProtoRoot="Protos\" GrpcServices="Both" />
|
||||||
|
|||||||
130
src/CMSMicroservice.Protobuf/Protos/manualpayment.proto
Normal file
130
src/CMSMicroservice.Protobuf/Protos/manualpayment.proto
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package manualpayment;
|
||||||
|
|
||||||
|
import "public_messages.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/wrappers.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "google/api/annotations.proto";
|
||||||
|
|
||||||
|
option csharp_namespace = "CMSMicroservice.Protobuf.Protos.ManualPayment";
|
||||||
|
|
||||||
|
service ManualPaymentContract
|
||||||
|
{
|
||||||
|
rpc CreateManualPayment(CreateManualPaymentRequest) returns (CreateManualPaymentResponse){
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/CreateManualPayment"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
rpc ApproveManualPayment(ApproveManualPaymentRequest) returns (google.protobuf.Empty){
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/ApproveManualPayment"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
rpc RejectManualPayment(RejectManualPaymentRequest) returns (google.protobuf.Empty){
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/RejectManualPayment"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
rpc GetAllManualPayments(GetAllManualPaymentsRequest) returns (GetAllManualPaymentsResponse){
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/GetAllManualPayments"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enums mirroring CMSMicroservice.Domain.Enums.ManualPaymentType
|
||||||
|
enum ManualPaymentType
|
||||||
|
{
|
||||||
|
ManualPaymentType_Unknown = 0;
|
||||||
|
ManualPaymentType_CashDeposit = 1;
|
||||||
|
ManualPaymentType_DiscountWalletCharge = 2;
|
||||||
|
ManualPaymentType_NetworkWalletCharge = 3;
|
||||||
|
ManualPaymentType_Settlement = 4;
|
||||||
|
ManualPaymentType_ErrorCorrection = 5;
|
||||||
|
ManualPaymentType_Refund = 6;
|
||||||
|
ManualPaymentType_Other = 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enums mirroring CMSMicroservice.Domain.Enums.ManualPaymentStatus
|
||||||
|
enum ManualPaymentStatus
|
||||||
|
{
|
||||||
|
ManualPaymentStatus_Pending = 0;
|
||||||
|
ManualPaymentStatus_Approved = 1;
|
||||||
|
ManualPaymentStatus_Rejected = 2;
|
||||||
|
ManualPaymentStatus_Cancelled = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateManualPaymentRequest
|
||||||
|
{
|
||||||
|
int64 user_id = 1;
|
||||||
|
int64 amount = 2;
|
||||||
|
ManualPaymentType type = 3;
|
||||||
|
string description = 4;
|
||||||
|
google.protobuf.StringValue reference_number = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateManualPaymentResponse
|
||||||
|
{
|
||||||
|
int64 id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ApproveManualPaymentRequest
|
||||||
|
{
|
||||||
|
int64 manual_payment_id = 1;
|
||||||
|
google.protobuf.StringValue approval_note = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RejectManualPaymentRequest
|
||||||
|
{
|
||||||
|
int64 manual_payment_id = 1;
|
||||||
|
string rejection_reason = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetAllManualPaymentsRequest
|
||||||
|
{
|
||||||
|
int32 page_number = 1;
|
||||||
|
int32 page_size = 2;
|
||||||
|
google.protobuf.Int64Value user_id = 3;
|
||||||
|
google.protobuf.Int32Value status = 4;
|
||||||
|
google.protobuf.Int32Value type = 5;
|
||||||
|
google.protobuf.Int64Value requested_by = 6;
|
||||||
|
google.protobuf.BoolValue order_by_descending = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetAllManualPaymentsResponse
|
||||||
|
{
|
||||||
|
messages.MetaData meta_data = 1;
|
||||||
|
repeated ManualPaymentModel models = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ManualPaymentModel
|
||||||
|
{
|
||||||
|
int64 id = 1;
|
||||||
|
int64 user_id = 2;
|
||||||
|
string user_full_name = 3;
|
||||||
|
string user_mobile = 4;
|
||||||
|
int64 amount = 5;
|
||||||
|
ManualPaymentType type = 6;
|
||||||
|
string type_display = 7;
|
||||||
|
string description = 8;
|
||||||
|
google.protobuf.StringValue reference_number = 9;
|
||||||
|
ManualPaymentStatus status = 10;
|
||||||
|
string status_display = 11;
|
||||||
|
int64 requested_by = 12;
|
||||||
|
string requested_by_name = 13;
|
||||||
|
google.protobuf.Int64Value approved_by = 14;
|
||||||
|
google.protobuf.StringValue approved_by_name = 15;
|
||||||
|
google.protobuf.Timestamp approved_at = 16;
|
||||||
|
google.protobuf.StringValue rejection_reason = 17;
|
||||||
|
google.protobuf.Int64Value transaction_id = 18;
|
||||||
|
google.protobuf.Timestamp created = 19;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -163,7 +163,20 @@ message GetUserOrderResponse
|
|||||||
// نام کامل و کدملی کاربر
|
// نام کامل و کدملی کاربر
|
||||||
google.protobuf.StringValue user_full_name = 15;
|
google.protobuf.StringValue user_full_name = 15;
|
||||||
google.protobuf.StringValue user_national_code = 16;
|
google.protobuf.StringValue user_national_code = 16;
|
||||||
|
// اطلاعات مالیات بر ارزش افزوده
|
||||||
|
OrderVATInfo vat_info = 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// اطلاعات مالیات بر ارزش افزوده
|
||||||
|
message OrderVATInfo
|
||||||
|
{
|
||||||
|
double vat_rate = 1; // نرخ مالیات (مثلاً 0.09)
|
||||||
|
int64 base_amount = 2; // مبلغ پایه (قبل از مالیات)
|
||||||
|
int64 vat_amount = 3; // مبلغ مالیات
|
||||||
|
int64 total_amount = 4; // مبلغ کل (پایه + مالیات)
|
||||||
|
bool is_paid = 5; // آیا پرداخت شده
|
||||||
|
}
|
||||||
|
|
||||||
message GetUserOrderResponseFactorDetail
|
message GetUserOrderResponseFactorDetail
|
||||||
{
|
{
|
||||||
int64 product_id = 1;
|
int64 product_id = 1;
|
||||||
@@ -236,6 +249,9 @@ message GetAllUserOrderByFilterResponseModel
|
|||||||
// نام کامل و کدملی کاربر
|
// نام کامل و کدملی کاربر
|
||||||
google.protobuf.StringValue user_full_name = 15;
|
google.protobuf.StringValue user_full_name = 15;
|
||||||
google.protobuf.StringValue user_national_code = 16;
|
google.protobuf.StringValue user_national_code = 16;
|
||||||
|
// مبلغ و درصد مالیات بر ارزش افزوده
|
||||||
|
int64 vat_amount = 17;
|
||||||
|
double vat_percentage = 18;
|
||||||
}
|
}
|
||||||
message GetAllUserOrderByFilterResponseModelFactorDetail
|
message GetAllUserOrderByFilterResponseModelFactorDetail
|
||||||
{
|
{
|
||||||
@@ -352,4 +368,3 @@ message ProductPVDto
|
|||||||
int64 unit_pv = 4;
|
int64 unit_pv = 4;
|
||||||
int64 total_pv = 5;
|
int64 total_pv = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
59
src/CMSMicroservice.WebApi/Services/ManualPaymentService.cs
Normal file
59
src/CMSMicroservice.WebApi/Services/ManualPaymentService.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using CMSMicroservice.Protobuf.Protos.ManualPayment;
|
||||||
|
using CMSMicroservice.WebApi.Common.Services;
|
||||||
|
using CMSMicroservice.Application.ManualPaymentCQ.Commands.CreateManualPayment;
|
||||||
|
using CMSMicroservice.Application.ManualPaymentCQ.Commands.ApproveManualPayment;
|
||||||
|
using CMSMicroservice.Application.ManualPaymentCQ.Commands.RejectManualPayment;
|
||||||
|
using CMSMicroservice.Application.ManualPaymentCQ.Queries.GetAllManualPayments;
|
||||||
|
using Grpc.Core;
|
||||||
|
using Mapster;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace CMSMicroservice.WebApi.Services;
|
||||||
|
|
||||||
|
public class ManualPaymentService : ManualPaymentContract.ManualPaymentContractBase
|
||||||
|
{
|
||||||
|
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
|
||||||
|
private readonly ISender _sender;
|
||||||
|
|
||||||
|
public ManualPaymentService(
|
||||||
|
IDispatchRequestToCQRS dispatchRequestToCQRS,
|
||||||
|
ISender sender)
|
||||||
|
{
|
||||||
|
_dispatchRequestToCQRS = dispatchRequestToCQRS;
|
||||||
|
_sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<CreateManualPaymentResponse> CreateManualPayment(
|
||||||
|
CreateManualPaymentRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
var command = request.Adapt<CreateManualPaymentCommand>();
|
||||||
|
var id = await _sender.Send(command, context.CancellationToken);
|
||||||
|
|
||||||
|
return new CreateManualPaymentResponse
|
||||||
|
{
|
||||||
|
Id = id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<Google.Protobuf.WellKnownTypes.Empty> ApproveManualPayment(
|
||||||
|
ApproveManualPaymentRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
return await _dispatchRequestToCQRS.Handle<ApproveManualPaymentRequest, ApproveManualPaymentCommand>(request, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<Google.Protobuf.WellKnownTypes.Empty> RejectManualPayment(
|
||||||
|
RejectManualPaymentRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
return await _dispatchRequestToCQRS.Handle<RejectManualPaymentRequest, RejectManualPaymentCommand>(request, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<GetAllManualPaymentsResponse> GetAllManualPayments(
|
||||||
|
GetAllManualPaymentsRequest request,
|
||||||
|
ServerCallContext context)
|
||||||
|
{
|
||||||
|
return await _dispatchRequestToCQRS.Handle<GetAllManualPaymentsRequest, GetAllManualPaymentsQuery, GetAllManualPaymentsResponse>(request, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user