From 190396f29c75dac83b694a13b58a30b3019bd730 Mon Sep 17 00:00:00 2001 From: Dennis Selden <111012436+DennSel@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:35:14 +0100 Subject: [PATCH 1/4] Display book loan status @Linda @Erika @Linus @Dennis --- src/main/java/org/example/LoanServices.java | 2 +- src/main/java/org/example/SearchCli.java | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/example/LoanServices.java b/src/main/java/org/example/LoanServices.java index 567e34d4..2e5fb200 100644 --- a/src/main/java/org/example/LoanServices.java +++ b/src/main/java/org/example/LoanServices.java @@ -6,7 +6,7 @@ public class LoanServices { - final private EntityManager em; + private final EntityManager em; public LoanServices(EntityManager em) { this.em = em; diff --git a/src/main/java/org/example/SearchCli.java b/src/main/java/org/example/SearchCli.java index ba7aad57..b5a46552 100644 --- a/src/main/java/org/example/SearchCli.java +++ b/src/main/java/org/example/SearchCli.java @@ -104,23 +104,37 @@ private static void chooseAndShowBookDetails(Scanner sc, List results) { Book selected = results.get(n - 1); printBookDetails(selected); - System.out.print("Tryck Enter för att gå tillbaka til sök"); + System.out.print("Tryck Enter för att gå tillbaka till sök"); sc.nextLine(); return; } } private static void printBookDetails(Book b) { + LoanServices loanServices = new LoanServices(em); System.out.println("\n=============================="); System.out.println(" " + b.getTitle()); System.out.println("------------------------------"); System.out.println("Författare: " + formatAuthors(b)); System.out.println("Genre: " + formatGenres(b)); System.out.println("Utgiven: " + b.getPublishYear()); + System.out.println("Låna bok"); String desc = b.getDescription(); if (desc == null || desc.isBlank()) desc = "(Ingen beskrivning)"; System.out.println("\nBeskrivning:\n" + desc); + + if (loanServices.isBookLoaned(b.getId())){ + System.out.println("Status: Utlånad"); + } else { + System.out.println("Status: Tillgänglig"); + } + + //todo: + // Status på boken: tillgänglig/utlånad + // om tillgänglig och inloggad - låna bok + // om ej inloggad - skicka till logga in sidan. + System.out.println("=============================="); } From 3ceaaead7c4991ab2dbc7f0b04eae3bd61d5ccdd Mon Sep 17 00:00:00 2001 From: Dennis Selden <111012436+DennSel@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:05:11 +0100 Subject: [PATCH 2/4] Enabled book loan functionality @Linus @Erika @Linda @Dennis --- src/main/java/org/example/App.java | 7 +++-- src/main/java/org/example/Book.java | 2 +- src/main/java/org/example/Loan.java | 3 ++- src/main/java/org/example/LoanServices.java | 24 ++++++++++------- src/main/java/org/example/SearchCli.java | 30 +++++++++++++++++++-- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index 0d94276e..53c06597 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -29,7 +29,7 @@ static void main(String[] args) { System.out.println("========================================================"); if (SessionManager.isLoggedIn()) { - System.out.println("1. Sök bok | 2. Hantera användare | 3. Logga ut | 0. Avsluta"); + System.out.println("1. Sök bok | 2. Mina lån | 3. Hantera användare | 4. Logga ut | 0. Avsluta"); } else { System.out.println("1. Sök bok | 2. Logga in/Skapa konto | 0. Avsluta"); } @@ -41,10 +41,13 @@ static void main(String[] args) { searchCli.bookSearchCli(); } case "2" -> { + + } + case "3" -> { if (SessionManager.isLoggedIn()) userCli.manageUserMenu(); else userCli.userMenu(); } - case "3" -> { + case "4" -> { if (SessionManager.isLoggedIn()) userCli.logout(); } case "0" -> appRunning = false; diff --git a/src/main/java/org/example/Book.java b/src/main/java/org/example/Book.java index da932078..ad821b31 100644 --- a/src/main/java/org/example/Book.java +++ b/src/main/java/org/example/Book.java @@ -81,7 +81,7 @@ public void setLoan(Loan loan) { @ManyToMany(mappedBy = "books") private Set genres = new HashSet<>(); - @OneToOne @JoinColumn(name = "loaned_book") + @OneToOne (mappedBy = "book") private Loan loan; public Set getAuthors() { diff --git a/src/main/java/org/example/Loan.java b/src/main/java/org/example/Loan.java index 94d23e27..ee28f15a 100644 --- a/src/main/java/org/example/Loan.java +++ b/src/main/java/org/example/Loan.java @@ -55,6 +55,7 @@ public Long getLoanId() { @ManyToOne @JoinColumn (name = "loan_user") private User user; - @OneToOne(mappedBy = "loan") + @OneToOne + @JoinColumn(name = "bookID") private Book book; } diff --git a/src/main/java/org/example/LoanServices.java b/src/main/java/org/example/LoanServices.java index 2e5fb200..613a12cf 100644 --- a/src/main/java/org/example/LoanServices.java +++ b/src/main/java/org/example/LoanServices.java @@ -16,7 +16,7 @@ public LoanServices(EntityManager em) { public boolean isBookLoaned(Long bookId) { List loans = em.createQuery( - "SELECT l FROM Loan l WHERE l.book.bookId = :bookId AND l.returnDate IS NULL", + "SELECT l FROM Loan l WHERE l.book.bookId = :bookId AND l.returnDate IS NOT NULL", Loan.class ) .setParameter("bookId", bookId) @@ -30,26 +30,31 @@ public boolean isBookLoaned(Long bookId) { } // Låna en bok - public boolean loanBook(Long bookId, Long userId) { + public boolean loanBook(User user, Book book) { - if (isBookLoaned(bookId)) { + if (isBookLoaned(book.getId())) { return false; } - User user = em.find(User.class, userId); - Book book = em.find(Book.class, bookId); + em.getTransaction().begin(); + + Book managedBook = em.merge(book); Loan loan = new Loan(); loan.setUser(user); - loan.setBook(book); loan.setLoanDate(ZonedDateTime.now()); - loan.setReturnDate(null); + loan.setReturnDate(ZonedDateTime.now().plusDays((7))); + + loan.setBook(managedBook); + managedBook.setLoan(loan); em.persist(loan); + em.getTransaction().commit(); + return true; } - // Lämna tillbak en bok + // Lämna tillbaka en bok public boolean returnBook(User user, Book book) { Loan loan = em.createQuery( @@ -69,7 +74,8 @@ public boolean returnBook(User user, Book book) { em.getTransaction().begin(); loan.setReturnDate(ZonedDateTime.now()); - book.setLoan(null); + Book managedBook = loan.getBook(); + managedBook.setLoan(null); em.getTransaction().commit(); return true; } diff --git a/src/main/java/org/example/SearchCli.java b/src/main/java/org/example/SearchCli.java index b5a46552..7f9d952d 100644 --- a/src/main/java/org/example/SearchCli.java +++ b/src/main/java/org/example/SearchCli.java @@ -3,6 +3,7 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; +import org.example.user.SessionManager; import java.util.List; import java.util.Scanner; @@ -118,7 +119,6 @@ private static void printBookDetails(Book b) { System.out.println("Författare: " + formatAuthors(b)); System.out.println("Genre: " + formatGenres(b)); System.out.println("Utgiven: " + b.getPublishYear()); - System.out.println("Låna bok"); String desc = b.getDescription(); if (desc == null || desc.isBlank()) desc = "(Ingen beskrivning)"; @@ -128,10 +128,36 @@ private static void printBookDetails(Book b) { System.out.println("Status: Utlånad"); } else { System.out.println("Status: Tillgänglig"); + + boolean isLoggedIn = SessionManager.isLoggedIn(); + boolean isRunning = true; + + if (isLoggedIn){ + while (isRunning) { + System.out.println("1. Låna bok | 2. Tillbaka"); + String choice = sc.nextLine(); + + switch (choice) { + case "1" -> { + loanServices.loanBook(SessionManager.getCurrentUser(), b); + isRunning = false; + System.out.println("Du har nu lånat boken!"); + } + + case "2" -> { + isRunning = false; + } + default -> System.out.println("Ogiltigt val, försök igen."); + } + } + } } +// boolean isLoggedIn = SessionManager.isLoggedIn(); +// User user = SessionManager.getCurrentUser(); +// user.getUserId(); + //todo: - // Status på boken: tillgänglig/utlånad // om tillgänglig och inloggad - låna bok // om ej inloggad - skicka till logga in sidan. From 48757778d902269f143b1016435631f62d41cec0 Mon Sep 17 00:00:00 2001 From: Dennis Selden <111012436+DennSel@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:38:01 +0100 Subject: [PATCH 3/4] Added functionality to display active loans in the CLI menu --- src/main/java/org/example/App.java | 12 ++++++++---- src/main/java/org/example/LoanServices.java | 10 ++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index 53c06597..a6879fa2 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -29,21 +29,25 @@ static void main(String[] args) { System.out.println("========================================================"); if (SessionManager.isLoggedIn()) { - System.out.println("1. Sök bok | 2. Mina lån | 3. Hantera användare | 4. Logga ut | 0. Avsluta"); + System.out.println("1. Sök bok | 5. Mina lån | 3. Hantera användare | 4. Logga ut | 0. Avsluta"); } else { System.out.println("1. Sök bok | 2. Logga in/Skapa konto | 0. Avsluta"); } System.out.print("Menyval: "); String choice = scanner.nextLine(); + LoanServices loanServices = new LoanServices(EMFactory.getEntityManager()); switch (choice) { case "1" -> { searchCli.bookSearchCli(); } - case "2" -> { - + case "5" -> { + System.out.println("Dina aktiva lån:"); + System.out.println(loanServices.activeLoans(SessionManager.getCurrentUser())); + // kunna välja att lämna tillbaka en bok + // System.out.println("Du har lämnat tillbaka din bok!"); } - case "3" -> { + case "2" -> { if (SessionManager.isLoggedIn()) userCli.manageUserMenu(); else userCli.userMenu(); } diff --git a/src/main/java/org/example/LoanServices.java b/src/main/java/org/example/LoanServices.java index 613a12cf..e5216794 100644 --- a/src/main/java/org/example/LoanServices.java +++ b/src/main/java/org/example/LoanServices.java @@ -79,4 +79,14 @@ public boolean returnBook(User user, Book book) { em.getTransaction().commit(); return true; } + + public List activeLoans(User user) { + + return em.createQuery( + "SELECT l FROM Loan l WHERE l.user = :user", + Loan.class + ) + .setParameter("user", user) + .getResultList(); + } } From 28ecdc7cb64f7fd7c9edb28bd4c0fdfae53accd5 Mon Sep 17 00:00:00 2001 From: Linus Samuelsson Date: Mon, 12 Jan 2026 14:48:09 +0100 Subject: [PATCH 4/4] Adds functionality for returning loans and fixes query for completed loans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dennis Seldén <111012436+dennsel@users.noreply.github.com> Co-authored-by: Linda Eskilsson Co-authored-by: Erika Falk Svendsen --- src/main/java/org/example/App.java | 56 +++++++++++++++++---- src/main/java/org/example/LoanServices.java | 4 +- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index a6879fa2..a7c8b166 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -7,6 +7,8 @@ import org.example.user.repository.JpaUserRepository; import org.example.user.repository.UserRepository; +import java.time.format.DateTimeFormatter; +import java.util.List; import java.util.Scanner; public class App { @@ -18,6 +20,8 @@ static void main(String[] args) { Scanner scanner = new Scanner(System.in); final UserCLI userCli = new UserCLI(userService, scanner); SearchCli searchCli = new SearchCli(scanner, EMFactory.getEntityManager()); + DateTimeFormatter formatter = + DateTimeFormatter.ofPattern("yyyy-MM-dd"); // ####################### // Application starts here @@ -29,7 +33,7 @@ static void main(String[] args) { System.out.println("========================================================"); if (SessionManager.isLoggedIn()) { - System.out.println("1. Sök bok | 5. Mina lån | 3. Hantera användare | 4. Logga ut | 0. Avsluta"); + System.out.println("1. Sök bok | 2. Hantera användare | 3. Logga ut | 4. Mina lån | 0. Avsluta"); } else { System.out.println("1. Sök bok | 2. Logga in/Skapa konto | 0. Avsluta"); } @@ -41,19 +45,51 @@ static void main(String[] args) { case "1" -> { searchCli.bookSearchCli(); } - case "5" -> { - System.out.println("Dina aktiva lån:"); - System.out.println(loanServices.activeLoans(SessionManager.getCurrentUser())); - // kunna välja att lämna tillbaka en bok - // System.out.println("Du har lämnat tillbaka din bok!"); - } case "2" -> { - if (SessionManager.isLoggedIn()) userCli.manageUserMenu(); - else userCli.userMenu(); + if (SessionManager.isLoggedIn()) { + userCli.manageUserMenu(); + } else { + userCli.userMenu(); + } } - case "4" -> { + case "3" -> { if (SessionManager.isLoggedIn()) userCli.logout(); } + case "4" -> { + System.out.println("Dina aktiva lån:"); + List loans = loanServices.activeLoans(SessionManager.getCurrentUser()); + + boolean running = true; + while (running) { + if (!loans.isEmpty()) { + int counter = 0; + for (Loan loan : loans) { + counter += 1; + System.out.println(counter + ". Titel: " + loan.getBook().getTitle() + " - Åter: " + loan.getReturnDate() + .format(formatter)); + } + System.out.println("Välj nummer för den bok du vill lämna tillbaka (0 = tillbaka): "); + String inputString = scanner.nextLine(); + Integer input = Integer.parseInt(inputString); + if (input >= 1 && input <= loans.size()) { + loanServices.returnBook( + SessionManager.getCurrentUser(), + loans.get(input - 1).getBook() + ); + loans.remove(input - 1); + System.out.println("Du har lämnat tillbaka din bok!"); + } else if (input == 0) { + running = false; + } else { + System.out.println("ogiltigt val."); + } + + } else { + System.out.println("Inga aktiva lån."); + running = false; + } + } + } case "0" -> appRunning = false; default -> System.out.println("Ogiltigt val."); } diff --git a/src/main/java/org/example/LoanServices.java b/src/main/java/org/example/LoanServices.java index e5216794..2dda1a57 100644 --- a/src/main/java/org/example/LoanServices.java +++ b/src/main/java/org/example/LoanServices.java @@ -58,7 +58,7 @@ public boolean loanBook(User user, Book book) { public boolean returnBook(User user, Book book) { Loan loan = em.createQuery( - "SELECT l FROM Loan l WHERE l.user = :user AND l.book = :book AND l.returnDate IS NULL", + "SELECT l FROM Loan l WHERE l.user = :user AND l.book = :book AND l.returnDate IS NOT NULL", Loan.class ) .setParameter("user", user) @@ -73,9 +73,9 @@ public boolean returnBook(User user, Book book) { em.getTransaction().begin(); - loan.setReturnDate(ZonedDateTime.now()); Book managedBook = loan.getBook(); managedBook.setLoan(null); + em.remove(loan); em.getTransaction().commit(); return true; }