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:
masoodafar-web
2026-02-07 22:03:49 +03:30
parent b2d676b555
commit 9185aa227d
13 changed files with 961 additions and 61 deletions
@@ -1,8 +1,10 @@
using CMSMicroservice.Application.CommissionCQ.Queries.GetUserWeeklyBalances;
using CMSMicroservice.Application.CommissionCQ.Queries.GetAvailableWeeks;
using CMSMicroservice.Application.CommissionCQ.Queries.GetUserCommissionPayouts;
using CMSMicroservice.Application.CommissionCQ.Queries.GetMyCommissionPayouts;
using CMSMicroservice.Application.CommissionCQ.Queries.GetWeekDefinitions;
using CMSMicroservice.Application.Common.Models;
using CMSMicroservice.Domain.Enums;
using CMSMicroservice.Protobuf.Protos.Commission;
using Google.Protobuf.WellKnownTypes;
using Mapster;
@@ -124,5 +126,38 @@ public class CommissionProfile : IRegister
: null)
.Map(dest => dest.IsExpired, src => src.IsExpired)
.Map(dest => dest.Created, src => Timestamp.FromDateTimeOffset(src.Created));
// GetMyCommissionPayouts Request Mapping
config.NewConfig<GetMyCommissionPayoutsRequest, GetMyCommissionPayoutsQuery>()
.Map(dest => dest.Status, src => src.Status != null && src.Status.Value >= 0
? (CommissionPayoutStatus?)src.Status.Value
: null)
.Map(dest => dest.WeekDefinitionId, src => src.WeekDefinitionId != null ? src.WeekDefinitionId.Value : (long?)null)
.Map(dest => dest.PaginationState, src => new PaginationState
{
PageNumber = src.PageNumber > 0 ? src.PageNumber : 1,
PageSize = src.PageSize > 0 ? src.PageSize : 10
});
// GetMyCommissionPayouts Response Mapping
config.NewConfig<GetMyCommissionPayoutsResponseDto, GetMyCommissionPayoutsResponse>()
.Map(dest => dest.MetaData, src => src.MetaData != null
? new CustomerMetaData { TotalCount = src.MetaData.TotalCount }
: new CustomerMetaData())
.Map(dest => dest.Payouts, src => src.Models);
// CustomerCommissionPayoutModel Mapping
config.NewConfig<GetMyCommissionPayoutsResponseModel, CustomerCommissionPayoutModel>()
.Map(dest => dest.Id, src => src.Id)
.Map(dest => dest.WeekDefinitionId, src => src.WeekDefinitionId)
.Map(dest => dest.WeekDisplayName, src => src.WeekDisplayName)
.Map(dest => dest.BalancesEarned, src => src.BalancesEarned)
.Map(dest => dest.TotalAmount, src => src.TotalAmount)
.Map(dest => dest.AmountFormatted, src => src.AmountFormatted)
.Map(dest => dest.Status, src => (int)src.Status)
.Map(dest => dest.CalculatedDate, src => src.CalculatedDate.HasValue
? Timestamp.FromDateTime(src.CalculatedDate.Value.ToUniversalTime())
: null)
.Map(dest => dest.DatePersian, src => src.DatePersian);
}
}
@@ -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))