feat: Implement customer profile and referral queries

- Add GetCustomerProfileResponseDto for retrieving customer profile information.
- Create GetCustomerReferralsQuery and GetCustomerReferralsQueryHandler to fetch customer referrals with pagination and filtering options.
- Introduce GetCustomerReferralsResponseDto to structure the response for customer referrals.
- Implement GetCustomerSettingsQuery and GetCustomerSettingsQueryHandler to retrieve user settings.
- Add GetCustomerOrder and GetCustomerOrderQueryHandler for fetching specific customer orders.
- Create GetCustomerOrderHistoryQuery and GetCustomerOrderHistoryQueryHandler to retrieve order history with filtering options.
- Implement GetCustomerOrdersQuery and GetCustomerOrdersQueryHandler for fetching multiple customer orders with filters.
- Add GetCustomerWalletChangeLogQuery and GetCustomerWalletChangeLogQueryHandler for retrieving wallet change logs.
- Implement GetCustomerWithdrawalSettingsQuery and GetCustomerWithdrawalSettingsQueryHandler for fetching withdrawal settings.
- Create GetCustomerWithdrawalsQuery and GetCustomerWithdrawalsQueryHandler to retrieve customer withdrawal requests.
This commit is contained in:
masoodafar-web
2026-02-05 23:01:50 +03:30
parent b41342dcad
commit b2d676b555
96 changed files with 4822 additions and 589 deletions
@@ -7,16 +7,23 @@ using CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetUserNetworkPosi
using CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetNetworkTree;
using CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetNetworkMembershipHistory;
using CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetNetworkStatistics;
using CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetMyNetworkTree;
using Mapster;
using CMSMicroservice.Domain.Enums;
namespace CMSMicroservice.WebApi.Services;
public class NetworkMembershipService : NetworkMembershipContract.NetworkMembershipContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
private readonly ISender _sender;
public NetworkMembershipService(IDispatchRequestToCQRS dispatchRequestToCQRS)
public NetworkMembershipService(
IDispatchRequestToCQRS dispatchRequestToCQRS,
ISender sender)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
_sender = sender;
}
public override async Task<Empty> JoinNetwork(JoinNetworkRequest request, ServerCallContext context)
@@ -54,4 +61,134 @@ public class NetworkMembershipService : NetworkMembershipContract.NetworkMembers
{
return await _dispatchRequestToCQRS.Handle<GetNetworkStatisticsRequest, GetNetworkStatisticsQuery, GetNetworkStatisticsResponse>(request, context);
}
// ============= Customer-specific Methods =============
public override async Task<GetMyNetworkTreeResponse> GetMyNetworkTree(GetMyNetworkTreeRequest request, ServerCallContext context)
{
// Use Customer-specific Query that gets UserId from ICurrentUserService
var query = new GetMyNetworkTreeQuery
{
MaxDepth = request.MaxDepth > 0 ? request.MaxDepth : 3
};
var tree = await _sender.Send(query, context.CancellationToken);
if (tree == null)
{
return new GetMyNetworkTreeResponse
{
RootNode = null,
TotalMembers = 0,
CurrentDepth = 0
};
}
// Convert NetworkTreeDto to NetworkTreeNodeModel
var rootNode = ConvertToNodeModel(tree);
return new GetMyNetworkTreeResponse
{
RootNode = rootNode,
TotalMembers = CountNodes(tree),
CurrentDepth = tree.CurrentDepth
};
}
public override async Task<GetMyNetworkTreeResponse> GetSubordinateTree(GetSubordinateTreeRequest request, ServerCallContext context)
{
// Get tree for a specific subordinate user
var query = new GetNetworkTreeQuery
{
UserId = request.TargetUserId,
MaxDepth = request.MaxDepth > 0 ? request.MaxDepth : 3
};
var tree = await _sender.Send(query, context.CancellationToken);
if (tree == null)
{
return new GetMyNetworkTreeResponse
{
RootNode = null,
TotalMembers = 0,
CurrentDepth = 0
};
}
var rootNode = ConvertToNodeModel(tree);
return new GetMyNetworkTreeResponse
{
RootNode = rootNode,
TotalMembers = CountNodes(tree),
CurrentDepth = tree.CurrentDepth
};
}
public override async Task<GetMyNetworkStatisticsResponse> GetMyNetworkStatistics(Google.Protobuf.WellKnownTypes.Empty request, ServerCallContext context)
{
// Get statistics for current user's network
var query = new GetNetworkStatisticsQuery { UserId = 0 }; // Will use ICurrentUserService
var stats = await _sender.Send(query, context.CancellationToken);
return stats.Adapt<GetMyNetworkStatisticsResponse>();
}
// Helper methods for tree conversion
private NetworkTreeNodeModel ConvertToNodeModel(NetworkTreeDto dto)
{
var node = new NetworkTreeNodeModel
{
UserId = dto.UserId,
UserName = $"{dto.FirstName} {dto.LastName}".Trim(),
FullName = $"{dto.FirstName} {dto.LastName}".Trim(),
NetworkLeg = dto.LegPosition.HasValue ? (int)dto.LegPosition.Value : 0,
NetworkLevel = dto.CurrentDepth,
Level = dto.CurrentDepth,
IsActive = dto.IsClubActive,
IsClubActive = dto.IsClubActive,
ReferralCode = dto.ReferralCode ?? "",
Mobile = dto.Mobile ?? "",
Position = dto.LegPosition.HasValue ? dto.LegPosition.Value.ToString() : "Root"
};
if (dto.ClubActivatedAt.HasValue)
{
node.ClubActivatedAt = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(
DateTime.SpecifyKind(dto.ClubActivatedAt.Value, DateTimeKind.Utc));
}
if (dto.UserCreated != null)
{
node.UserCreated = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(
dto.UserCreated.UtcDateTime);
}
if (dto.ActivationWeekDefinitionId.HasValue)
{
node.ActivationWeekDefinitionId = dto.ActivationWeekDefinitionId.Value;
}
node.IsActivatedInTargetWeek = dto.IsActivatedInTargetWeek;
// Recursively convert children
if (dto.LeftChild != null)
{
node.LeftChild = ConvertToNodeModel(dto.LeftChild);
}
if (dto.RightChild != null)
{
node.RightChild = ConvertToNodeModel(dto.RightChild);
}
return node;
}
private int CountNodes(NetworkTreeDto tree)
{
if (tree == null) return 0;
return 1 + CountNodes(tree.LeftChild) + CountNodes(tree.RightChild);
}
}
@@ -10,18 +10,27 @@ using CMSMicroservice.Application.PackageCQ.Commands.VerifyBasePackagePayment;
using CMSMicroservice.Application.PackageCQ.Queries.GetPackage;
using CMSMicroservice.Application.PackageCQ.Queries.GetAllPackageByFilter;
using CMSMicroservice.Application.PackageCQ.Queries.GetUserPackageStatus;
using CMSMicroservice.Application.PackageCQ.Queries.GetCustomerPackages;
using CMSMicroservice.Application.PackageCQ.Queries.GetCustomerPackageDetails;
using CMSMicroservice.Application.PackageCQ.Queries.GetCustomerPurchaseHistory;
using AppModels = CMSMicroservice.Application.Common.Models;
using Grpc.Core;
using Google.Protobuf.WellKnownTypes;
using System.Collections.Generic;
using CMSMicroservice.Protobuf.Protos;
using MediatR;
using Mapster;
namespace CMSMicroservice.WebApi.Services;
public class PackageService : PackageContract.PackageContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
private readonly ISender _sender;
public PackageService(IDispatchRequestToCQRS dispatchRequestToCQRS)
public PackageService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
_sender = sender;
}
public override async Task<CreateNewPackageResponse> CreateNewPackage(CreateNewPackageRequest request, ServerCallContext context)
{
@@ -74,108 +83,61 @@ public class PackageService : PackageContract.PackageContractBase
public override async Task<GetCustomerPackagesResponse> GetCustomerPackages(GetCustomerPackagesRequest request, ServerCallContext context)
{
// Mock Customer packages with realistic Persian data
var packages = new List<CustomerPackageModel>
var query = new GetCustomerPackagesQuery
{
new CustomerPackageModel
{
Id = 1,
Name = "پکیج طلایی",
Title = "پکیج طلایی", // Populate alias field
Description = "پکیج کامل با امکانات ویژه برای کاربران فعال",
Price = 5600000,
Currency = "IRR",
PackageType = PackageTypeEnum.PackageTypeGolden,
IsAvailable = true,
ImageUrl = "/images/packages/golden.jpg",
ImagePath = "/images/packages/golden.jpg", // Populate alias field
ValidityDays = 365,
IsPopular = true,
ShortDescription = "بهترین انتخاب برای درآمد بیشتر"
},
new CustomerPackageModel
{
Id = 2,
Name = "پکیج پریمیوم",
Title = "پکیج پریمیوم", // Populate alias field
Description = "پکیج پیشرفته با امکانات حرفه‌ای",
Price = 3200000,
Currency = "IRR",
PackageType = PackageTypeEnum.PackageTypePremium,
IsAvailable = true,
ImageUrl = "/images/packages/premium.jpg",
ImagePath = "/images/packages/premium.jpg", // Populate alias field
ValidityDays = 180,
IsPopular = false,
ShortDescription = "برای کسب و کارهای متوسط"
},
new CustomerPackageModel
{
Id = 3,
Name = "پکیج ابتدایی",
Title = "پکیج ابتدایی", // Populate alias field
Description = "پکیج مقدماتی برای شروع کار",
Price = 1500000,
Currency = "IRR",
PackageType = PackageTypeEnum.PackageTypeBasic,
IsAvailable = true,
ImageUrl = "/images/packages/basic.jpg",
ImagePath = "/images/packages/basic.jpg", // Populate alias field
ValidityDays = 90,
IsPopular = false,
ShortDescription = "مناسب برای شروع کننده‌ها"
}
};
return new GetCustomerPackagesResponse
{
Models = { packages }
IncludeInactive = request.IncludeInactive,
PackageTypeFilter = request.PackageTypeFilter != PackageTypeEnum.PackageTypeBasic
? (int?)request.PackageTypeFilter
: null
};
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerPackagesResponse();
response.Models.AddRange(result.Adapt<List<CustomerPackageModel>>());
return response;
}
public override async Task<GetCustomerPackageDetailsResponse> GetCustomerPackageDetails(GetCustomerPackageDetailsRequest request, ServerCallContext context)
{
// Mock Customer package details with comprehensive Persian information
var packageFeatures = new List<PackageFeature>
var query = new GetCustomerPackageDetailsQuery
{
new PackageFeature
{
Title = "درآمد کمیسیون",
Description = "دریافت کمیسیون از فروش محصولات",
Icon = "commission",
IsHighlighted = true
},
new PackageFeature
{
Title = "پشتیبانی 24/7",
Description = "دسترسی به پشتیبانی در تمام ساعات شبانه روز",
Icon = "support",
IsHighlighted = false
},
new PackageFeature
{
Title = "آموزش‌های تخصصی",
Description = "دسترسی به دوره‌های آموزشی و وبینارها",
Icon = "education",
IsHighlighted = true
}
PackageId = request.PackageId
};
return new GetCustomerPackageDetailsResponse
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerPackageDetailsResponse
{
Id = request.PackageId,
Title = "پکیج طلایی",
Description = "پکیج کامل با تمام امکانات برای کاربران حرفه‌ای",
Price = 5600000,
ImagePath = "/images/packages/golden-detail.jpg",
Features = { packageFeatures },
Requirements = new PurchaseRequirements
{
RequiresMembership = false,
MinimumWalletBalance = 560000,
Restrictions = { "باید حداقل 18 سال سن داشته باشید", "تایید هویت الزامی است" }
}
Id = result.Id,
Title = result.Title,
Description = result.Description,
Price = result.Price,
ImagePath = result.ImagePath
};
// Map Features
foreach (var feature in result.Features)
{
response.Features.Add(new PackageFeature
{
Title = feature.Title,
Description = feature.Description,
Icon = feature.Icon,
IsHighlighted = feature.IsHighlighted
});
}
// Map Requirements
response.Requirements = new PurchaseRequirements
{
RequiresMembership = result.Requirements.RequiresMembership,
MinimumWalletBalance = result.Requirements.MinimumWalletBalance
};
response.Requirements.Restrictions.AddRange(result.Requirements.Restrictions);
return response;
}
public override async Task<CustomerPurchasePackageResponse> CustomerPurchasePackage(CustomerPurchasePackageRequest request, ServerCallContext context)
@@ -189,7 +151,7 @@ public class PackageService : PackageContract.PackageContractBase
Success = true,
Message = "درخواست خرید پکیج با موفقیت ثبت شد",
OrderId = orderId,
PaymentGatewayUrl = $"https://payment.gateway.com/payment?authority={authority}&amount={GetPackagePrice(request.PackageId)}",
PaymentGatewayUrl = $"https://payment.gateway.com/payment?authority={authority}&amount=5600000",
Authority = authority
};
}
@@ -221,60 +183,43 @@ public class PackageService : PackageContract.PackageContractBase
public override async Task<GetCustomerPurchaseHistoryResponse> GetCustomerPurchaseHistory(GetCustomerPurchaseHistoryRequest request, ServerCallContext context)
{
// Mock Customer purchase history with realistic Persian data
var purchases = new List<PackagePurchaseHistory>
var query = new GetCustomerPurchaseHistoryQuery
{
new PackagePurchaseHistory
{
Id = 1,
PackageId = 1,
PackageName = "پکیج طلایی",
Amount = 5600000,
PackageType = PackageTypeEnum.PackageTypeGolden,
PurchaseDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-30)),
ExpiryDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(335)),
Status = PaymentStatusEnum.PaymentStatusSuccess,
StatusMessage = "فعال",
ReferenceCode = "REF123456789"
},
new PackagePurchaseHistory
{
Id = 2,
PackageId = 2,
PackageName = "پکیج پریمیوم",
Amount = 3200000,
PackageType = PackageTypeEnum.PackageTypePremium,
PurchaseDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-180)),
ExpiryDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-150)),
Status = PaymentStatusEnum.PaymentStatusSuccess,
StatusMessage = "منقضی شده",
ReferenceCode = "REF987654321"
}
UserId = request.UserId,
PaginationState = request.PaginationState?.Adapt<AppModels.PaginationState>(),
PackageTypeFilter = request.PackageTypeFilter != PackageTypeEnum.PackageTypeBasic
? (int?)request.PackageTypeFilter
: null,
FromDate = request.FromDate?.ToDateTime(),
ToDate = request.ToDate?.ToDateTime()
};
return new GetCustomerPurchaseHistoryResponse
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerPurchaseHistoryResponse
{
MetaData = new MetaData
{
CurrentPage = request.PaginationState?.PageNumber ?? 1,
TotalPage = 1,
PageSize = request.PaginationState?.PageSize ?? 10,
TotalCount = purchases.Count,
HasPrevious = false,
HasNext = false
},
Purchases = { purchases }
MetaData = result.MetaData.Adapt<MetaData>()
};
}
private long GetPackagePrice(long packageId)
{
return packageId switch
foreach (var purchase in result.Purchases)
{
1 => 5600000, // Golden
2 => 3200000, // Premium
3 => 1500000, // Basic
_ => 1000000 // Default
};
response.Purchases.Add(new PackagePurchaseHistory
{
Id = purchase.Id,
PackageId = purchase.PackageId,
PackageName = purchase.PackageName,
Amount = purchase.Amount,
PackageType = (PackageTypeEnum)purchase.PackageType,
PurchaseDate = Timestamp.FromDateTime(DateTime.SpecifyKind(purchase.PurchaseDate, DateTimeKind.Utc)),
ExpiryDate = purchase.ExpiryDate.HasValue
? Timestamp.FromDateTime(DateTime.SpecifyKind(purchase.ExpiryDate.Value, DateTimeKind.Utc))
: null,
Status = (PaymentStatusEnum)purchase.Status,
StatusMessage = purchase.StatusMessage,
ReferenceCode = purchase.ReferenceCode
});
}
return response;
}
}
@@ -1,10 +1,22 @@
using CMSMicroservice.Protobuf.Protos.Products;
using Grpc.Core;
using MediatR;
using CMSMicroservice.Application.ProductsCQ.Queries.GetCustomerProducts;
using CMSMicroservice.Application.ProductsCQ.Queries.GetCustomerProductsByFilter;
using Mapster;
using AppModels = CMSMicroservice.Application.Common.Models;
using System.Collections.Generic;
namespace CMSMicroservice.WebApi.Services;
public class ProductsService : ProductsContract.ProductsContractBase
{
private readonly ISender _sender;
public ProductsService(ISender sender)
{
_sender = sender;
}
public override async Task<CreateNewProductsResponse> CreateNewProducts(CreateNewProductsRequest request, ServerCallContext context)
{
throw new RpcException(new Status(StatusCode.Unimplemented, "Method not implemented yet"));
@@ -54,121 +66,159 @@ public class ProductsService : ProductsContract.ProductsContractBase
public override async Task<GetProductsResponse> GetCustomerProducts(GetProductsRequest request, ServerCallContext context)
{
// For now, return mock response with gallery and categories
return new GetProductsResponse
var query = new GetCustomerProductsQuery { Id = request.Id };
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetProductsResponse
{
Id = request.Id,
Title = $"Product {request.Id}",
Description = "Sample product description for customers",
ShortInfomation = "Short info",
FullInformation = "Full product information for customers",
Price = 50000,
Discount = 10,
Rate = 4,
ImagePath = "/images/product.jpg",
ThumbnailPath = "/images/product-thumb.jpg",
SaleCount = 25,
ViewCount = 150,
RemainingCount = 10,
Gallery =
Id = result.Id,
Title = result.Title,
Description = result.Description,
ShortInfomation = result.ShortInfomation,
FullInformation = result.FullInformation,
Price = result.Price,
Discount = result.Discount,
Rate = result.Rate,
ImagePath = result.ImagePath,
ThumbnailPath = result.ThumbnailPath,
SaleCount = result.SaleCount,
ViewCount = result.ViewCount,
RemainingCount = result.RemainingCount
};
// Add gallery items
if (result.Gallery != null)
{
foreach (var item in result.Gallery)
{
new ProductGalleryItem
response.Gallery.Add(new ProductGalleryItem
{
ProductGalleryId = 1,
ProductImageId = 1,
Title = "Main Image",
ImagePath = "/gallery/main.jpg",
ImageThumbnailPath = "/gallery/main-thumb.jpg"
}
},
Categories =
ProductGalleryId = item.ProductGalleryId,
ProductImageId = item.ProductImageId,
Title = item.Title,
ImagePath = item.ImagePath,
ImageThumbnailPath = item.ImageThumbnailPath
});
}
}
// Add categories
if (result.Categories != null)
{
foreach (var cat in result.Categories)
{
new ProductCategoryPath
var categoryPath = new ProductCategoryPath
{
CategoryId = 1,
Title = "Electronics",
Path =
CategoryId = cat.CategoryId,
Title = cat.Title
};
if (cat.Path != null)
{
foreach (var node in cat.Path)
{
new CategoryNode { Id = 1, Title = "Electronics" }
categoryPath.Path.Add(new CategoryNode
{
Id = node.Id,
Title = node.Title,
ParentId = node.ParentId
});
}
}
response.Categories.Add(categoryPath);
}
};
}
return response;
}
public override async Task<GetCustomerProductsByFilterResponse> GetCustomerProductsByFilter(GetAllProductsByFilterRequest request, ServerCallContext context)
{
// Mock response for customers with categories
return new GetCustomerProductsByFilterResponse
var query = new GetCustomerProductsByFilterQuery
{
PaginationState = request.PaginationState?.Adapt<AppModels.PaginationState>(),
SortBy = request.SortBy,
Id = request.Filter?.Id,
Title = request.Filter?.Title,
Description = request.Filter?.Description,
ShortInfomation = request.Filter?.ShortInfomation,
FullInformation = request.Filter?.FullInformation,
Price = request.Filter?.Price,
Discount = request.Filter?.Discount,
Rate = request.Filter?.Rate,
ImagePath = request.Filter?.ImagePath,
ThumbnailPath = request.Filter?.ThumbnailPath,
SaleCount = request.Filter?.SaleCount,
ViewCount = request.Filter?.ViewCount,
RemainingCount = request.Filter?.RemainingCount,
CategoryIds = request.Filter?.CategoryId != null ? new List<long> { request.Filter.CategoryId.Value } : null
};
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerProductsByFilterResponse
{
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{
CurrentPage = 1,
TotalPage = 1,
PageSize = 10,
TotalCount = 2,
HasPrevious = false,
HasNext = false
},
Models =
{
new GetCustomerProductsByFilterResponseModel
{
Id = 1,
Title = "Sample Product 1",
Description = "Description 1",
ShortInfomation = "Short info 1",
FullInformation = "Full info 1",
Price = 45000,
Discount = 5,
Rate = 4,
ImagePath = "/images/product1.jpg",
ThumbnailPath = "/images/product1-thumb.jpg",
SaleCount = 15,
ViewCount = 120,
RemainingCount = 8,
Categories =
{
new ProductCategoryPath
{
CategoryId = 1,
Title = "Electronics",
Path =
{
new CategoryNode { Id = 1, Title = "Electronics" }
}
}
}
},
new GetCustomerProductsByFilterResponseModel
{
Id = 2,
Title = "Sample Product 2",
Description = "Description 2",
ShortInfomation = "Short info 2",
FullInformation = "Full info 2",
Price = 35000,
Discount = 15,
Rate = 5,
ImagePath = "/images/product2.jpg",
ThumbnailPath = "/images/product2-thumb.jpg",
SaleCount = 30,
ViewCount = 200,
RemainingCount = 5,
Categories =
{
new ProductCategoryPath
{
CategoryId = 2,
Title = "Books",
Path =
{
new CategoryNode { Id = 2, Title = "Books" }
}
}
}
}
CurrentPage = result.MetaData.CurrentPage,
TotalPage = result.MetaData.TotalPage,
PageSize = result.MetaData.PageSize,
TotalCount = result.MetaData.TotalCount,
HasPrevious = result.MetaData.HasPrevious,
HasNext = result.MetaData.HasNext
}
};
foreach (var model in result.Models)
{
var productModel = new GetCustomerProductsByFilterResponseModel
{
Id = model.Id,
Title = model.Title,
Description = model.Description,
ShortInfomation = model.ShortInfomation,
FullInformation = model.FullInformation,
Price = model.Price,
Discount = model.Discount,
Rate = model.Rate,
ImagePath = model.ImagePath,
ThumbnailPath = model.ThumbnailPath,
SaleCount = model.SaleCount,
ViewCount = model.ViewCount,
RemainingCount = model.RemainingCount
};
if (model.Categories != null)
{
foreach (var cat in model.Categories)
{
var categoryPath = new ProductCategoryPath
{
CategoryId = cat.CategoryId,
Title = cat.Title
};
if (cat.Path != null)
{
foreach (var node in cat.Path)
{
categoryPath.Path.Add(new CategoryNode
{
Id = node.Id,
Title = node.Title,
ParentId = node.ParentId
});
}
}
productModel.Categories.Add(categoryPath);
}
}
response.Models.Add(productModel);
}
return response;
}
}
@@ -7,15 +7,22 @@ using CMSMicroservice.Application.TransactionsCQ.Queries.GetTransactions;
using CMSMicroservice.Application.TransactionsCQ.Queries.GetAllTransactionsByFilter;
using CMSMicroservice.Application.TransactionsCQ.Commands.VerifyTransaction;
using CMSMicroservice.Application.TransactionsCQ.Commands.RefundTransaction;
using CMSMicroservice.Application.TransactionsCQ.Queries.GetCustomerTransaction;
using CMSMicroservice.Application.TransactionsCQ.Queries.GetCustomerTransactionsByFilter;
using AppModels = CMSMicroservice.Application.Common.Models;
using MediatR;
using Mapster;
namespace CMSMicroservice.WebApi.Services;
public class TransactionsService : TransactionsContract.TransactionsContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
private readonly ISender _sender;
public TransactionsService(IDispatchRequestToCQRS dispatchRequestToCQRS)
public TransactionsService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
_sender = sender;
}
public override async Task<CreateNewTransactionsResponse> CreateNewTransactions(CreateNewTransactionsRequest request, ServerCallContext context)
{
@@ -52,87 +59,64 @@ public class TransactionsService : TransactionsContract.TransactionsContractBase
public override async Task<GetCustomerTransactionResponse> GetCustomerTransaction(GetCustomerTransactionRequest request, ServerCallContext context)
{
// Mock response for customer transaction
var query = new GetCustomerTransactionQuery
{
Id = request.Id,
Authority = request.Authority,
UserId = 0 // از JWT دریافت می‌شود
};
var result = await _sender.Send(query, context.CancellationToken);
return new GetCustomerTransactionResponse
{
Id = request.Id ?? 1,
MerchantId = "MERCHANT123",
Amount = 150000,
CallbackUrl = "https://mysite.com/callback",
Description = "خرید محصولات",
Mobile = "09123456789",
Email = "customer@example.com",
RequestStatusCode = 100,
RequestStatusMessage = "Success",
Authority = request.Authority ?? "A0000000000000000000000000001234567",
FeeType = "Payer",
Fee = 1500,
Currency = CurrencyEnum.Irr,
PaymentStatus = true,
VerificationStatusCode = 101,
VerificationStatusMessage = "Verified",
CardHash = "4F8A56B2C1D3E9A7B5C2F1E8D6A9B4C7E3F2A1D5",
CardPan = "622106******4567",
RefId = "REF123456789",
OrderId = "ORDER001",
Type = TransactionTypeEnum.Real
Id = result.Id,
Amount = result.Amount,
Description = result.Description,
PaymentStatus = result.PaymentStatus == Domain.Enums.PaymentStatus.Success,
RefId = result.RefId,
Type = (TransactionTypeEnum)result.Type,
Currency = CurrencyEnum.Irr
};
}
public override async Task<GetCustomerTransactionsByFilterResponse> GetCustomerTransactionsByFilter(GetCustomerTransactionsByFilterRequest request, ServerCallContext context)
{
// Mock response for customer transactions list
return new GetCustomerTransactionsByFilterResponse
var query = new GetCustomerTransactionsByFilterQuery
{
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{
CurrentPage = 1,
TotalPage = 1,
PageSize = 10,
TotalCount = 2,
HasPrevious = false,
HasNext = false
},
Models =
{
new GetCustomerTransactionsByFilterResponseModel
{
Id = 1,
MerchantId = "MERCHANT123",
Amount = 150000,
CallbackUrl = "https://mysite.com/callback",
Description = "خرید محصولات",
Mobile = "09123456789",
Email = "customer@example.com",
Authority = "A0000000000000000000000000001234567",
Fee = 1500,
Currency = CurrencyEnum.Irr,
PaymentStatus = true,
CardHash = "4F8A56B2C1D3E9A7B5C2F1E8D6A9B4C7E3F2A1D5",
CardPan = "622106******4567",
RefId = "REF123456789",
OrderId = "ORDER001",
Type = TransactionTypeEnum.Real
},
new GetCustomerTransactionsByFilterResponseModel
{
Id = 2,
MerchantId = "MERCHANT123",
Amount = 75000,
CallbackUrl = "https://mysite.com/callback",
Description = "تست پرداخت",
Mobile = "09123456789",
Email = "customer@example.com",
Authority = "A0000000000000000000000000001234568",
Fee = 750,
Currency = CurrencyEnum.Irr,
PaymentStatus = false,
RefId = "REF123456790",
OrderId = "ORDER002",
Type = TransactionTypeEnum.Sandbox
}
}
UserId = 0, // از JWT دریافت می‌شود
PaginationState = request.PaginationState?.Adapt<AppModels.PaginationState>(),
SortBy = request.SortBy,
IdFilter = request.Filter?.Id,
AmountFilter = request.Filter?.Amount,
DescriptionFilter = request.Filter?.Description,
PaymentStatusFilter = request.Filter?.PaymentStatus,
RefIdFilter = request.Filter?.RefId,
TypeFilter = request.Filter?.Type != null ? (int?)request.Filter.Type : null
};
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerTransactionsByFilterResponse
{
MetaData = result.MetaData.Adapt<CMSMicroservice.Protobuf.Protos.MetaData>()
};
foreach (var model in result.Models)
{
response.Models.Add(new GetCustomerTransactionsByFilterResponseModel
{
Id = model.Id,
Amount = model.Amount,
Description = model.Description,
PaymentStatus = model.PaymentStatus == Domain.Enums.PaymentStatus.Success,
RefId = model.RefId,
Type = (TransactionTypeEnum)model.Type,
Currency = CurrencyEnum.Irr
});
}
return response;
}
public override async Task<CustomerPaymentRequestResponse> CustomerPaymentRequest(CustomerPaymentRequestRequest request, ServerCallContext context)
@@ -6,15 +6,28 @@ using CMSMicroservice.Application.UserAddressCQ.Commands.DeleteUserAddress;
using CMSMicroservice.Application.UserAddressCQ.Queries.GetUserAddress;
using CMSMicroservice.Application.UserAddressCQ.Queries.GetAllUserAddressByFilter;
using CMSMicroservice.Application.UserAddressCQ.Commands.SetAddressAsDefault;
using CMSMicroservice.Application.UserAddressCQ.Queries.GetCustomerAddresses;
using CMSMicroservice.Application.UserAddressCQ.Commands.CreateCustomerAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.UpdateCustomerAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.DeleteCustomerAddress;
using CMSMicroservice.Application.UserAddressCQ.Commands.SetCustomerDefaultAddress;
using MediatR;
namespace CMSMicroservice.WebApi.Services;
public class UserAddressService : UserAddressContract.UserAddressContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
private readonly ISender _sender;
public UserAddressService(IDispatchRequestToCQRS dispatchRequestToCQRS)
public UserAddressService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
_sender = sender;
}
#region Admin Methods
public override async Task<CreateNewUserAddressResponse> CreateNewUserAddress(CreateNewUserAddressRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<CreateNewUserAddressRequest, CreateNewUserAddressCommand, CreateNewUserAddressResponse>(request, context);
@@ -39,4 +52,96 @@ public class UserAddressService : UserAddressContract.UserAddressContractBase
{
return await _dispatchRequestToCQRS.Handle<SetAddressAsDefaultRequest, SetAddressAsDefaultCommand>(request, context);
}
#endregion
#region Customer Methods
public override async Task<GetCustomerAddressesResponse> GetCustomerAddresses(GetCustomerAddressesRequest request, ServerCallContext context)
{
var query = new GetCustomerAddressesQuery();
var result = await _sender.Send(query);
var response = new GetCustomerAddressesResponse();
foreach (var addr in result.Addresses)
{
response.Models.Add(new CMSMicroservice.Protobuf.Protos.UserAddress.CustomerAddressModel
{
Id = addr.Id,
Title = addr.Title,
Address = addr.Address,
PostalCode = addr.PostalCode,
IsDefault = addr.IsDefault,
CityId = addr.CityId,
CityName = addr.CityName,
ProvinceName = addr.ProvinceName
});
}
return response;
}
public override async Task<CreateCustomerAddressResponse> CreateCustomerAddress(CreateCustomerAddressRequest request, ServerCallContext context)
{
var command = new CreateCustomerAddressCommand
{
Title = request.Title,
Address = request.Address,
PostalCode = request.PostalCode,
IsDefault = request.IsDefault,
CityId = request.CityId
};
var result = await _sender.Send(command);
return new CreateCustomerAddressResponse
{
Id = result.Id,
Message = result.Message
};
}
public override async Task<Empty> UpdateCustomerAddress(UpdateCustomerAddressRequest request, ServerCallContext context)
{
var command = new UpdateCustomerAddressCommand
{
Id = request.Id,
Title = request.Title,
Address = request.Address,
PostalCode = request.PostalCode,
IsDefault = request.IsDefault,
CityId = request.CityId
};
await _sender.Send(command);
return new Empty();
}
public override async Task<Empty> DeleteCustomerAddress(DeleteCustomerAddressRequest request, ServerCallContext context)
{
var command = new DeleteCustomerAddressCommand
{
Id = request.Id
};
await _sender.Send(command);
return new Empty();
}
public override async Task<Empty> SetCustomerDefaultAddress(SetCustomerDefaultAddressRequest request, ServerCallContext context)
{
var command = new SetCustomerDefaultAddressCommand
{
Id = request.Id
};
await _sender.Send(command);
return new Empty();
}
#endregion
}
@@ -1,15 +1,23 @@
using CMSMicroservice.Application.DiscountShopCQ.Commands.AddToCustomerCart;
using CMSMicroservice.Application.DiscountShopCQ.Commands.RemoveFromCustomerCart;
using CMSMicroservice.Application.DiscountShopCQ.Commands.UpdateCustomerCartItem;
using CMSMicroservice.Application.DiscountShopCQ.Queries.GetCustomerCart;
using CMSMicroservice.Protobuf.Protos.UserCarts;
using CMSMicroservice.WebApi.Common.Services;
using Google.Protobuf.WellKnownTypes;
using MediatR;
namespace CMSMicroservice.WebApi.Services;
public class UserCartsService : UserCartsContract.UserCartsContractBase
{
private readonly IDispatchRequestToCQRS _dispatcher;
private readonly ISender _sender;
public UserCartsService(IDispatchRequestToCQRS dispatcher)
public UserCartsService(IDispatchRequestToCQRS dispatcher, ISender sender)
{
_dispatcher = dispatcher;
_sender = sender;
}
#region Customer Methods
@@ -17,38 +25,89 @@ public class UserCartsService : UserCartsContract.UserCartsContractBase
public override async Task<AddNewUserCartForCustomerResponse> AddNewUserCartForCustomer(
AddNewUserCartForCustomerRequest request, ServerCallContext context)
{
// TODO: Map to DiscountShop AddToCart command
var command = new AddToCustomerCartCommand
{
ProductId = request.ProductId,
Count = request.Count
};
var result = await _sender.Send(command);
return new AddNewUserCartForCustomerResponse
{
Message = "AddNewUserCartForCustomer not implemented yet"
Id = result.Id,
Message = result.Message,
Success = result.Success
};
}
public override async Task<UpdateUserCartForCustomerResponse> UpdateUserCartForCustomer(
UpdateUserCartForCustomerRequest request, ServerCallContext context)
{
// TODO: Map to DiscountShop UpdateCartItemCount command
var command = new UpdateCustomerCartItemCommand
{
CartItemId = request.CartItemId,
Count = request.Count
};
var result = await _sender.Send(command);
return new UpdateUserCartForCustomerResponse
{
Message = "UpdateUserCartForCustomer not implemented yet"
Message = result.Message,
Success = result.Success
};
}
public override async Task<RemoveUserCartForCustomerResponse> RemoveUserCartForCustomer(
RemoveUserCartForCustomerRequest request, ServerCallContext context)
{
// TODO: Map to DiscountShop RemoveFromCart command
var command = new RemoveFromCustomerCartCommand
{
CartItemId = request.CartItemId
};
var result = await _sender.Send(command);
return new RemoveUserCartForCustomerResponse
{
Message = "RemoveUserCartForCustomer not implemented yet"
Message = result.Message,
Success = result.Success
};
}
public override async Task<GetUserCartForCustomerResponse> GetCustomerCart(
GetUserCartForCustomerRequest request, ServerCallContext context)
{
// TODO: Map to DiscountShop GetUserCart query
return new GetUserCartForCustomerResponse();
var query = new GetCustomerCartQuery();
var result = await _sender.Send(query);
var response = new GetUserCartForCustomerResponse
{
TotalPrice = result.TotalPrice,
TotalItemsCount = result.TotalItemsCount,
Message = result.Message
};
foreach (var item in result.Items)
{
response.Models.Add(new UserCartItem
{
Id = item.Id,
ProductId = item.ProductId,
ProductTitle = item.ProductTitle,
ProductShortInformation = item.ProductShortInformation,
ProductShortInfomation = item.ProductShortInformation, // Alias for typo compatibility
ProductPrice = item.ProductPrice,
ProductDiscount = item.ProductDiscount,
ProductThumbnailPath = item.ProductThumbnailPath,
Count = item.Count,
TotalItemPrice = item.TotalItemPrice,
Created = Timestamp.FromDateTime(DateTime.SpecifyKind(item.Created, DateTimeKind.Utc))
});
}
return response;
}
#endregion
@@ -1,13 +1,25 @@
using CMSMicroservice.Protobuf.Protos.UserOrder;
using CMSMicroservice.Application.UserOrderCQ.Queries.GetCustomerOrders;
using CMSMicroservice.Application.UserOrderCQ.Queries.GetCustomerOrder;
using CMSMicroservice.Application.UserOrderCQ.Queries.GetCustomerOrderHistory;
using AppModels = CMSMicroservice.Application.Common.Models;
using Grpc.Core;
using Google.Protobuf.WellKnownTypes;
using System.Collections.Generic;
using CMSMicroservice.Protobuf.Protos;
using MediatR;
using Mapster;
namespace CMSMicroservice.WebApi.Services;
public class UserOrderService : UserOrderContract.UserOrderContractBase
{
private readonly ISender _sender;
public UserOrderService(ISender sender)
{
_sender = sender;
}
public override async Task<CreateNewUserOrderResponse> CreateNewUserOrder(CreateNewUserOrderRequest request, ServerCallContext context)
{
throw new RpcException(new Status(StatusCode.Unimplemented, "Method not implemented yet"));
@@ -79,22 +91,135 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
public override async Task<GetAllUserOrderByFilterResponse> GetCustomerOrders(GetAllUserOrderByFilterRequest request, ServerCallContext context)
{
// For now, return empty response - will be implemented properly later
return new GetAllUserOrderByFilterResponse();
var query = new GetCustomerOrdersQuery
{
UserId = request.Filter?.UserId ?? 0,
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 = (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.DeliveryStatus = (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<GetUserOrderResponse> GetCustomerOrder(GetUserOrderRequest request, ServerCallContext context)
{
// Mock Customer order details with correct property names
return new GetUserOrderResponse
var query = new GetCustomerOrderQuery
{
Id = request.Id,
Amount = 250000,
PackageId = 1,
UserId = 1,
PaymentStatus = PaymentStatus.Success,
PaymentDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-2))
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 = (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.DeliveryStatus = (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;
}
// ============= Customer-specific Method Implementations =============
@@ -113,54 +238,46 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
public override async Task<GetCustomerOrderHistoryResponse> GetCustomerOrderHistory(GetCustomerOrderHistoryRequest request, ServerCallContext context)
{
// Mock Customer order history with realistic Persian data
var orders = new List<CustomerOrderModel>
var query = new GetCustomerOrderHistoryQuery
{
new CustomerOrderModel
{
Id = 1,
Amount = 250000,
PackageId = 1,
PackageName = "پکیج اسپشیال",
Status = OrderStatusEnum.OrderStatusDelivered,
StatusMessage = "تحویل داده شد",
OrderDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-10)),
DeliveryDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-3)),
TrackingCode = "TRK001",
ItemsCount = 5,
CanCancel = false,
CanReorder = true
},
new CustomerOrderModel
{
Id = 2,
Amount = 150000,
PackageId = 2,
PackageName = "پکیج عادی",
Status = OrderStatusEnum.OrderStatusShipped,
StatusMessage = "ارسال شده",
OrderDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-3)),
DeliveryDate = Timestamp.FromDateTime(DateTime.UtcNow.AddDays(2)),
TrackingCode = "TRK002",
ItemsCount = 3,
CanCancel = true,
CanReorder = true
}
UserId = request.UserId,
PaginationState = request.PaginationState?.Adapt<AppModels.PaginationState>(),
StatusFilter = request.StatusFilter != OrderStatusEnum.OrderStatusPending
? (int?)request.StatusFilter
: null,
FromDate = request.FromDate?.ToDateTime(),
ToDate = request.ToDate?.ToDateTime()
};
return new GetCustomerOrderHistoryResponse
var result = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerOrderHistoryResponse
{
MetaData = new MetaData
{
CurrentPage = request.PaginationState?.PageNumber ?? 1,
TotalPage = 1,
PageSize = request.PaginationState?.PageSize ?? 10,
TotalCount = orders.Count,
HasPrevious = false,
HasNext = false
},
Orders = { orders }
MetaData = result.MetaData.Adapt<MetaData>()
};
foreach (var order in result.Orders)
{
response.Orders.Add(new Protobuf.Protos.UserOrder.CustomerOrderModel
{
Id = order.Id,
Amount = order.Amount,
PackageId = order.PackageId ?? 0,
PackageName = order.PackageName,
Status = (OrderStatusEnum)order.Status,
StatusMessage = order.StatusMessage,
OrderDate = Timestamp.FromDateTime(DateTime.SpecifyKind(order.OrderDate, DateTimeKind.Utc)),
DeliveryDate = order.DeliveryDate.HasValue
? Timestamp.FromDateTime(DateTime.SpecifyKind(order.DeliveryDate.Value, DateTimeKind.Utc))
: null,
TrackingCode = order.TrackingCode,
ItemsCount = order.ItemsCount,
CanCancel = order.CanCancel,
CanReorder = order.CanReorder
});
}
return response;
}
public override async Task<CustomerTrackOrderResponse> CustomerTrackOrder(CustomerTrackOrderRequest request, ServerCallContext context)
@@ -225,7 +342,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase
return new CustomerTrackOrderResponse
{
Order = new CustomerOrderModel
Order = new Protobuf.Protos.UserOrder.CustomerOrderModel
{
Id = request.OrderId,
Amount = 180000,
@@ -13,17 +13,26 @@ using CMSMicroservice.Application.UserCQ.Commands.RefreshToken;
using CMSMicroservice.Application.UserCQ.Commands.CreateNewOtpToken;
using CMSMicroservice.Application.UserCQ.Commands.VerifyOtpToken;
using CMSMicroservice.Application.UserCQ.Commands.AcceptContract;
using CMSMicroservice.Application.UserCQ.Queries.GetCustomerProfile;
using CMSMicroservice.Application.UserCQ.Queries.GetCustomerReferrals;
using CMSMicroservice.Application.UserCQ.Queries.GetCustomerSettings;
using Google.Protobuf.WellKnownTypes;
using System.Collections.Generic;
using System.Linq;
using MediatR;
using Mapster;
using AppModels = CMSMicroservice.Application.Common.Models;
namespace CMSMicroservice.WebApi.Services;
public class UserService : UserContract.UserContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
private readonly ISender _sender;
public UserService(IDispatchRequestToCQRS dispatchRequestToCQRS)
public UserService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
_sender = sender;
}
public override async Task<CreateNewUserResponse> CreateNewUser(CreateNewUserRequest request, ServerCallContext context)
{
@@ -113,28 +122,32 @@ public class UserService : UserContract.UserContractBase
public override async Task<GetCustomerProfileResponse> GetCustomerProfile(GetCustomerProfileRequest request, ServerCallContext context)
{
// Mock implementation for Get Customer Profile
await Task.Delay(10);
var query = new GetCustomerProfileQuery { UserId = 0 };
var result = await _sender.Send(query, context.CancellationToken);
return new GetCustomerProfileResponse
{
Id = 123,
FirstName = "احمد",
LastName = "محمدی",
Mobile = "09123456789",
Email = "ahmad.mohammadi@example.com",
NationalCode = "1234567890",
AvatarPath = "/avatars/user_123.jpg",
ParentId = 100,
ReferralCode = "REF123456",
IsMobileVerified = true,
MobileVerifiedAt = Timestamp.FromDateTime(DateTime.SpecifyKind(new DateTime(2024, 1, 15), DateTimeKind.Utc)),
EmailNotifications = true,
SmsNotifications = true,
PushNotifications = false,
BirthDate = Timestamp.FromDateTime(DateTime.SpecifyKind(new DateTime(1990, 5, 20), DateTimeKind.Utc)),
FullName = "احمد محمدی",
ProfileCompletionPercentage = 85
Id = result.Id,
FirstName = result.FirstName,
LastName = result.LastName,
Mobile = result.Mobile,
Email = result.Email,
NationalCode = result.NationalCode,
AvatarPath = result.AvatarPath,
ParentId = result.ParentId,
ReferralCode = result.ReferralCode,
IsMobileVerified = result.IsMobileVerified,
MobileVerifiedAt = result.MobileVerifiedAt.HasValue
? Timestamp.FromDateTime(DateTime.SpecifyKind(result.MobileVerifiedAt.Value, DateTimeKind.Utc))
: null,
EmailNotifications = result.EmailNotifications,
SmsNotifications = result.SmsNotifications,
PushNotifications = result.PushNotifications,
BirthDate = result.BirthDate.HasValue
? Timestamp.FromDateTime(DateTime.SpecifyKind(result.BirthDate.Value, DateTimeKind.Utc))
: null,
FullName = result.FullName,
ProfileCompletionPercentage = result.ProfileCompletionPercentage
};
}
@@ -170,69 +183,52 @@ public class UserService : UserContract.UserContractBase
public override async Task<GetCustomerReferralsResponse> GetCustomerReferrals(GetCustomerReferralsRequest request, ServerCallContext context)
{
// Mock implementation for Get Customer Referrals
await Task.Delay(10);
var referrals = new List<CustomerReferralModel>
var query = new GetCustomerReferralsQuery
{
new CustomerReferralModel
{
Id = 1,
FirstName = "علی",
LastName = "احمدی",
Mobile = "09121234567",
JoinDate = Timestamp.FromDateTime(DateTime.SpecifyKind(new DateTime(2025, 12, 1), DateTimeKind.Utc)),
IsActive = true,
StatusMessage = "فعال",
Level = 1,
TotalCommission = 2500000
},
new CustomerReferralModel
{
Id = 2,
FirstName = "فاطمه",
LastName = "کریمی",
Mobile = "09122345678",
JoinDate = Timestamp.FromDateTime(DateTime.SpecifyKind(new DateTime(2025, 11, 15), DateTimeKind.Utc)),
IsActive = true,
StatusMessage = "فعال",
Level = 1,
TotalCommission = 1800000
},
new CustomerReferralModel
{
Id = 3,
FirstName = "محسن",
LastName = "رضایی",
Mobile = "09123456789",
JoinDate = Timestamp.FromDateTime(DateTime.SpecifyKind(new DateTime(2025, 10, 20), DateTimeKind.Utc)),
IsActive = false,
StatusMessage = "غیرفعال",
Level = 1,
TotalCommission = 950000
}
UserId = 0,
PaginationState = request.PaginationState?.Adapt<AppModels.PaginationState>(),
StatusFilter = request.StatusFilter
};
var result = await _sender.Send(query, context.CancellationToken);
return new GetCustomerReferralsResponse
var response = new GetCustomerReferralsResponse
{
MetaData = new MetaData
{
CurrentPage = 1,
TotalPage = 1,
PageSize = 10,
TotalCount = 3,
HasPrevious = false,
HasNext = false
CurrentPage = result.MetaData.CurrentPage,
TotalPage = result.MetaData.TotalPage,
PageSize = result.MetaData.PageSize,
TotalCount = result.MetaData.TotalCount,
HasPrevious = result.MetaData.HasPrevious,
HasNext = result.MetaData.HasNext
},
Referrals = { referrals },
Stats = new CustomerReferralStats
Stats = new CMSMicroservice.Protobuf.Protos.User.CustomerReferralStats
{
TotalReferrals = 3,
ActiveReferrals = 2,
TotalCommissionEarned = 5250000,
ThisMonthCommission = 850000
TotalReferrals = result.Stats.TotalReferrals,
ActiveReferrals = result.Stats.ActiveReferrals,
TotalCommissionEarned = result.Stats.TotalCommissionEarned,
ThisMonthCommission = result.Stats.ThisMonthCommission
}
};
foreach (var referral in result.Referrals)
{
response.Referrals.Add(new CMSMicroservice.Protobuf.Protos.User.CustomerReferralModel
{
Id = referral.Id,
FirstName = referral.FirstName,
LastName = referral.LastName,
Mobile = referral.Mobile,
JoinDate = Timestamp.FromDateTime(DateTime.SpecifyKind(referral.JoinDate, DateTimeKind.Utc)),
IsActive = referral.IsActive,
StatusMessage = referral.StatusMessage,
Level = referral.Level,
TotalCommission = referral.TotalCommission
});
}
return response;
}
public override async Task<UploadCustomerAvatarResponse> UploadCustomerAvatar(UploadCustomerAvatarRequest request, ServerCallContext context)
@@ -282,18 +278,18 @@ public class UserService : UserContract.UserContractBase
public override async Task<GetCustomerSettingsResponse> GetCustomerSettings(GetCustomerSettingsRequest request, ServerCallContext context)
{
// Mock implementation for Get Customer Settings
await Task.Delay(10);
var query = new GetCustomerSettingsQuery { UserId = 0 };
var result = await _sender.Send(query, context.CancellationToken);
return new GetCustomerSettingsResponse
{
EmailNotifications = true,
SmsNotifications = true,
PushNotifications = false,
MarketingNotifications = true,
PreferredLanguage = "fa-IR",
TimeZone = "Asia/Tehran",
TwoFactorAuthEnabled = false
EmailNotifications = result.EmailNotifications,
SmsNotifications = result.SmsNotifications,
PushNotifications = result.PushNotifications,
MarketingNotifications = result.MarketingNotifications,
PreferredLanguage = result.PreferredLanguage,
TimeZone = result.TimeZone,
TwoFactorAuthEnabled = result.TwoFactorAuthEnabled
};
}
@@ -5,14 +5,19 @@ using CMSMicroservice.Application.UserWalletCQ.Commands.UpdateUserWallet;
using CMSMicroservice.Application.UserWalletCQ.Commands.DeleteUserWallet;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetUserWallet;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetAllUserWalletByFilter;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWalletChangeLog;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWithdrawals;
using CMSMicroservice.Application.UserWalletCQ.Queries.GetCustomerWithdrawalSettings;
namespace CMSMicroservice.WebApi.Services;
public class UserWalletService : UserWalletContract.UserWalletContractBase
{
private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;
private readonly ISender _sender;
public UserWalletService(IDispatchRequestToCQRS dispatchRequestToCQRS)
public UserWalletService(IDispatchRequestToCQRS dispatchRequestToCQRS, ISender sender)
{
_dispatchRequestToCQRS = dispatchRequestToCQRS;
_sender = sender;
}
public override async Task<CreateNewUserWalletResponse> CreateNewUserWallet(CreateNewUserWalletRequest request, ServerCallContext context)
{
@@ -39,53 +44,56 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
public override async Task<GetCustomerWalletResponse> GetCustomerWallet(Google.Protobuf.WellKnownTypes.Empty request, ServerCallContext context)
{
// Mock response for customer wallet
// Use GetUserWallet with Id=0 to automatically use current user from JWT
var walletQuery = new GetUserWalletQuery { Id = 0 };
var wallet = await _sender.Send(walletQuery, context.CancellationToken);
return new GetCustomerWalletResponse
{
Balance = 150000,
NetworkBalance = 75000,
DiscountBalance = 25000
Balance = wallet.Balance,
NetworkBalance = wallet.NetworkBalance,
DiscountBalance = wallet.DiscountBalance
};
}
public override async Task<GetCustomerWalletChangeLogResponse> GetCustomerWalletChangeLog(GetCustomerWalletChangeLogRequest request, ServerCallContext context)
{
// Mock response for wallet change log
return new GetCustomerWalletChangeLogResponse
var query = new GetCustomerWalletChangeLogQuery
{
ReferenceId = request.ReferenceId,
IsIncrease = request.IsIncrease
};
var changeLogs = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerWalletChangeLogResponse
{
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{
CurrentPage = 1,
TotalPage = 1,
PageSize = 10,
TotalCount = 3,
PageSize = changeLogs.Count,
TotalCount = changeLogs.Count,
HasPrevious = false,
HasNext = false
},
Models =
{
new CustomerWalletChangeLogModel
{
CurrentBalance = 150000,
ChangeValue = 50000,
CurrentNetworkBalance = 75000,
ChangeNerworkValue = 25000,
IsIncrease = true,
RefrenceId = 123,
CreatedAt = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-1))
},
new CustomerWalletChangeLogModel
{
CurrentBalance = 100000,
ChangeValue = -20000,
CurrentNetworkBalance = 50000,
ChangeNerworkValue = -10000,
IsIncrease = false,
RefrenceId = 124,
CreatedAt = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-2))
}
}
};
foreach (var log in changeLogs)
{
response.Models.Add(new CustomerWalletChangeLogModel
{
CurrentBalance = log.CurrentBalance,
ChangeValue = log.ChangeValue,
CurrentNetworkBalance = log.CurrentNetworkBalance,
ChangeNerworkValue = log.ChangeNerworkValue,
IsIncrease = log.IsIncrease,
RefrenceId = log.RefrenceId,
CreatedAt = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.SpecifyKind(log.Created, DateTimeKind.Utc))
});
}
return response;
}
public override async Task<Google.Protobuf.WellKnownTypes.Empty> CustomerWithdrawBalance(CustomerWithdrawBalanceRequest request, ServerCallContext context)
@@ -96,41 +104,52 @@ public class UserWalletService : UserWalletContract.UserWalletContractBase
public override async Task<GetCustomerWithdrawalsResponse> GetCustomerWithdrawals(GetCustomerWithdrawalsRequest request, ServerCallContext context)
{
// Mock response for customer withdrawals
return new GetCustomerWithdrawalsResponse
var query = new GetCustomerWithdrawalsQuery
{
Status = request.Status
};
var withdrawals = await _sender.Send(query, context.CancellationToken);
var response = new GetCustomerWithdrawalsResponse
{
MetaData = new CMSMicroservice.Protobuf.Protos.MetaData
{
CurrentPage = 1,
TotalPage = 1,
PageSize = 10,
TotalCount = 1,
PageSize = withdrawals.Count,
TotalCount = withdrawals.Count,
HasPrevious = false,
HasNext = false
},
Models =
{
new CustomerWithdrawalModel
{
Id = 1,
WeekDefinitionId = 1,
WeekDisplayName = "هفته 1 - دی 1403",
TotalAmount = 50000,
Status = 1, // 0: Pending, 1: Approved, 2: Rejected
WithdrawalMethod = 0, // 0: Cash, 1: Diamond
IbanNumber = "IR123456789",
Created = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-3))
}
}
};
foreach (var withdrawal in withdrawals)
{
response.Models.Add(new CustomerWithdrawalModel
{
Id = withdrawal.Id,
WeekDefinitionId = withdrawal.WeekDefinitionId,
WeekDisplayName = withdrawal.WeekDisplayName,
TotalAmount = withdrawal.TotalAmount,
Status = withdrawal.Status,
WithdrawalMethod = withdrawal.WithdrawalMethod,
IbanNumber = withdrawal.IbanNumber,
Created = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.SpecifyKind(withdrawal.Created, DateTimeKind.Utc))
});
}
return response;
}
public override async Task<GetCustomerWithdrawalSettingsResponse> GetCustomerWithdrawalSettings(Google.Protobuf.WellKnownTypes.Empty request, ServerCallContext context)
{
// Mock response for withdrawal settings
var query = new GetCustomerWithdrawalSettingsQuery();
var settings = await _sender.Send(query, context.CancellationToken);
return new GetCustomerWithdrawalSettingsResponse
{
MinWithdrawalAmount = 50000 // Minimum 50,000 for withdrawal
MinWithdrawalAmount = settings.MinWithdrawalAmount
};
}
}