diff --git a/.gitignore b/.gitignore index 1057dde..b697fe7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ ################################################################################ /.vs /.idea -/web-library/appsettings.json /web-library/bin /web-library/obj /web-library/web-library.csproj.user diff --git a/web-library/Book/Controller/BookController.cs b/web-library/Book/Controller/BookController.cs index c9219b8..67a89cb 100644 --- a/web-library/Book/Controller/BookController.cs +++ b/web-library/Book/Controller/BookController.cs @@ -1,66 +1,58 @@ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace web_library.Book.Controller { using Entity; - using web_library.Book.Request; - using web_library.Book.Service; + using Request; + using Service; + using DataProvider; + using Microsoft.AspNetCore.Authorization; [Route("api/[controller]")] [ApiController] public class BookController : ControllerBase { private readonly IBookService _bookService; + private readonly IBookDataProvider _bookDataProvider; - public BookController(IBookService bookService) + public BookController(IBookService bookService, IBookDataProvider bookDataProvider) { _bookService = bookService; + _bookDataProvider = bookDataProvider; } // GET: api/ [HttpGet] public ActionResult> Get() { - return Ok(); - } - - // GET api//5 - [HttpGet("{id}")] - public string Get(int id) - { - return "value"; + return Ok(_bookDataProvider.getAll()); } // POST api/ [HttpPost] public ActionResult Post([FromBody] CreateBookRequest request) { - try - { - _bookService.createBook(request); - } - catch - (Exception) - { - return NotFound(); - } + _bookService.createBook(request); return Ok(); } - - // PUT api//5 - [HttpPut("{id}")] - public void Put(int id, [FromBody] string value) + // POST api/ + [HttpPost("seed")] + public ActionResult Seed([FromBody] CreateBookRequest request) { + request = new("seed"); + _bookService.createBook(request); + return Ok(); } - // DELETE api//5 - [HttpDelete("{id}")] - public void Delete(int id) + // PUT api//5 + [HttpPut("{id}")] + public ActionResult Put(int id, [FromBody] AssigneGenreToBookRequest request) { + request.book_id = id; + _bookService.assigneGenre(request); + return Ok(); } } } diff --git a/web-library/Book/DataProvider/BookDataProvider.cs b/web-library/Book/DataProvider/BookDataProvider.cs new file mode 100644 index 0000000..8709268 --- /dev/null +++ b/web-library/Book/DataProvider/BookDataProvider.cs @@ -0,0 +1,40 @@ +namespace web_library.Book.DataProvider; +using Entity; +using web_library.Book.Model; +using web_library.Book.Repository; + +public class BookDataProvider : IBookDataProvider +{ + private readonly IBookRepository _bookRepository; + public BookDataProvider(IBookRepository bookRepository) + { + _bookRepository = bookRepository; + } + private BookModel getModel(Book entity) + { + return new BookModel( + entity.Id, + entity.ISBN, + entity.Title, + entity.Author, + entity.Publisher, + entity.Publication_date, + entity.Location, + entity.Description, + entity.Copies.Count() + ); + } + public ICollection getAll() + { + List result = new(); + foreach (var item in _bookRepository.FindAll()) + { + result.Add(getModel(item)); + }; + return result; + } + public BookModel getById(int id) + { + return getModel(_bookRepository.FindByIdOrThrow(id)); + } +} diff --git a/web-library/Book/DataProvider/IBookDataProvider.cs b/web-library/Book/DataProvider/IBookDataProvider.cs new file mode 100644 index 0000000..d3ba205 --- /dev/null +++ b/web-library/Book/DataProvider/IBookDataProvider.cs @@ -0,0 +1,9 @@ +using web_library.Book.Model; + +namespace web_library.Book.DataProvider; + +public interface IBookDataProvider +{ + ICollection getAll(); + BookModel getById(int id); +} \ No newline at end of file diff --git a/web-library/Book/Model/BookModel.cs b/web-library/Book/Model/BookModel.cs new file mode 100644 index 0000000..0b98ed0 --- /dev/null +++ b/web-library/Book/Model/BookModel.cs @@ -0,0 +1,27 @@ +namespace web_library.Book.Model; + +public class BookModel +{ + public int BookId { get; set; } + public string ISBN { get; set; } + public string Title { get; set; } + public string Author { get; set; } + public string Publisher { get; set; } + public DateOnly Publication_date { get; set; } + public string Location { get; set; } + public string Description { get; set; } + public int NumberOfCopies { get; set; } + + public BookModel(int bookId, string iSBN, string title, string author, string publisher, DateOnly publication_date, string location, string description, int numberOfCopies) + { + BookId = bookId; + ISBN = iSBN; + Title = title; + Author = author; + Publisher = publisher; + Publication_date = publication_date; + Location = location; + Description = description; + NumberOfCopies = numberOfCopies; + } +} diff --git a/web-library/Book/Repository/BookCopyRepository.cs b/web-library/Book/Repository/BookCopyRepository.cs index a8d970b..194a483 100644 --- a/web-library/Book/Repository/BookCopyRepository.cs +++ b/web-library/Book/Repository/BookCopyRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using web_library.Book.Entity; +using web_library.SharedExceptions; namespace web_library.Book.Repository { @@ -18,14 +19,14 @@ public void Add(BookCopy entity) _context.SaveChanges(); } - public IEnumerable GetAll() + public IEnumerable FindAll() { throw new NotImplementedException(); } - public BookCopy GetByIdOrThrow(int id) + public BookCopy FindByIdOrThrow(int id) { - throw new NotImplementedException(); + return _context.BooksCopy.Find(id) ?? throw new NotFoundException("Book copy" + id + " not found in repository"); } public void Remove(BookCopy entity) diff --git a/web-library/Book/Repository/BookRepository.cs b/web-library/Book/Repository/BookRepository.cs index eb42bec..271654f 100644 --- a/web-library/Book/Repository/BookRepository.cs +++ b/web-library/Book/Repository/BookRepository.cs @@ -1,42 +1,41 @@ -using System; -using System.Collections.Generic; -using web_library.Book.DataProvider; +using Microsoft.EntityFrameworkCore; +using web_library.SharedExceptions; -namespace web_library.Book.Repository +namespace web_library.Book.Repository; +using Entity; + +public class BookRepository : IBookRepository { - public class BookRepository : IBookRepository + private readonly DataContext _context; + public BookRepository(DataContext context) { - private readonly DataContext _context; - public BookRepository(DataContext context) - { - _context = context; - } + _context = context; + } - public void Add(Entity.Book entity) - { - _context.Books.Add(entity); - _context.SaveChanges(); - } + public void Add(Book entity) + { + _context.Books.Add(entity); + _context.SaveChanges(); + } - public IEnumerable GetAll() - { - throw new NotImplementedException(); - } + public IEnumerable FindAll() + { + return _context.Books.Include(b => b.Copies).ToList(); + } - public Entity.Book GetByIdOrThrow(int id) - { - throw new NotImplementedException(); - } + public Book FindByIdOrThrow(int id) + { + return _context.Books.Find(id) ?? throw new NotFoundException("Book " + id + " not found in repository"); + } - public void Remove(Entity.Book entity) - { - throw new NotImplementedException(); - } + public void Remove(Book entity) + { + throw new NotImplementedException(); + } - public void Update(Entity.Book entity) - { - _context.Books.Update(entity); - _context.SaveChanges(); - } + public void Update(Book entity) + { + _context.Books.Update(entity); + _context.SaveChanges(); } } diff --git a/web-library/Book/Repository/IBookCopyRepository.cs b/web-library/Book/Repository/IBookCopyRepository.cs index 03e6934..50ffe95 100644 --- a/web-library/Book/Repository/IBookCopyRepository.cs +++ b/web-library/Book/Repository/IBookCopyRepository.cs @@ -1,8 +1,7 @@ using web_library.Book.Entity; -namespace web_library.Book.Repository +namespace web_library.Book.Repository; + +public interface IBookCopyRepository : IGenericRepository { - public interface IBookCopyRepository : IGenericRepository - { - } } \ No newline at end of file diff --git a/web-library/Book/Repository/IBookRepository.cs b/web-library/Book/Repository/IBookRepository.cs index c0c8412..48676cd 100644 --- a/web-library/Book/Repository/IBookRepository.cs +++ b/web-library/Book/Repository/IBookRepository.cs @@ -1,8 +1,7 @@ -namespace web_library.Book.DataProvider +namespace web_library.Book.Repository; + +using Entity; +public interface IBookRepository : IGenericRepository { - using Entity; - public interface IBookRepository : IGenericRepository - { - public void Update(Book book); - } + public void Update(Book book); } \ No newline at end of file diff --git a/web-library/Book/Request/AssigneGenreToBookRequest.cs b/web-library/Book/Request/AssigneGenreToBookRequest.cs new file mode 100644 index 0000000..36ad43f --- /dev/null +++ b/web-library/Book/Request/AssigneGenreToBookRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace web_library.Book.Request +{ + public class AssigneGenreToBookRequest + { + + public ICollection genres_ids { get; set; } + [JsonIgnore] + public int book_id { get; set; } + } +} diff --git a/web-library/Book/Request/CreateBookRequest.cs b/web-library/Book/Request/CreateBookRequest.cs index c0c0436..29ba343 100644 --- a/web-library/Book/Request/CreateBookRequest.cs +++ b/web-library/Book/Request/CreateBookRequest.cs @@ -1,16 +1,38 @@ -using System; - -namespace web_library.Book.Request +namespace web_library.Book.Request { public class CreateBookRequest { - public string ISBN { get; set; } - public string Title { get; set; } - public string Author { get; set; } - public string Publisher { get; set; } - public DateOnly Publication_date { get; set; } - public string Location { get; set; } - public string Description { get; set; } - public int NumberOfCopies { get; set; } + public string isbn { get; set; } + public string title { get; set; } + public string author { get; set; } + public string publisher { get; set; } + public DateOnly publication_date { get; set; } + public string location { get; set; } + public string description { get; set; } + public int numberOfCopies { get; set; } + + public CreateBookRequest() { } + public CreateBookRequest(string type) + { + List isbnList = new() { 9780439023528, 9780747532743, 9780451524935, 9780618260300, 9780141439600 }; + List titleList = new() { "The Hunger Games", "Harry Potter and the Philosopher's Stone", "1984", "The Hobbit", "Pride and Prejudice" }; + List authorList = new() { "Suzanne Collins", "J.K. Rowling", "George Orwell", "J.R.R. Tolkien", "Jane Austen" }; + List publisherList = new() { "Scholastic Press", "Bloomsbury", "Harcourt Brace Jovanovich", "Houghton Mifflin", "Penguin Books" }; + List publication_dateList = new() { "September 14, 2008", "June 26, 1997", "June 8, 1949", "September 21, 1937", "January 28, 1813" }; + List locationList = new() { "United States", "United Kingdom", "United Kingdom", "United Kingdom", "United Kingdom" }; + List descriptionList = new() { "A dystopian novel set in a post-apocalyptic society in the country of Panem.", "The first novel in the Harry Potter series and Rowling's debut novel.", "A dystopian social science fiction novel and a cautionary tale of a totalitarian regime.", "A children's fantasy novel and prelude to the Lord of the Rings series.", "A romantic novel of manners depicting the society of early 19th-century England." }; + List numberOfCopiesList = new() { 5, 10, 15, 20, 25 }; + + Random r = new Random(); + int bookNumber = r.Next(0, 5); + isbn = isbnList[bookNumber].ToString(); + title = titleList[bookNumber]; + author = authorList[bookNumber]; + publisher = publisherList[bookNumber]; + publication_date = DateOnly.Parse(publication_dateList[r.Next(0, 5)]); + location = locationList[bookNumber]; + description = descriptionList[bookNumber]; + numberOfCopies = numberOfCopiesList[bookNumber]; + } } } diff --git a/web-library/Book/Service/BookService.cs b/web-library/Book/Service/BookService.cs index fc50e56..4345924 100644 --- a/web-library/Book/Service/BookService.cs +++ b/web-library/Book/Service/BookService.cs @@ -1,50 +1,60 @@ using Microsoft.AspNetCore.Authorization; using Newtonsoft.Json; -using web_library.Book.DataProvider; -using web_library.Book.Entity; -using web_library.Book.Repository; -using web_library.Book.Request; using web_library.Role.Enum; using web_library.SharedExceptions; using web_library.User.Service; -namespace web_library.Book.Service +namespace web_library.Book.Service; +using Entity; +using Repository; +using Request; +using Genre.Entity; +using Genre.Repository; +public class BookService : IBookService { - public class BookService : IBookService + private readonly IGenreRepository _genreRepository; + private readonly IBookRepository _bookRepository; + private readonly IBookCopyRepository _bookCopyRepository; + private readonly IUserService _userService; + + public BookService(IGenreRepository genreRepository, IBookRepository bookRepository, IBookCopyRepository bookCopyRepository, IUserService userService) { - private readonly IBookRepository _bookRepository; - private readonly IBookCopyRepository _bookCopyRepository; - private readonly IUserService _userService; + _genreRepository = genreRepository; + _bookRepository = bookRepository; + _bookCopyRepository = bookCopyRepository; + _userService = userService; + } - public BookService(IBookRepository bookRepository, IBookCopyRepository bookCopyRepository, - IUserService userService) - { - _bookRepository = bookRepository; - _bookCopyRepository = bookCopyRepository; - _userService = userService; - } + public void createBook(CreateBookRequest request) + { + //if (!_userService.HasRole(_userService.GetUser(), Roles.Librarian)) + //{ + // throw new UnauthorizedException(); + //} - [Authorize] - public void createBook(CreateBookRequest request) - { - if (!_userService.HasRole(_userService.GetUser(), Roles.Librarian)) - { - throw new UnauthorizedException(); - } + var jsonString = JsonConvert.SerializeObject(request); - var jsonString = JsonConvert.SerializeObject(request); + Book? entity = JsonConvert.DeserializeObject(jsonString) ?? throw new JsonException(); - Entity.Book? entity = JsonConvert.DeserializeObject(jsonString) ?? throw new JsonException(); + _bookRepository.Add(entity); - _bookRepository.Add(entity); + for (int i = 0; i < request.numberOfCopies; i++) + { + BookCopy copy = new(entity); + _bookCopyRepository.Add(copy); + } - for (int i = 0; i < request.NumberOfCopies; i++) - { - BookCopy copy = new(entity); - _bookCopyRepository.Add(copy); - } + _bookRepository.Update(entity); + } - _bookRepository.Update(entity); + public void assigneGenre(AssigneGenreToBookRequest request) + { + Entity.Book? book = _bookRepository.FindByIdOrThrow(request.book_id); + foreach (var id in request.genres_ids) + { + Genre? genre = _genreRepository.FindByIdOrThrow(id); + book.AddGenre(genre); } + _bookRepository.Update(book); } } \ No newline at end of file diff --git a/web-library/Book/Service/IBookService.cs b/web-library/Book/Service/IBookService.cs index 9ba92e7..b628362 100644 --- a/web-library/Book/Service/IBookService.cs +++ b/web-library/Book/Service/IBookService.cs @@ -1,9 +1,9 @@ using web_library.Book.Request; -namespace web_library.Book.Service +namespace web_library.Book.Service; + +public interface IBookService { - public interface IBookService - { - void createBook(CreateBookRequest request); - } + void createBook(CreateBookRequest request); + void assigneGenre(AssigneGenreToBookRequest request); } \ No newline at end of file diff --git a/web-library/DataContext.cs b/web-library/DataContext.cs index d455e8a..e7f83db 100644 --- a/web-library/DataContext.cs +++ b/web-library/DataContext.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using web_library.Book.Entity; +using web_library.Genre.Entity; +using web_library.Reservation.Entity; +using web_library.Role.Entity; using web_library.User.Entity; - -namespace web_library; - public class DataContext : DbContext { protected readonly IConfiguration Configuration; @@ -20,7 +20,16 @@ protected override void OnConfiguring(DbContextOptionsBuilder options) protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.Entity(entity => + //modelBuilder.Entity() + // .HasMany(left => left.Genres) + // .WithMany(right => right.Books) + // .UsingEntity>( + // "book_genres", + // j => j.HasOne().WithMany().HasForeignKey("genre_id"), + // j => j.HasOne().WithMany().HasForeignKey("book_id") + //); + + modelBuilder.Entity(entity => { entity.ToTable("users"); entity.HasIndex(u => u.Email).IsUnique(); @@ -40,7 +49,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.HasIndex(ubi => ubi.UserId).IsUnique(); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.ToTable("roles"); entity.HasKey(r => r.Id); @@ -49,10 +58,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) base.OnModelCreating(modelBuilder); } - public DbSet Users { get; set; } - public DbSet Books { get; set; } + public DbSet Users { get; set; } + public DbSet Books { get; set; } public DbSet BooksCopy { get; set; } - public DbSet Genres { get; set; } + public DbSet Genres { get; set; } public DbSet UserBasicInfos { get; set; } - public DbSet Roles { get; set; } + public DbSet Roles { get; set; } + public DbSet Reservations{ get; set; } } \ No newline at end of file diff --git a/web-library/DependencyInjection.cs b/web-library/DependencyInjection.cs index 072c83a..0bc12fa 100644 --- a/web-library/DependencyInjection.cs +++ b/web-library/DependencyInjection.cs @@ -2,12 +2,17 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; -using web_library.Book.DataProvider; +using web_library.Genre.Service; +using web_library.Genre.Repository; using web_library.Book.Repository; using web_library.Book.Service; using web_library.Role.Repository; using web_library.User.Repository; using web_library.User.Service; +using web_library.Reservation.Service; +using web_library.Reservation.Repostiory; +using web_library.Reservation.DataProvider; +using web_library.Book.DataProvider; namespace web_library; @@ -92,13 +97,24 @@ public static IServiceCollection ServicesInjection(this IServiceCollection servi { services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + + + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); + services.AddTransient(); return services; diff --git a/web-library/Genre/Controller/GenresController.cs b/web-library/Genre/Controller/GenresController.cs new file mode 100644 index 0000000..1f72c53 --- /dev/null +++ b/web-library/Genre/Controller/GenresController.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Mvc; + +namespace web_library.Genre.Controller +{ + using web_library.Genre.Request; + using web_library.Genre.Service; + + [Route("api/[controller]")] + [ApiController] + public class GenresController : ControllerBase + { + private readonly IGenreService _genreService; + + public GenresController(IGenreService genreService) + { + _genreService = genreService; + } + + [HttpPost] + public ActionResult Post([FromBody] CreateGenreRequest request) + { + try + { + _genreService.createGenre(request); + return Ok(); + } + catch + (Exception) + { + return BadRequest(); + } + } + } +} diff --git a/web-library/Genre/Repository/GenreRepository.cs b/web-library/Genre/Repository/GenreRepository.cs new file mode 100644 index 0000000..1e7353f --- /dev/null +++ b/web-library/Genre/Repository/GenreRepository.cs @@ -0,0 +1,38 @@ +namespace web_library.Genre.Repository +{ + using Entity; + using SharedExceptions; + + public class GenreRepository : IGenreRepository + { + private readonly DataContext _context; + public GenreRepository(DataContext context) + { + _context = context; + } + + public void Add(Genre entity) + { + _context.Genres.Add(entity); + _context.Add(entity); + _context.SaveChanges(); + } + + public IEnumerable FindAll() + { + throw new NotImplementedException(); + } + + public Genre FindByIdOrThrow(int id) + { + Genre? genre = _context.Genres.Find(id) ?? throw new NotFoundException("Genre " + id + " not found in repository"); + return genre; + throw new NotImplementedException(); + } + + public void Remove(Genre entity) + { + throw new NotImplementedException(); + } + } +} diff --git a/web-library/Genre/Repository/IGenreRepository.cs b/web-library/Genre/Repository/IGenreRepository.cs new file mode 100644 index 0000000..c862514 --- /dev/null +++ b/web-library/Genre/Repository/IGenreRepository.cs @@ -0,0 +1,7 @@ +namespace web_library.Genre.Repository +{ + using Entity; + public interface IGenreRepository : IGenericRepository + { + } +} \ No newline at end of file diff --git a/web-library/Genre/Request/CreateGenreRequest.cs b/web-library/Genre/Request/CreateGenreRequest.cs new file mode 100644 index 0000000..93a9d16 --- /dev/null +++ b/web-library/Genre/Request/CreateGenreRequest.cs @@ -0,0 +1,7 @@ +namespace web_library.Genre.Request +{ + public class CreateGenreRequest + { + public string Name { get; set; } + } +} diff --git a/web-library/Genre/Service/GenreService.cs b/web-library/Genre/Service/GenreService.cs new file mode 100644 index 0000000..8a9636e --- /dev/null +++ b/web-library/Genre/Service/GenreService.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; +using web_library.Genre.Repository; +using web_library.Genre.Request; + +namespace web_library.Genre.Service +{ + using Entity; + using Newtonsoft.Json; + + public class GenreService : IGenreService + { + private readonly IGenreRepository _genreRepository; + + public GenreService(IGenreRepository genreRepository) + { + _genreRepository = genreRepository; + } + + public void createGenre(CreateGenreRequest request) + { + var jsonString = JsonConvert.SerializeObject(request); + + Genre? genre = JsonConvert.DeserializeObject(jsonString) ?? throw new JsonException(); + + _genreRepository.Add(genre); + } + } +} diff --git a/web-library/Genre/Service/IGenreService.cs b/web-library/Genre/Service/IGenreService.cs new file mode 100644 index 0000000..8960d6d --- /dev/null +++ b/web-library/Genre/Service/IGenreService.cs @@ -0,0 +1,9 @@ +using web_library.Genre.Request; + +namespace web_library.Genre.Service +{ + public interface IGenreService + { + void createGenre(CreateGenreRequest request); + } +} \ No newline at end of file diff --git a/web-library/IGenericRepository.cs b/web-library/IGenericRepository.cs index d92a4e4..891767f 100644 --- a/web-library/IGenericRepository.cs +++ b/web-library/IGenericRepository.cs @@ -4,8 +4,8 @@ namespace web_library; public interface IGenericRepository where T : class { - T GetByIdOrThrow(int id); - IEnumerable GetAll(); + T FindByIdOrThrow(int id); + IEnumerable FindAll(); void Add(T entity); void Remove(T entity); } \ No newline at end of file diff --git a/web-library/Migrations/DataContextModelSnapshot.cs b/web-library/Migrations/20231204004614_reservationEntity.Designer.cs similarity index 71% rename from web-library/Migrations/DataContextModelSnapshot.cs rename to web-library/Migrations/20231204004614_reservationEntity.Designer.cs index 2a61a6f..deff0e0 100644 --- a/web-library/Migrations/DataContextModelSnapshot.cs +++ b/web-library/Migrations/20231204004614_reservationEntity.Designer.cs @@ -2,6 +2,7 @@ using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using web_library; @@ -11,9 +12,11 @@ namespace web_library.Migrations { [DbContext(typeof(DataContext))] - partial class DataContextModelSnapshot : ModelSnapshot + [Migration("20231204004614_reservationEntity")] + partial class reservationEntity { - protected override void BuildModel(ModelBuilder modelBuilder) + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder @@ -22,22 +25,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - modelBuilder.Entity("BookGenre", b => + modelBuilder.Entity("book_genres", b => { - b.Property("BooksId") + b.Property("book_id") .HasColumnType("integer"); - b.Property("GenresId") + b.Property("genre_id") .HasColumnType("integer"); - b.HasKey("BooksId", "GenresId"); + b.HasKey("book_id", "genre_id"); - b.HasIndex("GenresId"); + b.HasIndex("genre_id"); - b.ToTable("BookGenre"); + b.ToTable("book_genres"); }); - modelBuilder.Entity("web_library.Book.Entity.Book", b => + modelBuilder.Entity("web_library.Api.Book.Entity.Book", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -85,7 +88,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("books"); }); - modelBuilder.Entity("web_library.Book.Entity.BookCopy", b => + modelBuilder.Entity("web_library.Api.Book.Entity.BookCopy", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -105,7 +108,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("book_copies"); }); - modelBuilder.Entity("web_library.Genre.Entity.Genre", b => + modelBuilder.Entity("web_library.Api.Genre.Entity.Genre", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -124,7 +127,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("genres"); }); - modelBuilder.Entity("web_library.Role.Entity.Role", b => + modelBuilder.Entity("web_library.Api.Reservation.Entity.Reservation", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -133,17 +136,27 @@ protected override void BuildModel(ModelBuilder modelBuilder) NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - b.Property("Name") - .IsRequired() - .HasColumnType("text") - .HasColumnName("name"); + b.Property("bookCopyId") + .HasColumnType("integer") + .HasColumnName("book_copy_id"); + + b.Property("reservationEndDate") + .HasColumnType("date") + .HasColumnName("reservation_end_date"); + + b.Property("reservationStartDate") + .HasColumnType("date") + .HasColumnName("reservation_start_date"); b.HasKey("Id"); - b.ToTable("roles", (string)null); + b.HasIndex("bookCopyId") + .IsUnique(); + + b.ToTable("reservations"); }); - modelBuilder.Entity("web_library.User.Entity.User", b => + modelBuilder.Entity("web_library.Api.User.Entity.User", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -162,21 +175,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("text") .HasColumnName("password"); - b.Property("RoleId") - .HasColumnType("integer") - .HasColumnName("role_id"); - b.HasKey("Id"); b.HasIndex("Email") .IsUnique(); - b.HasIndex("RoleId"); - b.ToTable("users", (string)null); }); - modelBuilder.Entity("web_library.User.Entity.UserBasicInfo", b => + modelBuilder.Entity("web_library.Api.User.Entity.UserBasicInfo", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -217,24 +224,24 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("user_basic_info", (string)null); }); - modelBuilder.Entity("BookGenre", b => + modelBuilder.Entity("book_genres", b => { - b.HasOne("web_library.Book.Entity.Book", null) + b.HasOne("web_library.Api.Book.Entity.Book", null) .WithMany() - .HasForeignKey("BooksId") + .HasForeignKey("book_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("web_library.Genre.Entity.Genre", null) + b.HasOne("web_library.Api.Genre.Entity.Genre", null) .WithMany() - .HasForeignKey("GenresId") + .HasForeignKey("genre_id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("web_library.Book.Entity.BookCopy", b => + modelBuilder.Entity("web_library.Api.Book.Entity.BookCopy", b => { - b.HasOne("web_library.Book.Entity.Book", "Book") + b.HasOne("web_library.Api.Book.Entity.Book", "Book") .WithMany("Copies") .HasForeignKey("BookId") .OnDelete(DeleteBehavior.Cascade) @@ -243,34 +250,39 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Book"); }); - modelBuilder.Entity("web_library.User.Entity.User", b => + modelBuilder.Entity("web_library.Api.Reservation.Entity.Reservation", b => { - b.HasOne("web_library.Role.Entity.Role", "Role") - .WithMany() - .HasForeignKey("RoleId") + b.HasOne("web_library.Api.Book.Entity.BookCopy", "bookCopy") + .WithOne("reservation") + .HasForeignKey("web_library.Api.Reservation.Entity.Reservation", "bookCopyId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("Role"); + b.Navigation("bookCopy"); }); - modelBuilder.Entity("web_library.User.Entity.UserBasicInfo", b => + modelBuilder.Entity("web_library.Api.User.Entity.UserBasicInfo", b => { - b.HasOne("web_library.User.Entity.User", "User") + b.HasOne("web_library.Api.User.Entity.User", "User") .WithOne("UserBasicInfo") - .HasForeignKey("web_library.User.Entity.UserBasicInfo", "UserId") + .HasForeignKey("web_library.Api.User.Entity.UserBasicInfo", "UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("User"); }); - modelBuilder.Entity("web_library.Book.Entity.Book", b => + modelBuilder.Entity("web_library.Api.Book.Entity.Book", b => { b.Navigation("Copies"); }); - modelBuilder.Entity("web_library.User.Entity.User", b => + modelBuilder.Entity("web_library.Api.Book.Entity.BookCopy", b => + { + b.Navigation("reservation"); + }); + + modelBuilder.Entity("web_library.Api.User.Entity.User", b => { b.Navigation("UserBasicInfo"); }); diff --git a/web-library/Migrations/20231204004614_reservationEntity.cs b/web-library/Migrations/20231204004614_reservationEntity.cs new file mode 100644 index 0000000..41d71cf --- /dev/null +++ b/web-library/Migrations/20231204004614_reservationEntity.cs @@ -0,0 +1,50 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace web_library.Migrations +{ + /// + public partial class reservationEntity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "reservations", + columns: table => new + { + id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + reservation_start_date = table.Column(type: "date", nullable: false), + reservation_end_date = table.Column(type: "date", nullable: false), + book_copy_id = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_reservations", x => x.id); + table.ForeignKey( + name: "FK_reservations_book_copies_book_copy_id", + column: x => x.book_copy_id, + principalTable: "book_copies", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_reservations_book_copy_id", + table: "reservations", + column: "book_copy_id", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "reservations"); + } + } +} diff --git a/web-library/Reservation/Controller/ReservationController.cs b/web-library/Reservation/Controller/ReservationController.cs new file mode 100644 index 0000000..2ab369c --- /dev/null +++ b/web-library/Reservation/Controller/ReservationController.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Mvc; + +namespace web_library.Reservation.Controller +{ + using DataProvider; + using Request; + using Service; + using Model; + + [Route("api/[controller]")] + [ApiController] + public class ReservationController : ControllerBase + { + private readonly IReservationService _reservationService; + private readonly IReservationDataProvider _reservationDataProvider; + + public ReservationController(IReservationService reservationService, IReservationDataProvider reservationDataProvider) + { + _reservationService = reservationService; + _reservationDataProvider = reservationDataProvider; + } + + // GET: HomeController + [HttpGet] + public ActionResult> Index() + { + return Ok(_reservationDataProvider.GetAll()); + } + // POST: HomeController/Create + [HttpPost] + public ActionResult Create([FromBody] CreateReservationRequest request) + { + _reservationService.createReservation(request); + return Ok(); + } + } +} diff --git a/web-library/Reservation/DataProvider/IReservationDataProvider.cs b/web-library/Reservation/DataProvider/IReservationDataProvider.cs new file mode 100644 index 0000000..d3ff166 --- /dev/null +++ b/web-library/Reservation/DataProvider/IReservationDataProvider.cs @@ -0,0 +1,9 @@ +using web_library.Reservation.Model; + +namespace web_library.Reservation.DataProvider +{ + public interface IReservationDataProvider + { + IEnumerable GetAll(); + } +} \ No newline at end of file diff --git a/web-library/Reservation/DataProvider/ReservationDataProvider.cs b/web-library/Reservation/DataProvider/ReservationDataProvider.cs new file mode 100644 index 0000000..0975588 --- /dev/null +++ b/web-library/Reservation/DataProvider/ReservationDataProvider.cs @@ -0,0 +1,47 @@ +namespace web_library.Reservation.DataProvider; + +using Entity; +using System.Security.Policy; +using web_library.Book.Repository; +using web_library.Reservation.Model; +using web_library.Reservation.Repostiory; + +public class ReservationDataProvider : IReservationDataProvider +{ + private readonly IReservationRepository _reservationRepository; + //private readonly IBookRepository _bookRepository; + + public ReservationDataProvider(IReservationRepository reservationRepository, IBookRepository bookRepository) + { + _reservationRepository = reservationRepository; + //_bookRepository = bookRepository; + } + + private ReservationModel getModel(Reservation entity) + { + return new ReservationModel( + entity.Id, + entity.bookCopy.Book.Id, + entity.bookCopy.Book.ISBN, + entity.bookCopy.Book.Title, + entity.bookCopy.Book.Author, + entity.bookCopy.Book.Publisher, + entity.bookCopy.Book.Publication_date, + entity.bookCopyId, + entity.reservationStartDate, + entity.reservationEndDate + ); + } + public IEnumerable GetAll() + { + List list = new(); + foreach (var item in _reservationRepository.FindAll()) + { + list.Add(getModel(item)); + } + return list; + } + + + +} diff --git a/web-library/Reservation/Entity/Reservation.cs b/web-library/Reservation/Entity/Reservation.cs new file mode 100644 index 0000000..363a76f --- /dev/null +++ b/web-library/Reservation/Entity/Reservation.cs @@ -0,0 +1,35 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace web_library.Reservation.Entity; + +using System.ComponentModel.DataAnnotations; +using Book.Entity; +using web_library.Book.Entity; + +[Table("reservations")] +public class Reservation +{ + [Column("id")] + [Key] + public int Id { get; set; } + + [Column("reservation_start_date")] + public DateOnly reservationStartDate { get; set; } + + [Column("reservation_end_date")] + public DateOnly reservationEndDate { get; set; } + + [Column("book_copy_id")] + public int bookCopyId { get; set; } + + public BookCopy bookCopy { get; set; } = null!; + + public Reservation() { } + + public Reservation(DateOnly reservationStartDate, DateOnly reservationEndDate, int bookCopyId) + { + this.reservationStartDate = reservationStartDate; + this.reservationEndDate = reservationEndDate; + this.bookCopyId = bookCopyId; + } +} diff --git a/web-library/Reservation/Model/ReservationModel.cs b/web-library/Reservation/Model/ReservationModel.cs new file mode 100644 index 0000000..965cbd8 --- /dev/null +++ b/web-library/Reservation/Model/ReservationModel.cs @@ -0,0 +1,33 @@ +using web_library.Book.Entity; + +namespace web_library.Reservation.Model +{ + public class ReservationModel + { + public int ReservationId { get; set; } + public int BookId { get; set; } + public string ISBN { get; set; } + public string Title { get; set; } + public string Author { get; set; } + public string Publisher { get; set; } + public DateOnly Publication_date { get; set; } + public int BookCopyId { get; set; } + public DateOnly StartDate { get; set; } + public DateOnly EndDate { get; set; } + public ReservationModel() { } + + public ReservationModel(int reservationId, int bookId, string iSBN, string title, string author, string publisher, DateOnly publication_date, int bookCopyId, DateOnly startDate, DateOnly endDate) + { + ReservationId = reservationId; + BookId = bookId; + ISBN = iSBN; + Title = title; + Author = author; + Publisher = publisher; + Publication_date = publication_date; + BookCopyId = bookCopyId; + StartDate = startDate; + EndDate = endDate; + } + } +} diff --git a/web-library/Reservation/Repostiory/IReservationRepository.cs b/web-library/Reservation/Repostiory/IReservationRepository.cs new file mode 100644 index 0000000..39a2fcc --- /dev/null +++ b/web-library/Reservation/Repostiory/IReservationRepository.cs @@ -0,0 +1,9 @@ +namespace web_library.Reservation.Repostiory +{ + using Entity; + using web_library.Reservation.Entity; + + public interface IReservationRepository : IGenericRepository + { + } +} \ No newline at end of file diff --git a/web-library/Reservation/Repostiory/ReservationRepository.cs b/web-library/Reservation/Repostiory/ReservationRepository.cs new file mode 100644 index 0000000..c29dc9e --- /dev/null +++ b/web-library/Reservation/Repostiory/ReservationRepository.cs @@ -0,0 +1,37 @@ +namespace web_library.Reservation.Repostiory; +using Microsoft.EntityFrameworkCore; +using SharedExceptions; +using Entity; +public class ReservationRepository : IReservationRepository +{ + private readonly DataContext _context; + + public ReservationRepository(DataContext context) + { + _context = context; + } + + public void Add(Reservation entity) + { + _context.Reservations.Add(entity); + _context.SaveChanges(); + } + + public IEnumerable FindAll() + { + return _context.Reservations + .Include(b => b.bookCopy) + .ThenInclude(b => b.Book) + .ToList(); + } + + public Reservation FindByIdOrThrow(int id) + { + return _context.Reservations.Find(id) ?? throw new NotFoundException("Reservation " + id + " not found in repository"); + } + + public void Remove(Reservation entity) + { + throw new NotImplementedException(); + } +} diff --git a/web-library/Reservation/Request/CreateReservationRequest.cs b/web-library/Reservation/Request/CreateReservationRequest.cs new file mode 100644 index 0000000..48b98fd --- /dev/null +++ b/web-library/Reservation/Request/CreateReservationRequest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace web_library.Reservation.Request; +public class CreateReservationRequest +{ + public int book_copy_id { get; set; } + public DateOnly reservation_start_date { get; set; } + public CreateReservationRequest() + { + reservation_start_date = new(); + } +} diff --git a/web-library/Reservation/Service/IReservationService.cs b/web-library/Reservation/Service/IReservationService.cs new file mode 100644 index 0000000..605996d --- /dev/null +++ b/web-library/Reservation/Service/IReservationService.cs @@ -0,0 +1,9 @@ +using web_library.Reservation.Request; + +namespace web_library.Reservation.Service +{ + public interface IReservationService + { + void createReservation(CreateReservationRequest request); + } +} \ No newline at end of file diff --git a/web-library/Reservation/Service/ReservationService.cs b/web-library/Reservation/Service/ReservationService.cs new file mode 100644 index 0000000..3b55bf8 --- /dev/null +++ b/web-library/Reservation/Service/ReservationService.cs @@ -0,0 +1,30 @@ +namespace web_library.Reservation.Service; +using Book.Entity; +using Book.Repository; +using Entity; +using Repostiory; +using Request; +using web_library.Book.Entity; +using web_library.Book.Repository; +using web_library.Reservation.Entity; +using web_library.Reservation.Repostiory; +using web_library.Reservation.Request; + +public class ReservationService : IReservationService +{ + private readonly IReservationRepository _reservationRepository; + private readonly IBookCopyRepository _bookCopyRepository; + + public ReservationService(IReservationRepository reservationRepository, IBookCopyRepository bookCopyRepository) + { + _reservationRepository = reservationRepository; + _bookCopyRepository = bookCopyRepository; + } + + public void createReservation(CreateReservationRequest request) + { + BookCopy bookCopy = _bookCopyRepository.FindByIdOrThrow(request.book_copy_id); + Reservation reservation = new(request.reservation_start_date, request.reservation_start_date.AddDays(30), request.book_copy_id); + _reservationRepository.Add(reservation); + } +} diff --git a/web-library/Role/Repository/RoleRepository.cs b/web-library/Role/Repository/RoleRepository.cs index b91c1b5..4449931 100644 --- a/web-library/Role/Repository/RoleRepository.cs +++ b/web-library/Role/Repository/RoleRepository.cs @@ -1,5 +1,4 @@ using web_library.SharedExceptions; - namespace web_library.Role.Repository; public class RoleRepository : IRoleRepository @@ -11,7 +10,7 @@ public RoleRepository(DataContext dbContext) _dbContext = dbContext; } - public Entity.Role GetByIdOrThrow(int id) + public Entity.Role FindByIdOrThrow(int id) { Entity.Role? role = _dbContext.Roles.Find(id); @@ -21,7 +20,7 @@ public Entity.Role GetByIdOrThrow(int id) return role; } - public IEnumerable GetAll() + public IEnumerable FindAll() { return _dbContext.Roles.ToList(); } diff --git a/web-library/SharedExceptions/AlreadyExistsException.cs b/web-library/SharedExceptions/AlreadyExistsException.cs index 7eba5d7..b3b6104 100644 --- a/web-library/SharedExceptions/AlreadyExistsException.cs +++ b/web-library/SharedExceptions/AlreadyExistsException.cs @@ -1,6 +1,4 @@ -using System; - -namespace web_library.Shared; +namespace web_library.SharedExceptions; public class AlreadyExistsException : Exception { diff --git a/web-library/User/Repository/IUserBasicInfoRepository.cs b/web-library/User/Repository/IUserBasicInfoRepository.cs index 57ed8d6..5ca44ca 100644 --- a/web-library/User/Repository/IUserBasicInfoRepository.cs +++ b/web-library/User/Repository/IUserBasicInfoRepository.cs @@ -1,5 +1,6 @@ namespace web_library.User.Repository; using Entity; +using web_library.User.Entity; public interface IUserBasicInfoRepository { diff --git a/web-library/User/Repository/IUserRepository.cs b/web-library/User/Repository/IUserRepository.cs index 2ff4778..e61248a 100644 --- a/web-library/User/Repository/IUserRepository.cs +++ b/web-library/User/Repository/IUserRepository.cs @@ -1,5 +1,6 @@ namespace web_library.User.Repository; using Entity; +using web_library.User.Entity; public interface IUserRepository : IGenericRepository { diff --git a/web-library/User/Repository/UserBasicInfoRepository.cs b/web-library/User/Repository/UserBasicInfoRepository.cs index 5991d01..4c5374d 100644 --- a/web-library/User/Repository/UserBasicInfoRepository.cs +++ b/web-library/User/Repository/UserBasicInfoRepository.cs @@ -1,5 +1,6 @@ namespace web_library.User.Repository; using Entity; +using web_library.User.Entity; public class UserBasicInfoRepository : IUserBasicInfoRepository { diff --git a/web-library/User/Repository/UserRepository.cs b/web-library/User/Repository/UserRepository.cs index 1acc6ab..cec6f14 100644 --- a/web-library/User/Repository/UserRepository.cs +++ b/web-library/User/Repository/UserRepository.cs @@ -11,7 +11,7 @@ public UserRepository(DataContext dbContext) _dbContext = dbContext; } - public Entity.User GetByIdOrThrow(int id) + public Entity.User FindByIdOrThrow(int id) { Entity.User? user = _dbContext.Users.Find(id); @@ -26,7 +26,7 @@ public Entity.User GetByIdOrThrow(int id) return _dbContext.Users.SingleOrDefault(user => user.Email == email); } - public IEnumerable GetAll() + public IEnumerable FindAll() { return _dbContext.Users.ToList(); }