namespace AAIntegration.SimmonsBank.API.Services; using AutoMapper; using BCrypt.Net; using AAIntegration.SimmonsBank.API.Entities; using AAIntegration.SimmonsBank.API.Config; using AAIntegration.SimmonsBank.API.Models.Accounts; using System.Collections; using System.Collections.Generic; using System.Linq; using System; using Internal; using Microsoft.EntityFrameworkCore; public interface IAccountService { IEnumerable GetAll(int ownerId); Account GetById(int accountId, int ownerId); void Create(AccountCreateRequest model, int ownerId); void Update(int accountId, AccountUpdateRequest model, int ownerId); void Delete(int accountId, int ownerId); } public class AccountService : IAccountService { private DataContext _context; private readonly IMapper _mapper; private IUserService _userService; public AccountService( DataContext context, IMapper mapper, IUserService userService) { _context = context; _mapper = mapper; _userService = userService; } public IEnumerable GetAll(int ownerId) { return _context.Accounts .Include(x => x.Owner) .Where(x => x.Owner.Id == ownerId); } public Account GetById(int accountId, int ownerId) { return getAccount(accountId, ownerId); } public void Create(AccountCreateRequest model, int ownerId) { // Check that account with same name or same external number doesn't exist IEnumerable accountsWithSameName = _context.Accounts .Include(x => x.Owner) .Where(x => x.Name.ToUpper() == model.Name.ToUpper() && x.Owner.Id == ownerId); if (accountsWithSameName.Count() > 0) throw new AppException("Account with name '" + model.Name + "' already exists"); if (!string.IsNullOrWhiteSpace(model.ExternalAccountNumber)) { IEnumerable matches = _context.Accounts .Include(x => x.Owner) .Where(x => x.ExternalAccountNumber == model.ExternalAccountNumber && x.Owner.Id == ownerId); if (matches.Count() > 0) throw new AppException("Account with external account number '" + model.ExternalAccountNumber + "' already exists under account named '" + matches.First().Name + "'"); } Account account = new Account { Name = model.Name, Balance = Convert.ToDecimal(model.InitialBalance), ExternalAccountNumber = model.ExternalAccountNumber, Owner = getOwner(ownerId) }; _context.Accounts.Add(account); _context.SaveChanges(); } public void Update(int accountId, AccountUpdateRequest model, int ownerId) { Account account = getAccount(accountId, ownerId); // validate if (model.Name != account.Name && _context.Accounts .Include(x => x.Owner) .Any(x => x.Name == model.Name && x.Owner.Id == ownerId)) throw new AppException("Account with the name '" + model.Name + "' already exists"); // Name if (!string.IsNullOrWhiteSpace(model.Name)) account.Name = model.Name; // External Account Number if (!string.IsNullOrWhiteSpace(model.ExternalAccountNumber)) account.ExternalAccountNumber = model.ExternalAccountNumber; _context.Accounts.Update(account); _context.SaveChanges(); } public void Delete(int accountId, int ownerId) { var account = getAccount(accountId, ownerId); _context.Accounts.Remove(account); _context.SaveChanges(); } // helper methods private Account getAccount(int id, int ownerId) { var account = _context.Accounts .Include(x => x.Owner) .FirstOrDefault(x => x.Id == id && x.Owner.Id == ownerId); if (account == null) throw new KeyNotFoundException("Account not found"); return account; } private User getOwner(int ownerId) { User? owner = _context.Users.Find(ownerId); if (owner == null) throw new AppException($"Owner with ID of '{ownerId}' could not be found"); return owner; } }