GetOperationHistory(Integer bankAccountId) {
- return operations;
- }
-}
diff --git a/DataAccess/src/main/java/DataAccess/UserRepository.java b/DataAccess/src/main/java/DataAccess/UserRepository.java
deleted file mode 100644
index 8cd18c2..0000000
--- a/DataAccess/src/main/java/DataAccess/UserRepository.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package DataAccess;
-
-import lombok.NoArgsConstructor;
-import Application.Abstractions.Repositories.IUserRepository;
-import Application.Contracts.ResultTypes.UserResult;
-import Application.Models.Entites.User;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-/**
- * Реализация репозитория для управления пользователями.
- * Хранит пользователей в памяти (в списке) и реализует операции CRUD для сущности {@link User}.
- *
- * Этот класс использует {@link ArrayList} для хранения данных и позволяет добавлять, обновлять, искать и удалять пользователей.
- */
-@NoArgsConstructor
-public class UserRepository implements IUserRepository {
-
- private final ArrayList _users = new ArrayList<>();
-
- /**
- * Добавляет нового пользователя в хранилище.
- *
- * @param user объект пользователя, который будет добавлен.
- * @return результат операции добавления, может быть ошибка создания пользователя, если пользователь равен {@code null}.
- */
- @Override
- public UserResult AddUser(User user) {
- if (user == null) {
- return new UserResult.UserCreationError("User can not be null");
- }
- _users.add(user);
- return new UserResult.Success();
- }
-
- /**
- * Находит пользователя по его идентификатору.
- *
- * @param id идентификатор пользователя, которого нужно найти.
- * @return найденный пользователь или {@code null}, если пользователь с таким идентификатором не существует.
- */
- @Override
- public User FindUserById(Integer id) {
- if (id < 0) {
- return null;
- }
- for (User user : _users) {
- if (Objects.equals(user.getId(), id)) {
- return user;
- }
- }
- return null;
- }
-
- /**
- * Обновляет данные пользователя по его идентификатору.
- *
- * @param id идентификатор пользователя, которого нужно обновить.
- * @param userUpdate объект с новыми данными пользователя.
- * @return результат операции обновления, может быть ошибка, если параметры обновления неверны.
- */
- @Override
- public UserResult UpdateUser(Integer id, User userUpdate) {
- if (userUpdate == null || id < 0) {
- return new UserResult.UserUpdateError("Invalid update parameters");
- }
-
- for (int i = 0; i < _users.size(); ++i) {
- User existingUser = _users.get(i);
- if (Objects.equals(existingUser.getId(), id)) {
- _users.set(i, userUpdate);
- return new UserResult.Success();
- }
- }
-
- return new UserResult.UserUpdateError("User update failed ");
- }
-
- /**
- * Удаляет пользователя по его идентификатору.
- *
- * @param id идентификатор пользователя, которого нужно удалить.
- * @return результат операции удаления, может быть ошибка, если параметры удаления неверны.
- */
- @Override
- public UserResult DeleteUser(Integer id) {
- if (id < 0) {
- return new UserResult.UserDeletionError("Invalid delete parameters");
- }
- _users.removeIf(user -> Objects.equals(user.getId(), id));
- return new UserResult.Success();
- }
-}
diff --git a/DataAccess/src/main/java/Services/BankAccountService.java b/DataAccess/src/main/java/Services/BankAccountService.java
new file mode 100644
index 0000000..fe291f0
--- /dev/null
+++ b/DataAccess/src/main/java/Services/BankAccountService.java
@@ -0,0 +1,42 @@
+package Services;
+
+import Application.Models.Entities.BankAccount;
+import DAO.HibernateBankAccountDAO;
+import Services.Interfaces.IBankAccountService;
+
+public class BankAccountService implements IBankAccountService {
+ private final HibernateBankAccountDAO BankAccountDAO;
+
+ public BankAccountService(HibernateBankAccountDAO bankAccountDAO) {
+ BankAccountDAO = bankAccountDAO;
+ }
+ @Override
+ public BankAccount GetAccount(int id) {
+ return BankAccountDAO.GetBankAccountByID(id);
+ }
+
+ @Override
+ public void UpdateAccount(BankAccount account) {
+ BankAccountDAO.SaveBankAccount(account);
+ }
+
+ @Override
+ public void DeleteAccount(BankAccount account) {
+ BankAccountDAO.DeleteBankAccount(account);
+ }
+
+ @Override
+ public boolean Deposit(int accountId, double amount) {
+ return BankAccountDAO.Deposit(accountId, amount);
+ }
+
+ @Override
+ public boolean Withdraw(int accountId, double amount) {
+ return BankAccountDAO.Withdraw(accountId, amount);
+ }
+
+ @Override
+ public boolean Transfer(int accountFromId, int accountToId, double amount) {
+ return BankAccountDAO.Transfer(accountFromId, accountToId, amount);
+ }
+}
diff --git a/DataAccess/src/main/java/Services/Interfaces/IBankAccountService.java b/DataAccess/src/main/java/Services/Interfaces/IBankAccountService.java
new file mode 100644
index 0000000..eac5e81
--- /dev/null
+++ b/DataAccess/src/main/java/Services/Interfaces/IBankAccountService.java
@@ -0,0 +1,12 @@
+package Services.Interfaces;
+
+import Application.Models.Entities.BankAccount;
+
+public interface IBankAccountService {
+ BankAccount GetAccount(int id);
+ void UpdateAccount(BankAccount account);
+ void DeleteAccount(BankAccount account);
+ boolean Deposit(int accountId, double amount);
+ boolean Withdraw(int accountId, double amount);
+ boolean Transfer(int accountFromId, int accountToId, double amount);
+}
diff --git a/DataAccess/src/main/java/Services/Interfaces/IOperationService.java b/DataAccess/src/main/java/Services/Interfaces/IOperationService.java
new file mode 100644
index 0000000..f86fd3e
--- /dev/null
+++ b/DataAccess/src/main/java/Services/Interfaces/IOperationService.java
@@ -0,0 +1,12 @@
+package Services.Interfaces;
+
+import Application.Models.Entities.Operation;
+
+import java.util.List;
+
+public interface IOperationService {
+ Operation GetOperation(int id);
+ void SaveOperation(Operation operation);
+ void DeleteOperation(Operation operation);
+ List FindAllOperationsByAccountId(int id);
+}
diff --git a/DataAccess/src/main/java/Services/Interfaces/IUserService.java b/DataAccess/src/main/java/Services/Interfaces/IUserService.java
new file mode 100644
index 0000000..54e8164
--- /dev/null
+++ b/DataAccess/src/main/java/Services/Interfaces/IUserService.java
@@ -0,0 +1,9 @@
+package Services.Interfaces;
+
+import Application.Models.Entities.User;
+
+public interface IUserService {
+ User GetUser(int id);
+ void SaveUser(User user);
+ void DeleteUser(User user);
+}
diff --git a/DataAccess/src/main/java/Services/OperationService.java b/DataAccess/src/main/java/Services/OperationService.java
new file mode 100644
index 0000000..f2920a1
--- /dev/null
+++ b/DataAccess/src/main/java/Services/OperationService.java
@@ -0,0 +1,35 @@
+package Services;
+
+import Application.Models.Entities.Operation;
+import DAO.HibernateOperationDAO;
+import Services.Interfaces.IOperationService;
+
+import java.util.List;
+
+public class OperationService implements IOperationService {
+ private final HibernateOperationDAO OperationDAO;
+
+ public OperationService(HibernateOperationDAO operationDAO) {
+ OperationDAO = operationDAO;
+ }
+
+ @Override
+ public Operation GetOperation(int id) {
+ return OperationDAO.GetOperationById(id);
+ }
+
+ @Override
+ public void SaveOperation(Operation operation) {
+ OperationDAO.SaveOperation(operation);
+ }
+
+ @Override
+ public void DeleteOperation(Operation operation) {
+ OperationDAO.DeleteOperation(operation);
+ }
+
+ @Override
+ public List FindAllOperationsByAccountId(int id) {
+ return OperationDAO.FindAllOperationsByAccountId(id);
+ }
+}
diff --git a/DataAccess/src/main/java/Services/UserService.java b/DataAccess/src/main/java/Services/UserService.java
new file mode 100644
index 0000000..2339ea4
--- /dev/null
+++ b/DataAccess/src/main/java/Services/UserService.java
@@ -0,0 +1,28 @@
+package Services;
+
+import Application.Models.Entities.User;
+import DAO.HibernateUserDAO;
+import Services.Interfaces.IUserService;
+
+public class UserService implements IUserService {
+ private final HibernateUserDAO UserDAO;
+
+ public UserService(HibernateUserDAO userDAO) {
+ UserDAO = userDAO;
+ }
+
+ @Override
+ public User GetUser(int id) {
+ return UserDAO.FindUserById(id);
+ }
+
+ @Override
+ public void SaveUser(User user) {
+ UserDAO.SaveUser(user);
+ }
+
+ @Override
+ public void DeleteUser(User user) {
+ UserDAO.DeleteUser(user);
+ }
+}
diff --git a/DataAccess/src/main/java/Utils/HibernateSessionFactoryUtil.java b/DataAccess/src/main/java/Utils/HibernateSessionFactoryUtil.java
new file mode 100644
index 0000000..230c5e8
--- /dev/null
+++ b/DataAccess/src/main/java/Utils/HibernateSessionFactoryUtil.java
@@ -0,0 +1,35 @@
+package Utils;
+
+import Application.Models.Entities.BankAccount;
+import Application.Models.Entities.Operation;
+import Application.Models.Entities.User;
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Configuration;
+
+
+public class HibernateSessionFactoryUtil {
+ private static SessionFactory SessionFactory;
+
+ private HibernateSessionFactoryUtil() {}
+
+ public static SessionFactory GetSessionFactory() {
+ if (SessionFactory == null) {
+ try {
+ Configuration config = new Configuration().configure();
+
+ config.addAnnotatedClass(User.class);
+ config.addAnnotatedClass(BankAccount.class);
+ config.addAnnotatedClass(Operation.class);
+ StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
+ .applySettings(config.getProperties());
+
+ SessionFactory = config.buildSessionFactory(builder.build());
+ } catch (Exception e) {
+ System.out.println("Error in getSessionFactory: " + e.getMessage());
+ throw new RuntimeException("Failed to create sessionFactory", e);
+ }
+ }
+ return SessionFactory;
+ }
+}
diff --git a/DataAccess/src/main/resources/hibernate.cfg.xml b/DataAccess/src/main/resources/hibernate.cfg.xml
new file mode 100644
index 0000000..99e6283
--- /dev/null
+++ b/DataAccess/src/main/resources/hibernate.cfg.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+ org.postgresql.Driver
+ jdbc:postgresql://localhost:5432/JavaLabsDb
+ postgres
+ limosha
+
+
+ org.hibernate.dialect.PostgreSQLDialect
+
+
+ true
+ true
+
+ create-drop
+
+
+
+
+
+
+
diff --git a/Presentation/src/main/java/Presentation/Console/Main.java b/Presentation/src/main/java/Presentation/Console/Main.java
index 5047091..5487063 100644
--- a/Presentation/src/main/java/Presentation/Console/Main.java
+++ b/Presentation/src/main/java/Presentation/Console/Main.java
@@ -2,9 +2,12 @@
import Presentation.Interfaces.IMenu;
+import org.flywaydb.core.Flyway;
public class Main {
public static void main(String[] args) {
+ Flyway flyway = Flyway.configure().dataSource("jdbc:postgresql://localhost:5432/JavaLabsDb", "postgres", "limosha").load();
+ flyway.migrate();
IMenu menu = new Menu();
menu.Run();
}
diff --git a/Presentation/src/main/java/Presentation/Console/Menu.java b/Presentation/src/main/java/Presentation/Console/Menu.java
index ed7ce7f..ecda47b 100644
--- a/Presentation/src/main/java/Presentation/Console/Menu.java
+++ b/Presentation/src/main/java/Presentation/Console/Menu.java
@@ -1,19 +1,26 @@
package Presentation.Console;
-import Application.Contracts.ResultTypes.BankAccountResult;
-import Application.Contracts.ResultTypes.OperationResult;
-import Application.Contracts.ResultTypes.UserResult;
+import Application.Models.Entities.Operation;
+import Application.ResultTypes.BankAccountResult;
+import Application.ResultTypes.OperationResult;
+import Application.ResultTypes.UserResult;
import Application.Managers.UserManager;
-import Application.Models.Entites.BankAccount;
-import Application.Models.Entites.User;
+import Application.Models.Entities.BankAccount;
+import Application.Models.Entities.User;
import Application.Models.Enums.HairColor;
import Application.Models.Enums.Sex;
-import Application.Models.Utils.IdGenerator;
-import Application.Services.UserService;
+import DAO.HibernateBankAccountDAO;
+import DAO.HibernateOperationDAO;
+import DAO.HibernateUserDAO;
+import Presentation.Controllers.UserController;
+import Services.BankAccountService;
+import Services.OperationService;
+import Services.UserService;
import Presentation.Interfaces.IMenu;
-import DataAccess.BankAccountRepository;
-import DataAccess.OperationRepository;
-import DataAccess.UserRepository;
+import Utils.HibernateSessionFactoryUtil;
+import org.hibernate.Hibernate;
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.Configuration;
import java.util.Scanner;
@@ -46,13 +53,13 @@
*/
public class Menu implements IMenu {
- private final IdGenerator userIdGenerator = new IdGenerator();
- private final IdGenerator bankAccountIdGenerator = new IdGenerator();
- private final UserService userService = new UserService(
- new UserRepository(),
- new BankAccountRepository(),
- new OperationRepository(),
- new UserManager());
+ private final SessionFactory sf = HibernateSessionFactoryUtil.GetSessionFactory();
+ private final UserController controller = new UserController(
+ new UserManager(), new UserService(new HibernateUserDAO(sf)),
+ new BankAccountService(new HibernateBankAccountDAO(sf)),
+ new OperationService(new HibernateOperationDAO(sf))
+ );
+
private final Scanner scanner = new Scanner(System.in);
@@ -101,28 +108,49 @@ public void Run() {
*/
private void createUser() {
System.out.print("Введите логин: ");
- String login = scanner.nextLine();
+ String login = scanner.nextLine().trim();
+ if (login.isEmpty()) {
+ System.out.println("Логин не может быть пустым!");
+ return;
+ }
+
System.out.print("Введите имя: ");
- String name = scanner.nextLine();
- System.out.print("Введите возраст: ");
- int age = scanner.nextInt();
- scanner.nextLine();
+ String name = scanner.nextLine().trim();
+ if (name.isEmpty()) {
+ System.out.println("Имя не может быть пустым!");
+ return;
+ }
+ System.out.print("Введите возраст: ");
+ int age;
+ try {
+ age = Integer.parseInt(scanner.nextLine().trim());
+ if (age <= 0) {
+ System.out.println("Возраст должен быть положительным числом!");
+ return;
+ }
+ } catch (NumberFormatException e) {
+ System.out.println("Неверный формат возраста. Введите число.");
+ return;
+ }
System.out.println("Выберите пол:");
System.out.println("1. Мужской");
System.out.println("2. Женский");
System.out.println("3. Неопределённый");
System.out.print("Введите цифру (1-3): ");
- int sexChoice = scanner.nextInt();
- scanner.nextLine();
-
- Sex sex = switch (sexChoice) {
- case 1 -> Sex.Male;
- case 2 -> Sex.Female;
- default -> Sex.Undefined;
- };
-
+ Sex sex;
+ try {
+ int sexChoice = Integer.parseInt(scanner.nextLine().trim());
+ sex = switch (sexChoice) {
+ case 1 -> Sex.Male;
+ case 2 -> Sex.Female;
+ default -> Sex.Undefined;
+ };
+ } catch (NumberFormatException e) {
+ System.out.println("Неверный выбор пола. Введите число от 1 до 3.");
+ return;
+ }
System.out.println("Выберите цвет волос:");
System.out.println("1. Блонд");
@@ -136,26 +164,36 @@ private void createUser() {
System.out.println("9. Белый");
System.out.println("10. Лысый");
System.out.print("Введите цифру (1-10): ");
- int hairChoice = scanner.nextInt();
- scanner.nextLine();
-
- HairColor hairColor = switch (hairChoice) {
- case 1 -> HairColor.Blond;
- case 2 -> HairColor.Ash;
- case 3 -> HairColor.Brown;
- case 4 -> HairColor.Auburn;
- case 5 -> HairColor.Black;
- case 6 -> HairColor.Dyed;
- case 7 -> HairColor.Colored;
- case 8 -> HairColor.Grey;
- case 9 -> HairColor.White;
- default -> HairColor.Bold;
- };
-
- User user = new User(userIdGenerator, login, name, age, sex, hairColor);
- UserResult result = userService.CreateUser(user);
-
- System.out.println(result instanceof UserResult.Success ? "Пользователь создан!" : "Ошибка создания пользователя.");
+ HairColor hairColor;
+ try {
+ int hairChoice = Integer.parseInt(scanner.nextLine().trim());
+ hairColor = switch (hairChoice) {
+ case 1 -> HairColor.Blond;
+ case 2 -> HairColor.Ash;
+ case 3 -> HairColor.Brown;
+ case 4 -> HairColor.Auburn;
+ case 5 -> HairColor.Black;
+ case 6 -> HairColor.Dyed;
+ case 7 -> HairColor.Colored;
+ case 8 -> HairColor.Grey;
+ case 9 -> HairColor.White;
+ default -> HairColor.Bold;
+ };
+ } catch (NumberFormatException e) {
+ System.out.println("Неверный выбор цвета волос. Введите число от 1 до 10.");
+ return;
+ }
+
+ // Создаем пользователя без использования IdGenerator, так как ID генерируется базой данных
+ User user = new User(login, name, age, sex, hairColor);
+
+ // Вызываем метод создания пользователя через контроллер
+ UserResult result = controller.CreateUser(user);
+ if (result instanceof UserResult.Success) {
+ System.out.println("Пользователь создан!");
+ } else {
+ System.out.println("Ошибка создания пользователя.");
+ }
}
/**
@@ -164,12 +202,7 @@ private void createUser() {
private void getUserInfo() {
System.out.print("Введите ID пользователя: ");
int userId = scanner.nextInt();
- User user = userService.get_userRepository().FindUserById(userId);
- if (user != null) {
- userService.GetUserInfo(user);
- } else {
- System.out.println("Пользователь не найден.");
- }
+ controller.GetUserInfo(userId);
}
/**
@@ -180,19 +213,15 @@ private void manageFriends() {
int userId = scanner.nextInt();
System.out.print("Введите ID друга: ");
int friendId = scanner.nextInt();
-
- User user = userService.get_userRepository().FindUserById(userId);
- User friend = userService.get_userRepository().FindUserById(friendId);
-
- if (user != null && friend != null) {
+ if (userId > 0 && friendId > 0) {
System.out.print("Добавить друга (1) или удалить (2): ");
int action = scanner.nextInt();
if (action == 1) {
- userService.AddFriend(user, friend);
+ controller.AddFriend(userId, friendId);
System.out.println("Друг добавлен.");
} else if (action == 2) {
- userService.RemoveFriend(user, friend);
+ controller.RemoveFriend(userId, friendId);
System.out.println("Друг удален.");
} else {
System.out.println("Неверная команда.");
@@ -208,18 +237,14 @@ private void manageFriends() {
private void createBankAccount() {
System.out.print("Введите ID пользователя: ");
int userId = scanner.nextInt();
-
- User user = userService.get_userRepository().FindUserById(userId);
+ User user = controller.GetUserById(userId);
if (user == null) {
- System.out.println("Пользователь не найден.");
+ System.out.println("Пользователь с ID " + userId + " не найден.");
return;
}
- System.out.println("Найден пользователь: " + user.getName() + " (ID: " + user.getId() + ")");
-
- BankAccount account = new BankAccount(bankAccountIdGenerator, user);
- BankAccountResult result = userService.addBankAccount(user, account);
-
+ BankAccount account = new BankAccount(user);
+ BankAccountResult result = controller.addBankAccount(userId, account);
if (result instanceof BankAccountResult.Success) {
System.out.println("Счет создан!");
} else {
@@ -233,18 +258,14 @@ private void createBankAccount() {
private void checkBalance() {
System.out.print("Введите ID счета: ");
int accountId = scanner.nextInt();
- BankAccount account = userService.get_bankAccountRepository().FindBankAccountById(accountId);
+ BankAccount account = controller.GetBankAccountById(accountId);
- if (account != null) {
- User user = userService.get_userRepository().FindUserById(account.getUserId());
- if (user != null) {
- userService.CheckBalance(user, account);
- } else {
- System.out.println("Пользователь не найден.");
- }
- } else {
+ if (account == null) {
System.out.println("Счет не найден.");
+ return;
}
+
+ controller.CheckBalance(account.getUser().getId(), accountId);
}
/**
@@ -256,9 +277,9 @@ private void withdraw() {
System.out.print("Введите сумму снятия: ");
double amount = scanner.nextDouble();
- BankAccount account = userService.get_bankAccountRepository().FindBankAccountById(accountId);
+ BankAccount account = controller.GetBankAccountById(accountId);
if (account != null) {
- OperationResult result = userService.Withdraw(account, amount);
+ OperationResult result = controller.Withdraw(account, amount);
if (result instanceof OperationResult.Success) {
System.out.println("Деньги сняты.");
@@ -279,9 +300,9 @@ private void deposit() {
System.out.print("Введите сумму пополнения: ");
double amount = scanner.nextDouble();
- BankAccount account = userService.get_bankAccountRepository().FindBankAccountById(accountId);
+ BankAccount account = controller.GetBankAccountById(accountId);
if (account != null) {
- OperationResult result = userService.Deposit(account, amount);
+ OperationResult result = controller.Deposit(account, amount);
if (result instanceof OperationResult.Success) {
System.out.println("Счет пополнен.");
} else if (result instanceof OperationResult.OperationError error) {
@@ -306,11 +327,11 @@ private void transfer() {
System.out.print("Введите сумму перевода: ");
double amount = Double.parseDouble(scanner.nextLine().trim().replace(',', '.'));
- BankAccount fromAccount = userService.get_bankAccountRepository().FindBankAccountById(fromId);
- BankAccount toAccount = userService.get_bankAccountRepository().FindBankAccountById(toId);
+ BankAccount fromAccount = controller.GetBankAccountById(fromId);
+ BankAccount toAccount = controller.GetBankAccountById(toId);
if (fromAccount != null && toAccount != null) {
- OperationResult result = userService.Transfer(fromAccount, toAccount, amount);
+ OperationResult result = controller.Transfer(fromAccount, toAccount, amount);
if (result instanceof OperationResult.Success) {
System.out.println("Перевод выполнен.");
} else if (result instanceof OperationResult.OperationError error) {
diff --git a/Presentation/src/main/java/Presentation/Controllers/UserController.java b/Presentation/src/main/java/Presentation/Controllers/UserController.java
new file mode 100644
index 0000000..74bee86
--- /dev/null
+++ b/Presentation/src/main/java/Presentation/Controllers/UserController.java
@@ -0,0 +1,191 @@
+package Presentation.Controllers;
+
+import Application.Managers.UserManager;
+import Application.Models.Entities.BankAccount;
+import Application.Models.Entities.Operation;
+import Application.Models.Entities.User;
+import Application.Models.Enums.OperationType;
+import Application.ResultTypes.BankAccountResult;
+import Application.ResultTypes.OperationResult;
+import Application.ResultTypes.UserResult;
+import Presentation.Interfaces.IUserController;
+import Services.BankAccountService;
+import Services.OperationService;
+import Services.UserService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UserController implements IUserController {
+ private final UserManager UserManager;
+ private final UserService UserService;
+ private final BankAccountService BankAccountService;
+ private final OperationService OperationService;
+
+ public UserController(UserManager userManager, UserService userService, BankAccountService bankAccountService, OperationService operationService) {
+ UserManager = userManager;
+ UserService = userService;
+ BankAccountService = bankAccountService;
+ OperationService = operationService;
+ }
+
+ @Override
+ public UserResult CreateUser(User user) {
+ if (user == null || user.getLogin() == null || user.getName() == null) {
+ return new UserResult.UserCreationError("Некорректные данные пользователя");
+ }
+ UserService.SaveUser(user);
+ return new UserResult.Success();
+ }
+
+ @Override
+ public User GetUserById(int id) {
+ try {
+ return UserService.GetUser(id);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ public BankAccount GetBankAccountById(int id) {
+ try {
+ return BankAccountService.GetAccount(id);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ public UserResult DeleteUser(User user) {
+ try {
+ UserService.DeleteUser(user);
+ return new UserResult.Success();
+ } catch (Exception e) {
+ return new UserResult.UserDeletionError(e.getMessage());
+ }
+ }
+
+ @Override
+ public void GetUserInfo(int id) {
+ UserManager.GetUserInfo(UserService.GetUser(id));
+ }
+
+ @Override
+ public void AddFriend(int userId, int otherId) {
+ User user1 = UserService.GetUser(userId);
+ User user2 = UserService.GetUser(otherId);
+ UserManager.AddFriend(user1, user2);
+ UserService.SaveUser(user1);
+ UserService.SaveUser(user2);
+ }
+
+ @Override
+ public void RemoveFriend(int userId, int otherId) {
+ User user1 = UserService.GetUser(userId);
+ User user2 = UserService.GetUser(otherId);
+ UserManager.RemoveFriend(user1, user2);
+ UserService.SaveUser(user1);
+ UserService.SaveUser(user2);
+ }
+
+ @Override
+ public BankAccountResult addBankAccount(int userId, BankAccount bankAccount) {
+ try {
+ User user = UserService.GetUser(userId);
+ UserManager.AddBankAccount(user, bankAccount);
+ UserService.SaveUser(user);
+ BankAccountService.UpdateAccount(bankAccount);
+ return new BankAccountResult.Success();
+ } catch (Exception e) {
+ return new BankAccountResult.BankAccountCreationError(e.getMessage());
+ }
+ }
+
+ @Override
+ public BankAccountResult RemoveBankAccount(int userId, BankAccount bankAccount) {
+ try {
+ User user = UserService.GetUser(userId);
+ UserManager.RemoveBankAccount(user, bankAccount);
+ UserService.SaveUser(user);
+ BankAccountService.UpdateAccount(bankAccount);
+ return new BankAccountResult.Success();
+ } catch (Exception e) {
+ return new BankAccountResult.BankAccountDeletionError(e.getMessage());
+ }
+ }
+
+ @Override
+ public OperationResult CheckBalance(int userId, int accountId) {
+ BankAccount account = BankAccountService.GetAccount(accountId);
+ if (account == null || account.getUser().getId() != userId) {
+ return new OperationResult.OperationError("Счет не найден или принадлежит другому пользователю.");
+ }
+ System.out.println("Баланс счета: " + account.getBalance());
+ return new OperationResult.Success();
+ }
+
+ @Override
+ public OperationResult Deposit(BankAccount bankAccount, Double amount) {
+ try {
+ BankAccountService.Deposit(bankAccount.getId(), amount);
+ OperationService.SaveOperation(new Operation(bankAccount, OperationType.Deposit, amount));
+ return new OperationResult.Success();
+ } catch (Exception e) {
+ return new OperationResult.OperationError(e.getMessage());
+ }
+ }
+
+ @Override
+ public OperationResult Withdraw(BankAccount bankAccount, Double amount) {
+ try {
+ boolean success = BankAccountService.Withdraw(bankAccount.getId(), amount);
+ if (!success) {
+ return new OperationResult.OperationError("Not enough balance.");
+ }
+ OperationService.SaveOperation(new Operation(bankAccount, OperationType.Withdraw, amount));
+ return new OperationResult.Success();
+ } catch (Exception e) {
+ return new OperationResult.OperationError(e.getMessage());
+ }
+ }
+
+ @Override
+ public OperationResult Transfer(BankAccount bankAccount1, BankAccount bankAccount2, Double amount) {
+ try {
+ User user1 = UserService.GetUser(bankAccount1.getUser().getId());
+ User user2 = UserService.GetUser(bankAccount2.getUser().getId());
+
+ double commissionRate = user1.getId().equals(user2.getId()) ? 0.00
+ : user1.getFriends().stream().anyMatch(f -> f.getId().equals(user2.getId())) ? 0.03
+ : 0.10;
+ double commission = amount * commissionRate;
+ double totalAmount = amount + commission;
+
+ boolean success = BankAccountService.Transfer(bankAccount1.getId(), bankAccount2.getId(), totalAmount);
+ if (!success) {
+ return new OperationResult.OperationError("Insufficient funds, including commission.");
+ }
+
+ OperationService.SaveOperation(new Operation(bankAccount1, OperationType.Transfer, totalAmount));
+ OperationService.SaveOperation(new Operation(bankAccount2, OperationType.Deposit, amount));
+
+ return new OperationResult.Success();
+ } catch (Exception e) {
+ return new OperationResult.OperationError(e.getMessage());
+ }
+ }
+
+ @Override
+ public OperationResult GetOperationHistory(int bankAccountId) {
+ try {
+ BankAccount account = BankAccountService.GetAccount(bankAccountId);
+ List operations = OperationService.FindAllOperationsByAccountId(account.getId());
+ return UserManager.PrintHistory(account, operations);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new OperationResult.OperationError(e.getMessage());
+ }
+ }
+
+}
diff --git a/Application/src/main/java/Application/Contracts/Interfaces/IUserService.java b/Presentation/src/main/java/Presentation/Interfaces/IUserController.java
similarity index 59%
rename from Application/src/main/java/Application/Contracts/Interfaces/IUserService.java
rename to Presentation/src/main/java/Presentation/Interfaces/IUserController.java
index dac25eb..a59ac15 100644
--- a/Application/src/main/java/Application/Contracts/Interfaces/IUserService.java
+++ b/Presentation/src/main/java/Presentation/Interfaces/IUserController.java
@@ -1,17 +1,17 @@
-package Application.Contracts.Interfaces;
+package Presentation.Interfaces;
-import Application.Contracts.ResultTypes.BankAccountResult;
-import Application.Contracts.ResultTypes.OperationResult;
-import Application.Contracts.ResultTypes.UserResult;
-import Application.Models.Entites.BankAccount;
-import Application.Models.Entites.User;
+import Application.ResultTypes.BankAccountResult;
+import Application.ResultTypes.OperationResult;
+import Application.ResultTypes.UserResult;
+import Application.Models.Entities.BankAccount;
+import Application.Models.Entities.User;
/**
* Интерфейс, предоставляющий операции для управления пользователями и их банковскими счетами.
* Включает методы для создания, удаления пользователей, управления их друзьями и банковскими счетами,
* а также выполнения различных операций с банковскими счетами.
*/
-public interface IUserService {
+public interface IUserController {
/**
* Создание нового пользователя.
@@ -21,6 +21,22 @@ public interface IUserService {
*/
UserResult CreateUser(User user);
+ /**
+ * Создание нового пользователя.
+ *
+ * @param id идентификатор пользователя, который должен быть найден.
+ * @return результат операции поиска пользователя.
+ */
+ User GetUserById(int id);
+
+ /**
+ * Создание нового пользователя.
+ *
+ * @param id идентификатор аккаунта, который должен быть найден.
+ * @return результат операции поиска аккаунта.
+ */
+ BankAccount GetBankAccountById(int id);
+
/**
* Удаление пользователя.
*
@@ -32,52 +48,52 @@ public interface IUserService {
/**
* Получение информации о пользователе.
*
- * @param user объект пользователя, информацию о котором необходимо получить.
+ * @param id идентификатор пользователя, информацию о котором необходимо получить.
*/
- void GetUserInfo(User user);
+ void GetUserInfo(int id);
/**
* Добавление пользователя в друзья.
*
- * @param user объект текущего пользователя.
- * @param other объект пользователя, которого нужно добавить в друзья.
+ * @param userId идентификатор текущего пользователя.
+ * @param otherId идентификатор пользователя, которого нужно добавить в друзья.
*/
- void AddFriend(User user, User other);
+ void AddFriend(int userId, int otherId);
/**
* Удаление пользователя из списка друзей.
*
- * @param user объект текущего пользователя.
- * @param other объект пользователя, которого нужно удалить из друзей.
+ * @param userId идентификатор текущего пользователя.
+ * @param otherId идентификатор пользователя, которого нужно удалить из друзей.
*/
- void RemoveFriend(User user, User other);
+ void RemoveFriend(int userId, int otherId);
/**
* Добавление нового банковского счета пользователю.
*
- * @param user объект пользователя, которому нужно добавить банковский счет.
+ * @param userId идентификатор пользователя, которому нужно добавить банковский счет.
* @param bankAccount объект банковского счета, который нужно добавить.
* @return результат операции добавления банковского счета.
*/
- BankAccountResult addBankAccount(User user, BankAccount bankAccount);
+ BankAccountResult addBankAccount(int userId, BankAccount bankAccount);
/**
* Удаление банковского счета пользователя.
*
- * @param user объект пользователя, чей банковский счет должен быть удален.
+ * @param userId идентификатор пользователя, чей банковский счет должен быть удален.
* @param bankAccount объект банковского счета, который нужно удалить.
* @return результат операции удаления банковского счета.
*/
- BankAccountResult RemoveBankAccount(User user, BankAccount bankAccount);
+ BankAccountResult RemoveBankAccount(int userId, BankAccount bankAccount);
/**
* Проверка баланса банковского счета пользователя.
*
- * @param user объект пользователя, чей баланс нужно проверить.
- * @param bankAccount объект банковского счета, баланс которого нужно проверить.
+ * @param userId идентификатор пользователя, чей баланс нужно проверить.
+ * @param bankAccountId объект банковского счета, баланс которого нужно проверить.
* @return результат операции проверки баланса.
*/
- OperationResult CheckBalance(User user, BankAccount bankAccount);
+ OperationResult CheckBalance(int userId, int bankAccountId);
/**
* Пополнение банковского счета.
@@ -110,8 +126,8 @@ public interface IUserService {
/**
* Получение истории операций для конкретного банковского счета.
*
- * @param bankAccount объект банковского счета, для которого нужно получить историю операций.
+ * @param bankAccountId идентификатор банковского счета, для которого нужно получить историю операций.
* @return результат операции получения истории.
*/
- OperationResult GetOperationHistory(BankAccount bankAccount);
+ OperationResult GetOperationHistory(int bankAccountId);
}
diff --git a/Presentation/src/main/resources/application.yml b/Presentation/src/main/resources/application.yml
new file mode 100644
index 0000000..204317a
--- /dev/null
+++ b/Presentation/src/main/resources/application.yml
@@ -0,0 +1,9 @@
+spring:
+ datasource:
+ url: jdbc:postgresql://localhost:5432/JavaLabsDb
+ username: postgres
+ password: limosha
+ flyway:
+ enabled: true
+ locations: classpath:db/migration
+ baseline-on-migrate: true
\ No newline at end of file
diff --git a/Presentation/src/main/resources/db/migration/V1__init.sql b/Presentation/src/main/resources/db/migration/V1__init.sql
new file mode 100644
index 0000000..26dd68f
--- /dev/null
+++ b/Presentation/src/main/resources/db/migration/V1__init.sql
@@ -0,0 +1,32 @@
+CREATE TABLE Users
+(
+ id SERIAL PRIMARY KEY,
+ login VARCHAR(255) UNIQUE NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ age INT NOT NULL,
+ sex VARCHAR(255) NOT NULL,
+ hairColor VARCHAR(255)
+);
+
+CREATE TABLE BankAccounts
+(
+ id SERIAL PRIMARY KEY,
+ balance DOUBLE PRECISION NOT NULL,
+ userLogin VARCHAR(255) NOT NULL,
+ userId INT NOT NULL REFERENCES Users (id)
+);
+
+CREATE TABLE Operations
+(
+ id SERIAL PRIMARY KEY,
+ accountId INT NOT NULL REFERENCES BankAccounts (id),
+ type VARCHAR(255) NOT NULL,
+ amount DOUBLE PRECISION NOT NULL
+);
+
+CREATE TABLE Friends
+(
+ userId INT NOT NULL REFERENCES Users (id),
+ friendId INT NOT NULL REFERENCES Users (id),
+ PRIMARY KEY (userId, friendId)
+);
\ No newline at end of file
diff --git a/Presentation/src/main/resources/db/migration/V2__drop_tables.sql b/Presentation/src/main/resources/db/migration/V2__drop_tables.sql
new file mode 100644
index 0000000..ea5d75d
--- /dev/null
+++ b/Presentation/src/main/resources/db/migration/V2__drop_tables.sql
@@ -0,0 +1,4 @@
+DROP TABLE Friends;
+DROP TABLE Operations;
+DROP TABLE BankAccounts;
+DROP TABLE Users;
diff --git a/Presentation/src/main/resources/db/migration/V3__init.sql b/Presentation/src/main/resources/db/migration/V3__init.sql
new file mode 100644
index 0000000..01d855f
--- /dev/null
+++ b/Presentation/src/main/resources/db/migration/V3__init.sql
@@ -0,0 +1,56 @@
+CREATE SEQUENCE IF NOT EXISTS bankaccounts_id_seq START WITH 1 INCREMENT BY 1;
+
+CREATE SEQUENCE IF NOT EXISTS operations_id_seq START WITH 1 INCREMENT BY 1;
+
+CREATE SEQUENCE IF NOT EXISTS users_id_seq START WITH 1 INCREMENT BY 1;
+
+CREATE TABLE bankaccounts
+(
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
+ balance DOUBLE PRECISION NOT NULL,
+ userlogin VARCHAR(255) NOT NULL,
+ userid INTEGER NOT NULL,
+ CONSTRAINT bankaccounts_pkey PRIMARY KEY (id)
+);
+
+CREATE TABLE friends
+(
+ userid INTEGER NOT NULL,
+ friendid INTEGER NOT NULL,
+ CONSTRAINT friends_pkey PRIMARY KEY (userid, friendid)
+);
+
+CREATE TABLE operations
+(
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
+ accountid INTEGER NOT NULL,
+ type VARCHAR(255) NOT NULL,
+ amount DOUBLE PRECISION NOT NULL,
+ CONSTRAINT operations_pkey PRIMARY KEY (id)
+);
+
+CREATE TABLE users
+(
+ id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
+ login VARCHAR(255) NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ age INTEGER NOT NULL,
+ sex VARCHAR(255) NOT NULL,
+ haircolor VARCHAR(255),
+ CONSTRAINT users_pkey PRIMARY KEY (id)
+);
+
+ALTER TABLE users
+ ADD CONSTRAINT users_login_key UNIQUE (login);
+
+ALTER TABLE bankaccounts
+ ADD CONSTRAINT bankaccounts_userid_fkey FOREIGN KEY (userid) REFERENCES users (id) ON DELETE NO ACTION;
+
+ALTER TABLE friends
+ ADD CONSTRAINT friends_friendid_fkey FOREIGN KEY (friendid) REFERENCES users (id) ON DELETE NO ACTION;
+
+ALTER TABLE friends
+ ADD CONSTRAINT friends_userid_fkey FOREIGN KEY (userid) REFERENCES users (id) ON DELETE NO ACTION;
+
+ALTER TABLE operations
+ ADD CONSTRAINT operations_accountid_fkey FOREIGN KEY (accountid) REFERENCES bankaccounts (id) ON DELETE NO ACTION;
\ No newline at end of file
diff --git a/Presentation/src/test/java/BankTests.java b/Presentation/src/test/java/BankTests.java
index 586778f..a1b0b16 100644
--- a/Presentation/src/test/java/BankTests.java
+++ b/Presentation/src/test/java/BankTests.java
@@ -1,12 +1,13 @@
-import Application.Abstractions.Repositories.IBankAccountRepository;
-import Application.Abstractions.Repositories.IOperationRepository;
-import Application.Contracts.ResultTypes.OperationResult;
-import Application.Models.Entites.BankAccount;
-import Application.Models.Entites.User;
+import Application.Managers.UserManager;
+import Application.ResultTypes.OperationResult;
+import Application.Models.Entities.BankAccount;
+import Application.Models.Entities.User;
import Application.Models.Enums.HairColor;
import Application.Models.Enums.Sex;
-import Application.Models.Utils.IdGenerator;
-import Application.Services.UserService;
+import Presentation.Controllers.UserController;
+import Services.BankAccountService;
+import Services.OperationService;
+import Services.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
@@ -20,83 +21,68 @@
public class BankTests {
@Mock
- private IBankAccountRepository bankAccountRepository;
+ private UserManager userManager;
@Mock
- private IOperationRepository operationRepository;
+ private UserService userService;
+
+ @Mock
+ private BankAccountService bankAccountService;
+
+ @Mock
+ private OperationService operationService;
@InjectMocks
- private UserService userService;
+ private UserController userController;
private BankAccount bankAccount;
+ private User user;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
- User user = new User(new IdGenerator(), "lim0sha", "Sasha", 22, Sex.Male, HairColor.Brown);
- bankAccount = new BankAccount(new IdGenerator(), user);
+ user = new User("lim0sha", "Sasha", 22, Sex.Male, HairColor.Brown);
+ bankAccount = new BankAccount(user);
+ bankAccount.setId(1);
bankAccount.setBalance(100.0);
}
@Test
void testWithdrawWithSufficientBalance() {
- Double withdrawAmount = 50.0;
- Double initialBalance = bankAccount.getBalance();
+ double withdrawAmount = 50.0;
+ when(bankAccountService.Withdraw(bankAccount.getId(), withdrawAmount)).thenReturn(true);
+ doNothing().when(operationService).SaveOperation(any());
- when(bankAccountRepository.FindBankAccountById(bankAccount.getId())).thenReturn(bankAccount);
- when(bankAccountRepository.UpdateBankAccountBalance(bankAccount.getId(), initialBalance - withdrawAmount))
- .thenAnswer(invocation -> {
- bankAccount.setBalance(initialBalance - withdrawAmount);
- return null;
- });
- when(operationRepository.AddOperation(any())).thenReturn(new OperationResult.Success());
-
- OperationResult operationResult = userService.Withdraw(bankAccount, withdrawAmount);
+ OperationResult operationResult = userController.Withdraw(bankAccount, withdrawAmount);
assertInstanceOf(OperationResult.Success.class, operationResult);
- assertEquals(initialBalance - withdrawAmount, bankAccount.getBalance(), 0.001);
- verify(bankAccountRepository, times(1)).UpdateBankAccountBalance(bankAccount.getId(), initialBalance - withdrawAmount);
- verify(operationRepository, times(1)).AddOperation(any());
-
- assertEquals(50.0, bankAccount.getBalance(), 0.001);
+ verify(bankAccountService, times(1)).Withdraw(bankAccount.getId(), withdrawAmount);
+ verify(operationService, times(1)).SaveOperation(any());
}
@Test
void testWithdrawWithInsufficientBalance() {
- Double withdrawAmount = 150.0;
-
- when(bankAccountRepository.FindBankAccountById(bankAccount.getId())).thenReturn(bankAccount);
+ double withdrawAmount = 150.0;
+ when(bankAccountService.Withdraw(bankAccount.getId(), withdrawAmount)).thenReturn(false);
- OperationResult operationResult = userService.Withdraw(bankAccount, withdrawAmount);
+ OperationResult operationResult = userController.Withdraw(bankAccount, withdrawAmount);
assertInstanceOf(OperationResult.OperationError.class, operationResult);
- assertEquals("Not enough balance", ((OperationResult.OperationError) operationResult).getMessage());
- verify(bankAccountRepository, times(0)).UpdateBankAccountBalance(any(), anyDouble());
- verify(operationRepository, times(0)).AddOperation(any());
-
- assertEquals(100.0, bankAccount.getBalance(), 0.001);
+ assertEquals("Not enough balance.", ((OperationResult.OperationError) operationResult).getMessage());
+ verify(bankAccountService, times(1)).Withdraw(bankAccount.getId(), withdrawAmount);
+ verify(operationService, times(0)).SaveOperation(any()); // SaveOperation не должен вызываться
}
@Test
void testDeposit() {
- Double depositAmount = 100.0;
- Double initialBalance = bankAccount.getBalance();
-
- when(bankAccountRepository.FindBankAccountById(bankAccount.getId())).thenReturn(bankAccount);
- when(bankAccountRepository.UpdateBankAccountBalance(bankAccount.getId(), initialBalance + depositAmount))
- .thenAnswer(invocation -> {
- bankAccount.setBalance(initialBalance + depositAmount);
- return null;
- });
- when(operationRepository.AddOperation(any())).thenReturn(new OperationResult.Success());
+ double depositAmount = 100.0;
+ when(bankAccountService.Deposit(bankAccount.getId(), depositAmount)).thenReturn(true);
+ doNothing().when(operationService).SaveOperation(any());
- OperationResult operationResult = userService.Deposit(bankAccount, depositAmount);
+ OperationResult operationResult = userController.Deposit(bankAccount, depositAmount);
assertInstanceOf(OperationResult.Success.class, operationResult);
- assertEquals(initialBalance + depositAmount, bankAccount.getBalance(), 0.001);
- verify(bankAccountRepository, times(1)).UpdateBankAccountBalance(bankAccount.getId(), initialBalance + depositAmount);
- verify(operationRepository, times(1)).AddOperation(any());
-
- assertEquals(200.0, bankAccount.getBalance(), 0.001);
+ verify(bankAccountService, times(1)).Deposit(bankAccount.getId(), depositAmount);
+ verify(operationService, times(1)).SaveOperation(any());
}
}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 0223449..b718579 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,6 +7,39 @@
1.0-SNAPSHOT
pom
+
+
+ org.hibernate
+ hibernate-core
+ 6.4.4.Final
+
+
+
+ org.hibernate
+ hibernate-ehcache
+ 4.3.0.Beta3
+
+
+
+ org.postgresql
+ postgresql
+ 42.7.2
+
+
+
+ net.bytebuddy
+ byte-buddy
+ 1.14.7
+
+
+
+ org.flywaydb
+ flyway-core
+ 9.22.0
+
+
+
+
Application
DataAccess
@@ -28,6 +61,21 @@
+
+
+ org.flywaydb
+ flyway-maven-plugin
+ 9.22.0
+
+ jdbc:postgresql://localhost:5432/JavaLabsDb
+ postgres
+ limosha
+
+ classpath:db/migration
+
+ true
+
+
\ No newline at end of file