using BankContracts.BindingModels.Cashier; using BankContracts.BusinessLogicsContracts.Cashier; using BankContracts.SearchModels.Cashier; using BankContracts.StoragesModels.Cashier; using BankContracts.ViewModels; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BankBusinessLogic.BusinessLogic.Cashier { // Класс, реализующий бизнес-логику для счетов public class AccountLogic : IAccountLogic { private readonly ILogger _logger; private readonly IAccountStorage _accountStorage; private readonly ICashWithdrawalLogic _cashWithdrawalLogic; private readonly IMoneyTransferLogic _moneyTransferLogic; // Конструктор public AccountLogic(ILogger logger, IAccountStorage accountStorage, ICashWithdrawalLogic cashWithdrawalLogic, IMoneyTransferLogic moneyTransferLogic) { _logger = logger; _accountStorage = accountStorage; _cashWithdrawalLogic = cashWithdrawalLogic; _moneyTransferLogic = moneyTransferLogic; } // Вывод конкретного счёта public AccountViewModel? ReadElement(AccountSearchModel model) { if (model == null) { throw new ArgumentNullException(nameof(model)); } _logger.LogInformation("ReadElement. AccountNumber:{Name}. Id:{Id}", model.AccountNumber, model?.Id); var element = _accountStorage.GetElement(model); if (element == null) { _logger.LogWarning("ReadElement element not found"); return null; } _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); return element; } // Вывод всего списка счетов public List? ReadList(AccountSearchModel? model) { _logger.LogInformation("ReadList. AccountNumber:{AccountNumber}. Id:{Id}", model.AccountNumber, model?.Id); // list хранит весь список в случае, если model пришло со значением null на вход метода var list = model == null ? _accountStorage.GetFullList() : _accountStorage.GetFilteredList(model); if (list == null) { _logger.LogWarning("ReadList return null list"); return null; } _logger.LogInformation("ReadList. Count:{Count}", list.Count); return list; } // Метод, отвечающий за изменение баланса счёта public bool ChangeBalance(AccountSearchModel? model, int sum) { // Ищем счёт var account = ReadElement(model); if (account == null) { throw new ArgumentNullException("Счёт не найден", nameof(account)); } // Проверяем возможность операции снятия (sum может быть отрицательной) if (sum + account.Balance < 0) { return false; } // Обновляем балланс счёта _accountStorage.Update(new AccountBindingModel { Id = account.Id, Balance = account.Balance + sum }); return true; } // Создание счёта public bool Create(AccountBindingModel model) { CheckModel(model); if (_accountStorage.Insert(model) == null) { _logger.LogWarning("Insert operation failed"); return false; } return true; } // Обновление счёта public bool Update(AccountBindingModel model) { CheckModel(model); if (_accountStorage.Update(model) == null) { _logger.LogWarning("Update operation failed"); return false; } return true; } // Удаление счёта public bool Delete(AccountBindingModel model) { CheckModel(model, false); _logger.LogInformation("Delete. Id:{Id}", model.Id); if (_accountStorage.Delete(model) == null) { _logger.LogWarning("Delete operation failed"); return false; } return true; } // Проверка входного аргумента для методов Insert, Update и Delete private void CheckModel(AccountBindingModel model, bool withParams = true) { if (model == null) { throw new ArgumentNullException(nameof(model)); } // Так как при удалении передаём как параметр false if (!withParams) { return; } // Проверка на наличие номера счёта if (string.IsNullOrEmpty(model.AccountNumber)) { throw new ArgumentNullException("Отсутствие номера у счёта", nameof(model.AccountNumber)); } // Проверка на наличие id клиента (И всё-таки не будет лишним добавить Id клиента) if (model.ClientId < 0) { throw new ArgumentNullException("Некорректный Id клиента", nameof(model.ClientId)); } // Проверка на наличие id кассира, создавшего счёт if (model.CashierId < 0) { throw new ArgumentNullException("Некорректный Id кассира, открывшего счёт", nameof(model.CashierId)); } if (model.Balance < 0) { throw new ArgumentNullException("Изначальный баланс аккаунта не может быть < 0", nameof(model.Balance)); } // Проверка на корректную дату открытия счёта if (model.DateOpen > DateTime.Now) { throw new ArgumentNullException("Дата открытия счёта не может быть ранее текущей", nameof(model.DateOpen)); } _logger.LogInformation("Account. AccountNumber:{AccountNumber}. ClientId:{ClientId}. " + "CashierId:{CashierId}. DateOpen:{DateOpen}. Id:{Id}", model.AccountNumber, model.ClientId, model.CashierId, model.DateOpen, model.Id); // Для проверка на наличие такого же счёта var element = _accountStorage.GetElement(new AccountSearchModel { AccountNumber = model.AccountNumber, }); // Если элемент найден и его Id не совпадает с Id переданного объекта if (element != null && element.Id != model.Id) { throw new InvalidOperationException("Счёт с таким номером уже существует"); } } } }