Implement Inventory Management Service with CRUD operations for warehouses and inventory items, stock operations, and bulk processing capabilities.
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m48s

This commit is contained in:
masoodafar-web
2026-01-02 00:45:37 +03:30
parent f0117eb1d5
commit 1cf501711f
50 changed files with 10699 additions and 101 deletions
@@ -32,4 +32,9 @@ public class CreateManualPaymentCommand : IRequest<long>
/// شماره مرجع یا شماره فیش (اختیاری)
/// </summary>
public string? ReferenceNumber { get; set; }
/// <summary>
/// مسیر تصویر فیش واریزی (اختیاری)
/// </summary>
public string? ImagePath { get; set; }
}
@@ -1,5 +1,6 @@
using CMSMicroservice.Application.Common.Exceptions;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Common;
using CMSMicroservice.Domain.Entities;
using CMSMicroservice.Domain.Entities.Payment;
using CMSMicroservice.Domain.Enums;
@@ -32,13 +33,24 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
try
{
_logger.LogInformation(
"Creating manual payment for UserId: {UserId}, Amount: {Amount}, Type: {Type}",
"Creating manual membership payment for UserId: {UserId}, Type: {Type}",
request.UserId,
request.Amount,
request.Type
);
// 1. بررسی وجود کاربر
// 1. بررسی Admin فعلی
var currentUserId = _currentUser.UserId;
if (string.IsNullOrEmpty(currentUserId))
{
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
}
if (!long.TryParse(currentUserId, out var adminUserId))
{
throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
}
// 2. بررسی وجود کاربر
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);
@@ -48,47 +60,102 @@ public class CreateManualPaymentCommandHandler : IRequestHandler<CreateManualPay
throw new NotFoundException(nameof(User), request.UserId);
}
// 2. بررسی Admin فعلی
var currentUserId = _currentUser.UserId;
if (string.IsNullOrEmpty(currentUserId))
// 3. پیدا کردن کیف پول
var wallet = await _context.UserWallets
.FirstOrDefaultAsync(w => w.UserId == request.UserId, cancellationToken);
if (wallet == null)
{
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
_logger.LogError("Wallet not found for UserId: {UserId}", request.UserId);
throw new NotFoundException($"کیف پول کاربر {request.UserId} یافت نشد");
}
if (!long.TryParse(currentUserId, out var requestedById))
{
throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
}
// 4. محاسبه مبالغ
var balanceAmount = SystemConstants.BasePackageAmount; // 56M
var discountBalanceAmount = SystemConstants.BasePackageAmount * 2; // 112M
var totalAmount = balanceAmount + discountBalanceAmount; // 168M
// 3. ایجاد ManualPayment
// 5. ثبت تراکنش
var transaction = new Transaction
{
Amount = totalAmount,
Description = $"عضویت دستی باشگاه مشتریان - {request.Description} - مرجع: {request.ReferenceNumber}",
PaymentStatus = PaymentStatus.Success,
PaymentDate = DateTime.Now,
RefId = request.ReferenceNumber,
Type = TransactionType.DepositExternal1
};
_context.Transactions.Add(transaction);
await _context.SaveChangesAsync(cancellationToken);
// 6. ایجاد ManualPayment با وضعیت Approved (بدون نیاز به تایید دو مرحله‌ای)
var manualPayment = new ManualPayment
{
UserId = request.UserId,
Amount = request.Amount,
Amount = totalAmount,
Type = request.Type,
Description = request.Description,
ReferenceNumber = request.ReferenceNumber,
Status = ManualPaymentStatus.Pending,
RequestedBy = requestedById
ImagePath = request.ImagePath,
Status = ManualPaymentStatus.Approved,
RequestedBy = adminUserId,
ApprovedBy = adminUserId,
ApprovedAt = DateTime.Now,
TransactionId = transaction.Id
};
_context.ManualPayments.Add(manualPayment);
// 7. اعمال تغییرات بر کیف پول
var oldBalance = wallet.Balance;
var oldDiscountBalance = wallet.DiscountBalance;
wallet.Balance += balanceAmount; // +56M
wallet.DiscountBalance += discountBalanceAmount; // +112M
// 8. ثبت لاگ کیف پول
var walletLog = new UserWalletChangeLog
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
ChangeValue = balanceAmount,
CurrentNetworkBalance = wallet.NetworkBalance,
ChangeNerworkValue = 0,
CurrentDiscountBalance = wallet.DiscountBalance,
ChangeDiscountValue = discountBalanceAmount,
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(walletLog, cancellationToken);
// 9. تنظیم روش خرید پکیج
user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase;
// 10. ذخیره همه تغییرات
await _context.SaveChangesAsync(cancellationToken);
_logger.LogInformation(
"Manual payment created successfully. Id: {Id}, UserId: {UserId}, RequestedBy: {RequestedBy}",
"Manual membership payment created successfully. " +
"ManualPaymentId: {Id}, UserId: {UserId}, TransactionId: {TransactionId}, " +
"Balance: {OldBalance} -> {NewBalance}, DiscountBalance: {OldDiscount} -> {NewDiscount}",
manualPayment.Id,
request.UserId,
requestedById
transaction.Id,
oldBalance,
wallet.Balance,
oldDiscountBalance,
wallet.DiscountBalance
);
return manualPayment.Id;
}
catch (Exception ex)
catch (Exception ex) when (ex is not NotFoundException && ex is not UnauthorizedAccessException)
{
_logger.LogError(
ex,
"Error creating manual payment for UserId: {UserId}",
"Error creating manual membership payment for UserId: {UserId}",
request.UserId
);
throw;
@@ -118,58 +118,19 @@ public class ProcessManualMembershipPaymentCommandHandler : IRequestHandler<Proc
};
await _context.UserWalletChangeLogs.AddAsync(balanceLog, cancellationToken);
user.PackagePurchaseMethod = PackagePurchaseMethod.DirectPurchase;
// 10. به‌روزرسانی ManualPayment با TransactionId
manualPayment.TransactionId = transaction.Id;
await _context.SaveChangesAsync(cancellationToken);
// 11. پیدا کردن یا ایجاد آدرس پیشفرض کاربر
var userAddress = await _context.UserAddresses
.Where(a => a.UserId == request.UserId)
.OrderByDescending(a => a.IsDefault)
.ThenBy(a => a.Id)
.FirstOrDefaultAsync(cancellationToken);
if (userAddress == null)
{
userAddress = new UserAddress
{
UserId = request.UserId,
Title = "آدرس پیشفرض",
Address = "پرداخت دستی عضویت - آدرس موقت",
PostalCode = "0000000000",
IsDefault = true,
CityId = 1
};
await _context.UserAddresses.AddAsync(userAddress, cancellationToken);
await _context.SaveChangesAsync(cancellationToken);
}
// 12. ثبت سفارش
var order = new UserOrder
{
UserId = request.UserId,
Amount = request.Amount,
TransactionId = transaction.Id,
PaymentStatus = PaymentStatus.Success,
PaymentDate = DateTime.Now,
PaymentMethod = PaymentMethod.Deposit,
DeliveryStatus = DeliveryStatus.None,
UserAddressId = userAddress.Id,
DeliveryDescription = $"پرداخت دستی عضویت - مرجع: {request.ReferenceNumber}"
};
_context.UserOrders.Add(order);
await _context.SaveChangesAsync(cancellationToken);
_logger.LogInformation(
"Manual membership payment processed successfully. UserId: {UserId}, Amount: {Amount}, ManualPaymentId: {ManualPaymentId}, TransactionId: {TransactionId}, OrderId: {OrderId}, AdminUserId: {AdminUserId}",
request.UserId, request.Amount, manualPayment.Id, transaction.Id, order.Id, adminUserId);
"Manual membership payment processed successfully. UserId: {UserId}, Amount: {Amount}, ManualPaymentId: {ManualPaymentId}, TransactionId: {TransactionId}, AdminUserId: {AdminUserId}",
request.UserId, request.Amount, manualPayment.Id, transaction.Id, adminUserId);
return new ProcessManualMembershipPaymentResponseDto
{
TransactionId = transaction.Id,
OrderId = order.Id,
NewWalletBalance = wallet.Balance,
Message = "پرداخت دستی با موفقیت ثبت شد"
};