PrenotazioneLibriServiceImpl.java
package it.unisa.c07.biblionet.prenotazioneLibri.service;
import it.unisa.c07.biblionet.model.dao.GenereDAO;
import it.unisa.c07.biblionet.model.dao.LibroDAO;
import it.unisa.c07.biblionet.model.dao.PossessoDAO;
import it.unisa.c07.biblionet.model.dao.TicketPrestitoDAO;
import it.unisa.c07.biblionet.model.dao.customQueriesResults.ILibroIdAndName;
import it.unisa.c07.biblionet.model.dao.utente.BibliotecaDAO;
import it.unisa.c07.biblionet.model.entity.Genere;
import it.unisa.c07.biblionet.model.entity.Libro;
import it.unisa.c07.biblionet.model.entity.Possesso;
import it.unisa.c07.biblionet.model.entity.TicketPrestito;
import it.unisa.c07.biblionet.model.entity.compositeKey.PossessoId;
import it.unisa.c07.biblionet.model.entity.utente.Biblioteca;
import it.unisa.c07.biblionet.model.entity.utente.Lettore;
import it.unisa.c07.biblionet.prenotazioneLibri.service.bookApiAdapter.BookApiAdapter;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Implementa la classe che esplicita i metodi
* definiti nell'interfaccia service per il
* sottosustema PrenotazioneLibri.
* @author Viviana Pentangelo, Gianmario Voria
*/
@Service
@RequiredArgsConstructor
public class PrenotazioneLibriServiceImpl implements PrenotazioneLibriService {
/**
*Si occupa delle operazioni CRUD per libro.
*/
private final LibroDAO libroDAO;
/**
*Si occupa delle operazioni CRUD per genere.
*/
private final GenereDAO genereDAO;
/**
*Si occupa delle operazioni CRUD per biblioteca.
*/
private final BibliotecaDAO bibliotecaDAO;
/**
*Si occupa delle operazioni CRUD per possesso.
*/
private final PossessoDAO possessoDAO;
/**
*Si occupa delle operazioni CRUD per ticket.
*/
private final TicketPrestitoDAO ticketPrestitoDAO;
/**
* Si occupa delle operazioni per l'inject.
*/
private final BookApiAdapter bookApiAdapter;
/**
* Implementa la funzionalità che permette
* di visualizzare la lista completa dei libri
* prenotabili sulla piattaforma.
* @return La lista di libri
*/
@Override
public List<Libro> visualizzaListaLibriCompleta() {
return libroDAO.findAll(Sort.by("titolo"));
}
/**
* Implementa la funzionalità che permette
* di visualizzare una lista di libri prenotabili
* filtrata per titolo.
* @param titolo Stringa che deve essere contenuta
* nel titolo
* @return La lista di libri
*/
@Override
public List<Libro> visualizzaListaLibriPerTitolo(final String titolo) {
return libroDAO.findByTitoloLike(titolo);
}
/**
* Implementa la funzionalità che permette
* di visualizzare il profilo di una singola biblioteca.
* @param email della biblioteca
* @return la biblioteca
*/
@Override
public Biblioteca getBibliotecaById(final String email) {
Biblioteca biblioteca = bibliotecaDAO.findByID(email);
return biblioteca;
}
/**
* Implementa la funzionalità che permette
* di visualizzare la lista completa dei libri
* prenotabili da una determinata biblioteca.
* @param nomeBiblioteca Il nome della biblioteca
* @return La lista di libri
*/
@Override
public List<Libro> visualizzaListaLibriPerBiblioteca(
final String nomeBiblioteca) {
List<Biblioteca> b = bibliotecaDAO.findByNome(nomeBiblioteca);
List<Libro> libri = new ArrayList<>();
for (Biblioteca bib : b) {
String bibID = bib.getEmail();
List<Possesso> possessi = possessoDAO.findByBibliotecaID(bibID);
for (Possesso p : possessi) {
Optional<Libro> l =
libroDAO.findById(p.getPossessoID().getLibroID());
if (!libri.contains(l.orElse(null))) {
libri.add(l.orElse(null));
}
}
}
return libri;
}
/**
* Implementa la funzionalità che permette
* di visualizzare la lista completa dei libri
* prenotabili di un dato genere.
* @param genere Il nome del genere
* @return La lista di libri
*/
@Override
public List<Libro> visualizzaListaLibriPerGenere(
final String genere) {
List<Libro> libri = libroDAO.findAll();
List<Libro> list = new ArrayList<>();
Genere g = genereDAO.findByName(genere);
for (Libro l : libri) {
if (l.getGeneri().contains(g)) {
list.add(l);
}
}
return list;
}
/**
* Implementa la funzionalità che permette
* di richiedere un prestito per un libro
* da una biblioteca.
* @param lettore Il lettore che lo richiede
* @param idBiblioteca id della biblioteca
* @param idLibro id del libro
* @return Il ticket aperto in attesa di approvazione
*/
@Override
public TicketPrestito richiediPrestito(final Lettore lettore,
final String idBiblioteca,
final int idLibro) {
TicketPrestito ticket = new TicketPrestito();
ticket.setLettore(lettore);
ticket.setDataRichiesta(LocalDateTime.now());
ticket.setStato(TicketPrestito.Stati.IN_ATTESA_DI_CONFERMA);
Biblioteca biblioteca =
bibliotecaDAO.findByID(idBiblioteca);
Libro libro = libroDAO.getOne(idLibro);
ticket.setBiblioteca(biblioteca);
ticket.setLibro(libro);
ticketPrestitoDAO.save(ticket);
return ticket;
}
/**
* Implementa la funzionalità che permette
* di ottenere la lista delle biblioteche
* che posseggono un dato libro.
* @param libro Il libro di cui estrarre le biblioteche
* @return La lista delle biblioteche che possiedono il libro
*/
@Override
public List<Biblioteca> getBibliotecheLibro(final Libro libro) {
List<Biblioteca> lista = new ArrayList<>();
for (Possesso p : libro.getPossessi()) {
lista.add(bibliotecaDAO.
findByID(p.getPossessoID().getBibliotecaID()));
}
return lista;
}
/**
* Implementa la funzionalità che permette
* di ottenere un libro dato il suo ID.
* @param id L'ID del libro da ottenere
* @return Il libro da ottenere
*/
@Override
public Libro getLibroByID(final int id) {
return libroDAO.getOne(id);
}
/**
* Implementa la funzionalità che permette
* di ottenere una lista di richieste per una biblioteca.
* @param biblioteca la biblioteca di cui vedere le richieste
* @return La lista di richieste
*/
@Override
public List<TicketPrestito> getTicketsByBiblioteca(
final Biblioteca biblioteca) {
return ticketPrestitoDAO.
findAllByBibliotecaEmail(biblioteca.getEmail());
}
/**
* Implementa la funzionalità che permette
* di ottenere un ticket dato il suo ID.
* @param id L'ID del ticket da recuperare
* @return Il ticket ottenuto
*/
@Override
public TicketPrestito getTicketByID(final int id) {
return ticketPrestitoDAO.getOne(id);
}
/**
* Implementa la funzionalità che permette
* di accettare la richiesta di prestito di un libro.
* @param ticket il ticket che rappresenta la richiesta
* @param giorni il tempo di concessione del libro
* @return Il ticket aggiornato
*/
@Override
public TicketPrestito accettaRichiesta(final TicketPrestito ticket,
final int giorni) {
ticket.setDataRestituzione(LocalDateTime.now().plusDays(giorni));
ticket.setStato(TicketPrestito.Stati.IN_ATTESA_DI_RESTITUZIONE);
Libro l = ticket.getLibro();
Biblioteca b = ticket.getBiblioteca();
Possesso pos = possessoDAO.
getOne(new PossessoId(b.getEmail(), l.getIdLibro()));
if (pos != null) {
pos.setNumeroCopie(pos.getNumeroCopie() - 1);
possessoDAO.save(pos);
}
ticketPrestitoDAO.save(ticket);
return ticket;
}
/**
* Implementa la funzionalità che permette
* di rifiutare la richiesta di prestito di un libro.
* @param ticket il ticket che rappresenta la richiesta
* @return Il ticket aggiornato
*/
@Override
public TicketPrestito rifiutaRichiesta(final TicketPrestito ticket) {
ticket.setStato(TicketPrestito.Stati.RIFIUTATO);
ticketPrestitoDAO.save(ticket);
return ticket;
}
/**
* Implementa la funzionalità che permette
* di chiudere un ticket di prenotazione di un libro
* quando questo viene riconsegnato.
* @param ticket il ticket che rappresenta la richiesta da chiudere
* @return Il ticket aggiornato a chiuso
*/
@Override
public TicketPrestito chiudiTicket(final TicketPrestito ticket) {
ticket.setStato(TicketPrestito.Stati.CHIUSO);
Libro l = ticket.getLibro();
Biblioteca b = ticket.getBiblioteca();
Possesso pos = possessoDAO.
getOne(new PossessoId(b.getEmail(), l.getIdLibro()));
if (pos != null) {
pos.setNumeroCopie(pos.getNumeroCopie() + 1);
possessoDAO.save(pos);
}
return ticketPrestitoDAO.save(ticket);
}
/**
* Implementa la funzionalità che permette
* di ottenere la lista di ticket aperti da un Lettore.
* @param lettore il Lettore di cui recuperare i ticket
* @return la lista dei ticket
*/
@Override
public List<TicketPrestito> getTicketsLettore(final Lettore lettore) {
return ticketPrestitoDAO.
findAllByLettoreEmail(lettore.getEmail());
}
/**
* Implementa la funzionalità che permette di
* ottenere una lista di id e titoli di libri
* sulla base di un titolo dato
*
* ! Controllare prima di consegnare
*
* @param titolo il titolo che deve mathcare
* @return la lista di informazioni
*/
public List<ILibroIdAndName> findByTitoloContains(final String titolo) {
List<ILibroIdAndName> infoLibroList =
libroDAO.findByTitoloContains(titolo);
if (infoLibroList == null) {
infoLibroList = new ArrayList<>();
} else if (infoLibroList.size() > 10) {
infoLibroList = infoLibroList.subList(0, 9);
}
return infoLibroList;
}
/**
* Implementa la funzionalità che permette
* di creare un nuovo libro e inserirlo nella lista
* a partire da un isbn usando una API di google.
* @param isbn il Lettore di cui recuperare i ticket
* @param idBiblioteca l'id della biblioteca che lo possiede
* @param numCopie il numero di copie possedute
* @param generi la lista dei generi
* @return il libro creato
*/
public Libro inserimentoPerIsbn(final String isbn,
final String idBiblioteca,
final int numCopie,
final List<String> generi) {
//Recupero l'oggetto Libro da Api per isbn
Libro l = bookApiAdapter.getLibroDaBookApi(isbn);
System.out.println(l);
if (l == null) {
return l;
}
//Casting dei generi
List<Genere> g = new ArrayList<>();
for (String s : generi) {
g.add(genereDAO.findByName(s));
}
l.setGeneri(g);
//Controllo che il libro non sia già salvato
boolean exists = false;
Libro libro = null;
for (Libro tl : libroDAO.findAll()) {
if (tl.getIsbn().equals(l.getIsbn())) {
exists = true;
libro = tl;
}
}
if (!exists) {
libro = libroDAO.save(l);
}
Biblioteca b = bibliotecaDAO.findByID(idBiblioteca);
//Se per errore avesse inserito un libro che possiede già,
//aggiorno semplicemente il numero di copie che ha.
for (Possesso p : b.getPossessi()) {
if (p.getPossessoID().getLibroID() == libro.getIdLibro()) {
p.setNumeroCopie(p.getNumeroCopie() + numCopie);
possessoDAO.save(p);
bibliotecaDAO.save(b);
return libro;
}
}
//Creo il possesso relativo al libro e alla biblioteca
//che lo inserisce e lo memorizzo
PossessoId pid = new PossessoId(idBiblioteca, libro.getIdLibro());
Possesso possesso = new Possesso(pid, numCopie);
possessoDAO.save(possesso);
List<Possesso> plist = b.getPossessi();
plist.add(possesso);
b.setPossessi(plist);
//Update della biblioteca con il nuovo possesso
bibliotecaDAO.save(b);
return libro;
}
/**
* Implementa la funzionalità che permette
* di inserire un libro già memorizzato negli
* archivi della piattaforma alla lista dei propri
* libri prenotabili.
* @param idLibro il Libro da inserire
* @param idBiblioteca l'id della biblioteca che lo possiede
* @param numCopie il numero di copie possedute
* @return il libro inserito
*/
public Libro inserimentoDalDatabase(final int idLibro,
final String idBiblioteca,
final int numCopie) {
Libro l = libroDAO.getOne(idLibro);
Biblioteca b = bibliotecaDAO.findByID(idBiblioteca);
//Se per errore avesse inserito un libro che possiede già,
//aggiorno semplicemente il numero di copie che ha.
for (Possesso p : b.getPossessi()) {
if (p.getPossessoID().getLibroID() == idLibro) {
p.setNumeroCopie(p.getNumeroCopie() + numCopie);
possessoDAO.save(p);
bibliotecaDAO.save(b);
return l;
}
}
//Creo e salvo il nuovo possesso
PossessoId pid = new PossessoId(idBiblioteca, idLibro);
Possesso p = new Possesso(pid, numCopie);
possessoDAO.save(p);
List<Possesso> plist = b.getPossessi();
plist.add(p);
b.setPossessi(plist);
//Update della biblioteca con il nuovo possesso
bibliotecaDAO.save(b);
return l;
}
/**
* Implementa la funzionalità che permette
* di inserire un libro attraverso un form.
* @param libro il Libro da memorizzare
* @param idBiblioteca l'id della biblioteca che lo possiede
* @param numCopie il numero di copie possedute
* @param generi la lista dei generi del libro
* @return il libro inserito
*/
public Libro inserimentoManuale(final Libro libro,
final String idBiblioteca,
final int numCopie,
final List<String> generi) {
Biblioteca b = bibliotecaDAO.findByID(idBiblioteca);
//Controllo che il libro non sia già salvato
boolean exists = false;
Libro l = new Libro();
List<Genere> g = new ArrayList<>();
for (String s : generi) {
g.add(genereDAO.findByName(s));
}
libro.setGeneri(g);
for (Libro tl : libroDAO.findAll()) {
if (tl.getTitolo().equals(libro.getTitolo())) {
exists = true;
l = tl;
}
}
if (!exists) {
l = libroDAO.save(libro);
}
//Se per errore avesse inserito un libro che possiede già,
//aggiorno semplicemente il numero di copie che ha.
for (Possesso p : b.getPossessi()) {
if (p.getPossessoID().getLibroID() == l.getIdLibro()) {
p.setNumeroCopie(p.getNumeroCopie() + numCopie);
possessoDAO.save(p);
bibliotecaDAO.save(b);
return l;
}
}
//Creo e salvo il nuovo possesso
PossessoId pid = new PossessoId(idBiblioteca, l.getIdLibro());
Possesso p = new Possesso(pid, numCopie);
possessoDAO.save(p);
List<Possesso> plist = b.getPossessi();
plist.add(p);
b.setPossessi(plist);
//Update della biblioteca con il nuovo possesso
bibliotecaDAO.save(b);
return l;
}
/**
* Implementa la funzionalità che permette di
* recuperare la lista dei generi.
* @return la lista dei generi.
*/
public List<Genere> getAllGeneri() {
return genereDAO.findAll();
}
/**
* Implementa la funzionalità che permette di
* recuperare la lista delle biblioteche.
* @return la lista delle biblioteche.
*/
@Override
public List<Biblioteca> getAllBiblioteche() {
return bibliotecaDAO.findAllBiblioteche();
}
/**
* Implementa la funzionalità che permette di
* recuperare la lista delle biblioteche dato un nome.
* @return la lista delle biblioteche.
*/
@Override
public List<Biblioteca> getBibliotecheByNome(final String nome) {
List<Biblioteca> byNome = bibliotecaDAO.findByNome(nome);
return byNome;
}
/**
* Implementa la funzionalità che permette di
* recuperare la lista delle biblioteche data una citta.
* @return la lista delle biblioteche.
*/
@Override
public List<Biblioteca> getBibliotecheByCitta(final String citta) {
List<Biblioteca> byCitta = bibliotecaDAO.findByCitta(citta);
return byCitta;
}
}