Handler.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Common.ValueObject;
  4. using Domain.Entities.Donations;
  5. using Microsoft.EntityFrameworkCore;
  6. using SharedKernel.Results;
  7. namespace Application.Features.Api.Studio.Settlement.SaveAccount;
  8. internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result<Response>>
  9. {
  10. private const int MaxAccounts = 8;
  11. public async Task<Result<Response>> Handle(Command request, CancellationToken ct)
  12. {
  13. // 유효성 검사
  14. if (string.IsNullOrWhiteSpace(request.BankCode))
  15. {
  16. return Result.Failure<Response>(Error.Problem("BankCode", "은행을 선택해 주세요."));
  17. }
  18. if (string.IsNullOrWhiteSpace(request.AccountNumber) || request.AccountNumber.Length is < 7 or > 16 || !request.AccountNumber.All(char.IsDigit))
  19. {
  20. return Result.Failure<Response>(Error.Problem("AccountNumber", "올바른 계좌번호를 입력해 주세요. (7~16자리 숫자)"));
  21. }
  22. if (string.IsNullOrWhiteSpace(request.AccountHolder) || request.AccountHolder.Trim().Length < 2)
  23. {
  24. return Result.Failure<Response>(Error.Problem("AccountHolder", "예금주명을 입력해 주세요. (2자 이상)"));
  25. }
  26. var bank = SettlementBankCode.List.FirstOrDefault(b => b.Value == request.BankCode);
  27. if (bank is null)
  28. {
  29. return Result.Failure<Response>(Error.Problem("BankCode", "유효하지 않은 은행 코드입니다."));
  30. }
  31. // 채널 확인
  32. var channel = await db.Channel.AsNoTracking().FirstOrDefaultAsync(c => c.MemberID == request.MemberID && c.IsActive, ct);
  33. if (channel is null)
  34. {
  35. return Result.Failure<Response>(Error.NotFound("Channel", "채널 정보를 찾을 수 없습니다."));
  36. }
  37. // 수정
  38. if (request.AccountID.HasValue)
  39. {
  40. var existing = await db.SettlementAccount.FirstOrDefaultAsync(a => a.ID == request.AccountID.Value && a.MemberID == request.MemberID, ct);
  41. if (existing is null)
  42. {
  43. return Result.Failure<Response>(Error.NotFound("Account", "계좌 정보를 찾을 수 없습니다."));
  44. }
  45. existing.Update(request.BankCode, bank.Text, request.AccountNumber, request.AccountHolder.Trim());
  46. await db.SaveChangesAsync(ct);
  47. return Result.Success(new Response("계좌가 수정되었습니다."));
  48. }
  49. // 신규 등록: 개수 제한
  50. var count = await db.SettlementAccount.CountAsync(a => a.MemberID == request.MemberID, ct);
  51. if (count >= MaxAccounts)
  52. {
  53. return Result.Failure<Response>(Error.Problem("Account", $"계좌는 최대 {MaxAccounts}개까지 등록할 수 있습니다."));
  54. }
  55. var account = SettlementAccount.Create(
  56. channel.ID, request.MemberID,
  57. request.BankCode, bank.Text,
  58. request.AccountNumber, request.AccountHolder.Trim()
  59. );
  60. db.SettlementAccount.Add(account);
  61. await db.SaveChangesAsync(ct);
  62. return Result.Success(new Response("계좌가 등록되었습니다."));
  63. }
  64. }