feat: Add discount balance and change value to wallet change log
- Added CurrentDiscountBalance and ChangeDiscountValue properties to GetCustomerWalletChangeLogResponseDto. - Updated userwallet.proto to include current_discount_balance and change_discount_value fields. - Enhanced CommissionProfile mapping to support GetMyCommissionPayouts requests and responses. - Implemented GetMyCommissionPayouts query and handler to retrieve user commission payouts. - Added validation for GetMyCommissionPayouts query. - Updated UserOrderService to handle user orders, including VAT calculations and wallet transactions. - Enhanced UserWalletService to include new properties in wallet change log responses.
This commit is contained in:
@@ -5,14 +5,19 @@ using CMSMicroservice.Application.CategoryCQ.Commands.UpdateCategory;
|
||||
using CMSMicroservice.Application.CategoryCQ.Commands.DeleteCategory;
|
||||
using CMSMicroservice.Application.CategoryCQ.Queries.GetCategory;
|
||||
using CMSMicroservice.Application.CategoryCQ.Queries.GetAllCategoryByFilter;
|
||||
using MediatR;
|
||||
using AppModels = CMSMicroservice.Application.Common.Models;
|
||||
|
||||
namespace CMSMicroservice.WebApi.Services;
|
||||
public class CategoryService : CategoryContract.CategoryContractBase
|
||||
{
|
||||
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
|
||||
private readonly ISender _sender;
|
||||
|
||||
public CategoryService(IDispatchRequestToCQRS dispatchRequestToCQRS)
|
||||
public CategoryService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
|
||||
{
|
||||
_dispatchRequestToCQRS = dispatchRequestToCQRS;
|
||||
_sender = sender;
|
||||
}
|
||||
public override async Task<CreateNewCategoryResponse> CreateNewCategory(CreateNewCategoryRequest request, ServerCallContext context)
|
||||
{
|
||||
@@ -45,20 +50,52 @@ public class CategoryService : CategoryContract.CategoryContractBase
|
||||
|
||||
public override async Task<GetAllCategoriesForCustomerResponse> GetAllCategoriesForCustomer(GetAllCategoriesForCustomerRequest request, ServerCallContext context)
|
||||
{
|
||||
// TODO: Implement using existing CMS Category Application layer
|
||||
// For now, return empty response
|
||||
return new GetAllCategoriesForCustomerResponse
|
||||
// Use GetAllCategoryByFilter to get all active categories
|
||||
var query = new GetAllCategoryByFilterQuery
|
||||
{
|
||||
Filter = new CMSMicroservice.Application.CategoryCQ.Queries.GetAllCategoryByFilter.GetAllCategoryByFilterFilter
|
||||
{
|
||||
IsActive = true // Only active categories for customers
|
||||
},
|
||||
PaginationState = new AppModels.PaginationState
|
||||
{
|
||||
PageNumber = request.PageNumber > 0 ? request.PageNumber : 1,
|
||||
PageSize = request.PageSize > 0 ? request.PageSize : 100 // Default to large page size to get all
|
||||
},
|
||||
SortBy = "SortOrder" // Sort by display order
|
||||
};
|
||||
|
||||
var result = await _sender.Send(query, context.CancellationToken);
|
||||
|
||||
var response = new GetAllCategoriesForCustomerResponse
|
||||
{
|
||||
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
|
||||
{
|
||||
CurrentPage = request.PageNumber,
|
||||
PageSize = request.PageSize,
|
||||
TotalCount = 0,
|
||||
TotalPage = 0,
|
||||
HasNext = false,
|
||||
HasPrevious = false
|
||||
CurrentPage = result.MetaData.CurrentPage,
|
||||
PageSize = result.MetaData.PageSize,
|
||||
TotalCount = result.MetaData.TotalCount,
|
||||
TotalPage = result.MetaData.TotalPage,
|
||||
HasNext = result.MetaData.HasNext,
|
||||
HasPrevious = result.MetaData.HasPrevious
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var cat in result.Models)
|
||||
{
|
||||
response.Models.Add(new GetAllCategoryFilterResponseModel
|
||||
{
|
||||
Id = cat.Id,
|
||||
Name = cat.Name,
|
||||
Title = cat.Title,
|
||||
Description = cat.Description ?? string.Empty,
|
||||
ImagePath = cat.ImagePath ?? string.Empty,
|
||||
ParentId = cat.ParentId ?? 0,
|
||||
IsActive = cat.IsActive,
|
||||
SortOrder = cat.SortOrder
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public override async Task<GetCategoryByIdForCustomerResponse> GetCategoryByIdForCustomer(GetCategoryByIdForCustomerRequest request, ServerCallContext context)
|
||||
|
||||
@@ -19,6 +19,7 @@ using CMSMicroservice.Application.CommissionCQ.Queries.GetWorkerExecutionLogs;
|
||||
using CMSMicroservice.Application.CommissionCQ.Queries.GetWithdrawalReports;
|
||||
using CMSMicroservice.Application.CommissionCQ.Queries.GetAvailableWeeks;
|
||||
using CMSMicroservice.Application.CommissionCQ.Queries.GetWeekDefinitions;
|
||||
using CMSMicroservice.Application.CommissionCQ.Queries.GetMyCommissionPayouts;
|
||||
|
||||
namespace CMSMicroservice.WebApi.Services;
|
||||
|
||||
@@ -68,6 +69,11 @@ public class CommissionService : CommissionContract.CommissionContractBase
|
||||
return await _dispatchRequestToCQRS.Handle<GetUserCommissionPayoutsRequest, GetUserCommissionPayoutsQuery, GetUserCommissionPayoutsResponse>(request, context);
|
||||
}
|
||||
|
||||
public override async Task<GetMyCommissionPayoutsResponse> GetMyCommissionPayouts(GetMyCommissionPayoutsRequest request, ServerCallContext context)
|
||||
{
|
||||
return await _dispatchRequestToCQRS.Handle<GetMyCommissionPayoutsRequest, GetMyCommissionPayoutsQuery, GetMyCommissionPayoutsResponse>(request, context);
|
||||
}
|
||||
|
||||
public override async Task<GetCommissionPayoutHistoryResponse> GetCommissionPayoutHistory(GetCommissionPayoutHistoryRequest request, ServerCallContext context)
|
||||
{
|
||||
return await _dispatchRequestToCQRS.Handle<GetCommissionPayoutHistoryRequest, GetCommissionPayoutHistoryQuery, GetCommissionPayoutHistoryResponse>(request, context);
|
||||
|
||||
@@ -6,6 +6,7 @@ using CMSMicroservice.Application.ProductsCQ.Queries.GetCustomerProductsByFilter
|
||||
using Mapster;
|
||||
using AppModels = CMSMicroservice.Application.Common.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CMSMicroservice.WebApi.Services;
|
||||
|
||||
@@ -39,7 +40,64 @@ public class ProductsService : ProductsContract.ProductsContractBase
|
||||
|
||||
public override async Task<GetAllProductsByFilterResponse> GetAllProductsByFilter(GetAllProductsByFilterRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, "Method not implemented yet"));
|
||||
// Map to GetCustomerProductsByFilter query (public products API)
|
||||
var query = new GetCustomerProductsByFilterQuery
|
||||
{
|
||||
Id = request.Filter?.Id,
|
||||
Title = request.Filter?.Title ?? string.Empty,
|
||||
Description = request.Filter?.Description ?? string.Empty,
|
||||
ShortInfomation = request.Filter?.ShortInfomation ?? string.Empty,
|
||||
FullInformation = request.Filter?.FullInformation ?? string.Empty,
|
||||
Price = request.Filter?.Price,
|
||||
Discount = request.Filter?.Discount,
|
||||
Rate = request.Filter?.Rate,
|
||||
SaleCount = request.Filter?.SaleCount,
|
||||
ViewCount = request.Filter?.ViewCount,
|
||||
RemainingCount = request.Filter?.RemainingCount,
|
||||
CategoryIds = request.Filter?.CategoryId.HasValue == true
|
||||
? new List<long> { request.Filter.CategoryId.Value }
|
||||
: new List<long>(),
|
||||
SortBy = request.SortBy ?? string.Empty,
|
||||
PaginationState = request.PaginationState != null
|
||||
? new AppModels.PaginationState
|
||||
{
|
||||
PageNumber = request.PaginationState.PageNumber,
|
||||
PageSize = request.PaginationState.PageSize
|
||||
}
|
||||
: new AppModels.PaginationState { PageNumber = 1, PageSize = 20 }
|
||||
};
|
||||
|
||||
var result = await _sender.Send(query, context.CancellationToken);
|
||||
|
||||
return new GetAllProductsByFilterResponse
|
||||
{
|
||||
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
|
||||
{
|
||||
CurrentPage = result.MetaData.CurrentPage,
|
||||
TotalPage = result.MetaData.TotalPage,
|
||||
PageSize = result.MetaData.PageSize,
|
||||
TotalCount = result.MetaData.TotalCount,
|
||||
HasPrevious = result.MetaData.HasPrevious,
|
||||
HasNext = result.MetaData.HasNext
|
||||
},
|
||||
Models = { result.Models.Select(m => new GetAllProductsByFilterResponseModel
|
||||
{
|
||||
Id = m.Id,
|
||||
Title = m.Title,
|
||||
Description = m.Description,
|
||||
ShortInfomation = m.ShortInfomation,
|
||||
FullInformation = m.FullInformation,
|
||||
Price = m.Price,
|
||||
Discount = m.Discount,
|
||||
Rate = m.Rate,
|
||||
ImagePath = m.ImagePath,
|
||||
ThumbnailPath = m.ThumbnailPath,
|
||||
SaleCount = m.SaleCount,
|
||||
ViewCount = m.ViewCount,
|
||||
RemainingCount = m.RemainingCount,
|
||||
CategoryIds = { m.Categories?.Select(c => c.CategoryId) ?? Enumerable.Empty<long>() }
|
||||
}) }
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task<BulkUpdateProductPricesResponse> BulkUpdateProductPrices(BulkUpdateProductPricesRequest request, ServerCallContext context)
|
||||
|
||||
@@ -2,23 +2,33 @@ using CMSMicroservice.Protobuf.Protos.UserOrder;
|
||||
using CMSMicroservice.Application.UserOrderCQ.Queries.GetCustomerOrders;
|
||||
using CMSMicroservice.Application.UserOrderCQ.Queries.GetCustomerOrder;
|
||||
using CMSMicroservice.Application.UserOrderCQ.Queries.GetCustomerOrderHistory;
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Entities;
|
||||
using CMSMicroservice.Domain.Entities.Order;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using AppModels = CMSMicroservice.Application.Common.Models;
|
||||
using Grpc.Core;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CMSMicroservice.Protobuf.Protos;
|
||||
using MediatR;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace CMSMicroservice.WebApi.Services;
|
||||
|
||||
public class UserOrderService : UserOrderContract.UserOrderContractBase
|
||||
{
|
||||
private readonly ISender _sender;
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ICurrentUserService _currentUserService;
|
||||
|
||||
public UserOrderService(ISender sender)
|
||||
public UserOrderService(ISender sender, IApplicationDbContext context, ICurrentUserService currentUserService)
|
||||
{
|
||||
_sender = sender;
|
||||
_context = context;
|
||||
_currentUserService = currentUserService;
|
||||
}
|
||||
public override async Task<CreateNewUserOrderResponse> CreateNewUserOrder(CreateNewUserOrderRequest request, ServerCallContext context)
|
||||
{
|
||||
@@ -37,17 +47,299 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
|
||||
|
||||
public override async Task<GetUserOrderResponse> GetUserOrder(GetUserOrderRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, "Method not implemented yet"));
|
||||
var query = new GetCustomerOrderQuery
|
||||
{
|
||||
OrderId = request.Id,
|
||||
UserId = 0 // از JWT دریافت میشود
|
||||
};
|
||||
|
||||
var result = await _sender.Send(query, context.CancellationToken);
|
||||
|
||||
var response = new GetUserOrderResponse
|
||||
{
|
||||
Id = result.Id,
|
||||
Amount = result.Amount,
|
||||
PackageId = result.PackageId ?? 0,
|
||||
TransactionId = result.TransactionId,
|
||||
UserId = result.UserId,
|
||||
UserAddressId = result.UserAddressId,
|
||||
UserAddressText = result.UserAddressText,
|
||||
TrackingCode = result.TrackingCode,
|
||||
DeliveryDescription = result.DeliveryDescription,
|
||||
UserFullName = result.UserFullName,
|
||||
UserNationalCode = result.UserNationalCode
|
||||
};
|
||||
|
||||
// VAT Info
|
||||
if (result.VatAmount > 0)
|
||||
{
|
||||
response.VatInfo = new OrderVATInfo
|
||||
{
|
||||
VatRate = result.VatPercentage / 100,
|
||||
BaseAmount = result.Amount - result.VatAmount,
|
||||
VatAmount = result.VatAmount,
|
||||
TotalAmount = result.Amount,
|
||||
IsPaid = result.PaymentStatus == Domain.Enums.PaymentStatus.Success
|
||||
};
|
||||
}
|
||||
|
||||
response.PaymentStatus = (CMSMicroservice.Protobuf.Protos.PaymentStatus)result.PaymentStatus;
|
||||
if (result.PaymentDate.HasValue)
|
||||
response.PaymentDate = Timestamp.FromDateTime(DateTime.SpecifyKind(result.PaymentDate.Value, DateTimeKind.Utc));
|
||||
|
||||
if (result.PaymentMethod.HasValue)
|
||||
response.PaymentMethod = (CMSMicroservice.Protobuf.Protos.PaymentMethod)result.PaymentMethod.Value;
|
||||
|
||||
response.DeliveryStatus = (CMSMicroservice.Protobuf.Protos.DeliveryStatus)result.DeliveryStatus;
|
||||
|
||||
foreach (var fd in result.FactorDetails)
|
||||
{
|
||||
response.FactorDetails.Add(new GetUserOrderResponseFactorDetail
|
||||
{
|
||||
ProductId = fd.ProductId,
|
||||
ProductTitle = fd.ProductTitle,
|
||||
ProductThumbnailPath = fd.ProductThumbnailPath,
|
||||
UnitPrice = fd.UnitPrice,
|
||||
Count = fd.Count,
|
||||
UnitDiscountPrice = fd.UnitDiscountPrice
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public override async Task<GetAllUserOrderByFilterResponse> GetAllUserOrderByFilter(GetAllUserOrderByFilterRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, "Method not implemented yet"));
|
||||
// Admin API - can view all orders or filter by specific user
|
||||
var query = new GetCustomerOrdersQuery
|
||||
{
|
||||
UserId = request.Filter?.UserId ?? 0, // 0 means all users (admin view)
|
||||
PaginationState = request.PaginationState?.Adapt<AppModels.PaginationState>(),
|
||||
PaymentStatusFilter = request.Filter?.PaymentStatus != null
|
||||
? (int?)request.Filter.PaymentStatus
|
||||
: null,
|
||||
DeliveryStatusFilter = request.Filter?.DeliveryStatus != null
|
||||
? (int?)request.Filter.DeliveryStatus
|
||||
: null,
|
||||
FromDate = request.Filter?.PaymentDate?.ToDateTime(),
|
||||
ToDate = null
|
||||
};
|
||||
|
||||
var result = await _sender.Send(query, context.CancellationToken);
|
||||
|
||||
var response = new GetAllUserOrderByFilterResponse
|
||||
{
|
||||
MetaData = result.MetaData.Adapt<MetaData>()
|
||||
};
|
||||
|
||||
foreach (var model in result.Models)
|
||||
{
|
||||
var orderModel = new GetAllUserOrderByFilterResponseModel
|
||||
{
|
||||
Id = model.Id,
|
||||
Amount = model.Amount,
|
||||
PackageId = model.PackageId ?? 0,
|
||||
TransactionId = model.TransactionId,
|
||||
UserId = model.UserId,
|
||||
UserAddressId = model.UserAddressId,
|
||||
UserAddressText = model.UserAddressText,
|
||||
TrackingCode = model.TrackingCode,
|
||||
DeliveryDescription = model.DeliveryDescription,
|
||||
UserFullName = model.UserFullName,
|
||||
UserNationalCode = model.UserNationalCode,
|
||||
VatAmount = model.VatAmount,
|
||||
VatPercentage = model.VatPercentage
|
||||
};
|
||||
|
||||
orderModel.PaymentStatus = (CMSMicroservice.Protobuf.Protos.PaymentStatus)model.PaymentStatus;
|
||||
if (model.PaymentDate.HasValue)
|
||||
orderModel.PaymentDate = Timestamp.FromDateTime(DateTime.SpecifyKind(model.PaymentDate.Value, DateTimeKind.Utc));
|
||||
|
||||
if (model.PaymentMethod.HasValue)
|
||||
orderModel.PaymentMethod = (CMSMicroservice.Protobuf.Protos.PaymentMethod)model.PaymentMethod.Value;
|
||||
|
||||
orderModel.DeliveryStatus = (CMSMicroservice.Protobuf.Protos.DeliveryStatus)model.DeliveryStatus;
|
||||
|
||||
foreach (var fd in model.FactorDetails)
|
||||
{
|
||||
orderModel.FactorDetails.Add(new GetAllUserOrderByFilterResponseModelFactorDetail
|
||||
{
|
||||
ProductId = fd.ProductId,
|
||||
ProductTitle = fd.ProductTitle,
|
||||
ProductThumbnailPath = fd.ProductThumbnailPath,
|
||||
UnitPrice = fd.UnitPrice,
|
||||
Count = fd.Count,
|
||||
UnitDiscountPrice = fd.UnitDiscountPrice
|
||||
});
|
||||
}
|
||||
|
||||
response.Models.Add(orderModel);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public override async Task<SubmitShopBuyOrderResponse> SubmitShopBuyOrder(SubmitShopBuyOrderRequest request, ServerCallContext context)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, "Method not implemented yet"));
|
||||
// Get UserId from JWT or request
|
||||
var userId = !string.IsNullOrEmpty(_currentUserService.UserId)
|
||||
? long.Parse(_currentUserService.UserId)
|
||||
: request.UserId;
|
||||
|
||||
if (userId == 0)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.Unauthenticated, "User not authenticated"));
|
||||
}
|
||||
|
||||
// Get user's cart items with product details
|
||||
var cartItems = await _context.UserCarts
|
||||
.Include(c => c.Product)
|
||||
.Where(c => c.UserId == userId && !c.IsDeleted)
|
||||
.ToListAsync(context.CancellationToken);
|
||||
|
||||
if (!cartItems.Any())
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.FailedPrecondition, "سبد خرید خالی است"));
|
||||
}
|
||||
|
||||
// Get user's default address
|
||||
var defaultAddress = await _context.UserAddresses
|
||||
.Where(a => a.UserId == userId && a.IsDefault && !a.IsDeleted)
|
||||
.FirstOrDefaultAsync(context.CancellationToken);
|
||||
|
||||
if (defaultAddress == null)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.FailedPrecondition, "آدرس پیشفرض یافت نشد"));
|
||||
}
|
||||
|
||||
// Calculate amounts
|
||||
const decimal vatRate = 0.09m;
|
||||
long baseAmount = cartItems.Sum(c => c.Product.Price * c.Count);
|
||||
long vatAmount = (long)(baseAmount * vatRate);
|
||||
long totalAmount = baseAmount + vatAmount;
|
||||
|
||||
// Validate total amount
|
||||
if (request.TotalAmount > 0 && Math.Abs(totalAmount - request.TotalAmount) > 100)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.InvalidArgument,
|
||||
$"مبلغ نامعتبر است. محاسبه شده: {totalAmount}, دریافتی: {request.TotalAmount}"));
|
||||
}
|
||||
|
||||
// Get user's wallet
|
||||
var wallet = await _context.UserWallets
|
||||
.Where(w => w.UserId == userId)
|
||||
.FirstOrDefaultAsync(context.CancellationToken);
|
||||
|
||||
if (wallet == null)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.FailedPrecondition, "کیف پول یافت نشد"));
|
||||
}
|
||||
|
||||
// Check wallet balance
|
||||
if (wallet.Balance < totalAmount)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.FailedPrecondition,
|
||||
$"موجودی کیف پول کافی نیست. موجودی: {wallet.Balance:N0} تومان، مورد نیاز: {totalAmount:N0} تومان"));
|
||||
}
|
||||
|
||||
// Create transaction
|
||||
var transaction = new Transaction
|
||||
{
|
||||
Amount = totalAmount,
|
||||
Description = $"خرید محصولات - سفارش شماره در حال ایجاد",
|
||||
PaymentStatus = CMSMicroservice.Domain.Enums.PaymentStatus.Success,
|
||||
PaymentDate = DateTime.UtcNow,
|
||||
Type = CMSMicroservice.Domain.Enums.TransactionType.Buy,
|
||||
RefId = $"SHOP_{DateTime.UtcNow.Ticks}"
|
||||
};
|
||||
|
||||
_context.Transactions.Add(transaction);
|
||||
await _context.SaveChangesAsync(context.CancellationToken);
|
||||
|
||||
// Deduct from wallet
|
||||
var oldBalance = wallet.Balance;
|
||||
wallet.Balance -= totalAmount;
|
||||
|
||||
// Create wallet change log
|
||||
var walletLog = new UserWalletChangeLog
|
||||
{
|
||||
WalletId = wallet.Id,
|
||||
CurrentBalance = wallet.Balance,
|
||||
ChangeValue = -totalAmount,
|
||||
CurrentNetworkBalance = wallet.NetworkBalance,
|
||||
ChangeNerworkValue = 0,
|
||||
CurrentDiscountBalance = wallet.DiscountBalance,
|
||||
ChangeDiscountValue = 0,
|
||||
IsIncrease = false,
|
||||
RefrenceId = transaction.Id
|
||||
};
|
||||
|
||||
_context.UserWalletChangeLogs.Add(walletLog);
|
||||
|
||||
// Create order
|
||||
var order = new UserOrder
|
||||
{
|
||||
UserId = userId,
|
||||
UserAddressId = defaultAddress.Id,
|
||||
Amount = totalAmount,
|
||||
TransactionId = transaction.Id,
|
||||
PaymentStatus = CMSMicroservice.Domain.Enums.PaymentStatus.Success,
|
||||
PaymentDate = DateTime.UtcNow,
|
||||
PaymentMethod = CMSMicroservice.Domain.Enums.PaymentMethod.Wallet,
|
||||
DeliveryStatus = CMSMicroservice.Domain.Enums.DeliveryStatus.Pending,
|
||||
HasVAT = true
|
||||
};
|
||||
|
||||
_context.UserOrders.Add(order);
|
||||
await _context.SaveChangesAsync(context.CancellationToken);
|
||||
|
||||
// Update transaction description with order ID
|
||||
transaction.Description = $"خرید محصولات - سفارش #{order.Id}";
|
||||
await _context.SaveChangesAsync(context.CancellationToken);
|
||||
|
||||
// Create order VAT record
|
||||
var orderVat = new OrderVAT
|
||||
{
|
||||
OrderId = order.Id,
|
||||
VATRate = vatRate,
|
||||
BaseAmount = baseAmount,
|
||||
VATAmount = vatAmount,
|
||||
TotalAmount = totalAmount
|
||||
};
|
||||
|
||||
_context.OrderVATs.Add(orderVat);
|
||||
|
||||
// Create factor details for each cart item
|
||||
foreach (var cartItem in cartItems)
|
||||
{
|
||||
var factorDetail = new FactorDetails
|
||||
{
|
||||
OrderId = order.Id,
|
||||
ProductId = cartItem.ProductId,
|
||||
Count = cartItem.Count,
|
||||
UnitPrice = cartItem.Product.Price,
|
||||
UnitDiscount = 0,
|
||||
UnitDiscountPrice = cartItem.Product.Price,
|
||||
IsChangePrice = false
|
||||
};
|
||||
|
||||
_context.FactorDetails.Add(factorDetail);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync(context.CancellationToken);
|
||||
|
||||
// Clear user's cart
|
||||
foreach (var cartItem in cartItems)
|
||||
{
|
||||
cartItem.IsDeleted = true;
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync(context.CancellationToken);
|
||||
|
||||
return new SubmitShopBuyOrderResponse
|
||||
{
|
||||
Id = order.Id
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task<CancelOrderResponse> CancelOrder(CancelOrderRequest request, ServerCallContext context)
|
||||
@@ -131,14 +423,14 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
|
||||
VatPercentage = model.VatPercentage
|
||||
};
|
||||
|
||||
orderModel.PaymentStatus = (PaymentStatus)model.PaymentStatus;
|
||||
orderModel.PaymentStatus = (CMSMicroservice.Protobuf.Protos.PaymentStatus)model.PaymentStatus;
|
||||
if (model.PaymentDate.HasValue)
|
||||
orderModel.PaymentDate = Timestamp.FromDateTime(DateTime.SpecifyKind(model.PaymentDate.Value, DateTimeKind.Utc));
|
||||
|
||||
if (model.PaymentMethod.HasValue)
|
||||
orderModel.PaymentMethod = (PaymentMethod)model.PaymentMethod.Value;
|
||||
orderModel.PaymentMethod = (CMSMicroservice.Protobuf.Protos.PaymentMethod)model.PaymentMethod.Value;
|
||||
|
||||
orderModel.DeliveryStatus = (DeliveryStatus)model.DeliveryStatus;
|
||||
orderModel.DeliveryStatus = (CMSMicroservice.Protobuf.Protos.DeliveryStatus)model.DeliveryStatus;
|
||||
|
||||
foreach (var fd in model.FactorDetails)
|
||||
{
|
||||
@@ -197,14 +489,14 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
|
||||
};
|
||||
}
|
||||
|
||||
response.PaymentStatus = (PaymentStatus)result.PaymentStatus;
|
||||
response.PaymentStatus = (CMSMicroservice.Protobuf.Protos.PaymentStatus)result.PaymentStatus;
|
||||
if (result.PaymentDate.HasValue)
|
||||
response.PaymentDate = Timestamp.FromDateTime(DateTime.SpecifyKind(result.PaymentDate.Value, DateTimeKind.Utc));
|
||||
|
||||
if (result.PaymentMethod.HasValue)
|
||||
response.PaymentMethod = (PaymentMethod)result.PaymentMethod.Value;
|
||||
response.PaymentMethod = (CMSMicroservice.Protobuf.Protos.PaymentMethod)result.PaymentMethod.Value;
|
||||
|
||||
response.DeliveryStatus = (DeliveryStatus)result.DeliveryStatus;
|
||||
response.DeliveryStatus = (CMSMicroservice.Protobuf.Protos.DeliveryStatus)result.DeliveryStatus;
|
||||
|
||||
foreach (var fd in result.FactorDetails)
|
||||
{
|
||||
@@ -384,4 +676,15 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
|
||||
TotalAmount = totalAmount
|
||||
};
|
||||
}
|
||||
|
||||
public override Task<GetVATRateResponse> GetVATRate(Google.Protobuf.WellKnownTypes.Empty request, ServerCallContext context)
|
||||
{
|
||||
// VAT Rate for Iran: 9% (نرخ مالیات بر ارزش افزوده ایران)
|
||||
return Task.FromResult(new GetVATRateResponse
|
||||
{
|
||||
VatRate = 0.09,
|
||||
VatPercentage = 9,
|
||||
IsEnabled = true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
|
||||
ChangeValue = log.ChangeValue,
|
||||
CurrentNetworkBalance = log.CurrentNetworkBalance,
|
||||
ChangeNerworkValue = log.ChangeNerworkValue,
|
||||
CurrentDiscountBalance = log.CurrentDiscountBalance,
|
||||
ChangeDiscountValue = log.ChangeDiscountValue,
|
||||
IsIncrease = log.IsIncrease,
|
||||
RefrenceId = log.RefrenceId,
|
||||
CreatedAt = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.SpecifyKind(log.Created, DateTimeKind.Utc))
|
||||
|
||||
Reference in New Issue
Block a user