| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- using Application.Abstractions.Messaging;
- using Application.Abstractions.Data;
- using SharedKernel.Results;
- using Domain.Entities.Common.ValueObject;
- using Domain.Entities.Wallets.ValueObject;
- using Microsoft.EntityFrameworkCore;
- namespace Application.Features.Admin.Member.Wallet.List.Charge;
- public sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result>
- {
- public async Task<Result> Handle(Command request, CancellationToken ct)
- {
- var wallet = await db.Wallet.Include(x => x.Balances).Include(x => x.Transactions).FirstOrDefaultAsync(x => x.ID == request.WalletID, ct);
- if (wallet is null)
- {
- return Result.Failure(Error.NotFound("Wallet.NotFound", "지갑을 찾을 수 없습니다."));
- }
- if (request.BalanceType == WalletBalanceType.Locked)
- {
- return Result.Failure(Error.Problem("Wallet.LockedNotAdjustable", "잠금 잔액은 직접 조정할 수 없습니다."));
- }
- var amount = Money.KRW(Math.Abs(request.Amount));
- var reason = request.Amount > 0 ? "관리자 충전" : "관리자 차감";
- if (request.Amount > 0)
- {
- if (request.BalanceType.HasValue)
- {
- wallet.AdjustIncrease(request.BalanceType.Value, amount, reason, memo: request.Memo);
- }
- else
- {
- wallet.AdjustIncrease(amount, reason, memo: request.Memo);
- }
- }
- else if (request.Amount < 0)
- {
- if (request.BalanceType.HasValue)
- {
- // 지정 잔액 단일 차감 — 구지갑은 해당 유형 row 가 없을 수 있어 컬렉션에서 직접 조회
- var typeBalance = wallet.Balances.SingleOrDefault(x => x.Type == request.BalanceType.Value)?.Amount.Value ?? 0;
- if (typeBalance < amount.Value)
- {
- return Result.Failure(Error.Problem("Wallet.InsufficientBalance", "선택한 잔액 유형의 차감 가능 금액이 부족합니다."));
- }
- wallet.AdjustDecrease(request.BalanceType.Value, amount, reason, memo: request.Memo);
- }
- else
- {
- if (wallet.GetTotalAvailable().Value < amount.Value)
- {
- return Result.Failure(Error.Problem("Wallet.InsufficientBalance", "차감 가능한 잔액이 부족합니다."));
- }
- wallet.AdjustDecreaseAcrossBalances(amount, reason, memo: request.Memo);
- }
- }
- else
- {
- return Result.Failure(Error.Problem("Wallet.AmountRequired", "충전 금액을 입력해주세요."));
- }
- await db.SaveChangesAsync(ct);
- return Result.Success();
- }
- }
|