diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..3729ff0c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..1ff0c423 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..9491a2fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/DOUGLAS+HENRIQUE+SILVEIRA+ANDRADE.docx.pdf b/DOUGLAS+HENRIQUE+SILVEIRA+ANDRADE.docx.pdf new file mode 100644 index 00000000..37e0e43a Binary files /dev/null and b/DOUGLAS+HENRIQUE+SILVEIRA+ANDRADE.docx.pdf differ diff --git a/DataBase/GenerateBookTb.csv b/DataBase/GenerateBookTb.csv new file mode 100644 index 00000000..5eab5645 --- /dev/null +++ b/DataBase/GenerateBookTb.csv @@ -0,0 +1,5 @@ +"IdBook";"Name";"Genre";"Author";"WrittenDate";"BarCode";"AvailableQuantity";"RentedQuantity" +3;"Don Quixote";"Novel";"Miguel de Cervantes";"1924-01-01 00:00:00";"7227715787";6;2 +4;"A Passage to India";"Novel";"E.M. Forster";"1615-01-01 00:00:00";"5268865911";8;2 +5;"Beloved";"Novel";"Toni Morrison";"1987-01-01 00:00:00";"0069266027";2;2 +6;"Moby Dick";"Novel";"Herman Melville";"1851-01-01 00:00:00";"8472729595";10;0 diff --git a/DataBase/GenerateDataBase.sql b/DataBase/GenerateDataBase.sql new file mode 100644 index 00000000..3edab5ed --- /dev/null +++ b/DataBase/GenerateDataBase.sql @@ -0,0 +1,100 @@ +-- MySQL Workbench Forward Engineering + +SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; + +-- ----------------------------------------------------- +-- Schema mydb +-- ----------------------------------------------------- +-- ----------------------------------------------------- +-- Schema library_app_db +-- ----------------------------------------------------- + +-- ----------------------------------------------------- +-- Schema library_app_db +-- ----------------------------------------------------- +CREATE SCHEMA IF NOT EXISTS `library_app_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ; +USE `library_app_db` ; + +-- ----------------------------------------------------- +-- Table `library_app_db`.`booktb` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `library_app_db`.`booktb` ( + `IdBook` INT NOT NULL AUTO_INCREMENT, + `Name` VARCHAR(45) NOT NULL, + `Genre` VARCHAR(45) NULL DEFAULT NULL, + `Author` VARCHAR(45) NOT NULL, + `WrittenDate` DATETIME NULL DEFAULT NULL, + `BarCode` VARCHAR(45) NOT NULL, + `AvailableQuantity` INT NULL DEFAULT NULL, + `RentedQuantity` INT NULL DEFAULT NULL, + PRIMARY KEY (`IdBook`), + UNIQUE INDEX `idBookTb_UNIQUE` (`IdBook` ASC) VISIBLE) +ENGINE = InnoDB +AUTO_INCREMENT = 7 +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + + +-- ----------------------------------------------------- +-- Table `library_app_db`.`persontb` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `library_app_db`.`persontb` ( + `CPF` BIGINT NOT NULL, + `Name` VARCHAR(45) NOT NULL, + `Birth` DATE NULL DEFAULT NULL, + `Email` VARCHAR(45) NULL DEFAULT NULL, + `Phone` VARCHAR(45) NULL DEFAULT NULL, + PRIMARY KEY (`CPF`), + UNIQUE INDEX `IdPerson_UNIQUE` (`CPF` ASC) VISIBLE) +ENGINE = InnoDB +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + + +-- ----------------------------------------------------- +-- Table `library_app_db`.`renttb` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `library_app_db`.`renttb` ( + `IdRent` INT NOT NULL AUTO_INCREMENT, + `IdBook` INT NOT NULL, + `CPF` BIGINT NOT NULL, + `RentedDate` DATETIME NOT NULL, + `ReturnDate` DATETIME NOT NULL, + `Status` VARCHAR(45) NOT NULL, + PRIMARY KEY (`IdRent`), + INDEX `IdBook_idx` (`IdBook` ASC) VISIBLE, + INDEX `_idx` (`CPF` ASC) VISIBLE, + CONSTRAINT `CPF` + FOREIGN KEY (`CPF`) + REFERENCES `library_app_db`.`persontb` (`CPF`), + CONSTRAINT `IdBook` + FOREIGN KEY (`IdBook`) + REFERENCES `library_app_db`.`booktb` (`IdBook`) + ON DELETE CASCADE + ON UPDATE CASCADE) +ENGINE = InnoDB +AUTO_INCREMENT = 7 +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + + +-- ----------------------------------------------------- +-- Table `library_app_db`.`usertb` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `library_app_db`.`usertb` ( + `IdUser` INT NOT NULL AUTO_INCREMENT, + `Email` VARCHAR(45) NOT NULL, + `Password` VARCHAR(45) NOT NULL, + PRIMARY KEY (`IdUser`), + UNIQUE INDEX `IdUser_UNIQUE` (`IdUser` ASC) VISIBLE) +ENGINE = InnoDB +AUTO_INCREMENT = 4 +DEFAULT CHARACTER SET = utf8mb4 +COLLATE = utf8mb4_0900_ai_ci; + + +SET SQL_MODE=@OLD_SQL_MODE; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; +SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/DataBase/GeneratePersonTb.csv b/DataBase/GeneratePersonTb.csv new file mode 100644 index 00000000..17b9f8d3 --- /dev/null +++ b/DataBase/GeneratePersonTb.csv @@ -0,0 +1,5 @@ +"CPF";"Name";"Birth";"Email";"Phone" +10987654321;"Pessoa 2";"1999-01-01";"teste@gmail.com";"(31)111111111" +11111111111;"Pessoa 3";"1998-01-01";"aa@gmail.com";"(31)123456789" +11540075613;"Douglas";"1997-05-22";"testeemail@gmail.com";"(31)999973545" +12345678910;"Pessoa 1";"2000-01-01";"string@gmail.com";"(31)999999999" diff --git a/DataBase/GenerateRentTb.csv b/DataBase/GenerateRentTb.csv new file mode 100644 index 00000000..0aa803f0 --- /dev/null +++ b/DataBase/GenerateRentTb.csv @@ -0,0 +1,7 @@ +"IdRent";"IdBook";"CPF";"RentedDate";"ReturnDate";"Status" +1;4;11540075613;"2022-11-19 18:43:53";"2022-11-19 18:43:53";"Returned" +2;3;11540075613;"2022-11-20 14:24:42";"2022-11-20 14:24:42";"Rented" +3;3;11111111111;"2022-11-20 14:24:42";"2022-11-20 14:24:42";"Rented" +4;4;11111111111;"2022-11-20 14:24:42";"2022-11-20 14:24:42";"Returned" +5;5;12345678910;"2022-11-20 14:24:42";"2022-11-20 14:24:42";"Rented" +6;5;10987654321;"2022-11-20 14:24:42";"2022-11-20 14:24:42";"Rented" diff --git a/DataBase/GenerateUserTb.csv b/DataBase/GenerateUserTb.csv new file mode 100644 index 00000000..e5c24b19 --- /dev/null +++ b/DataBase/GenerateUserTb.csv @@ -0,0 +1,4 @@ +"IdUser";"Email";"Password" +1;"testeemail@gmail.com";"123456" +2;"teste";"123" +3;"admin";"admin" diff --git a/LibraryApp - Douglas Andrade.sln b/LibraryApp - Douglas Andrade.sln new file mode 100644 index 00000000..c932ef66 --- /dev/null +++ b/LibraryApp - Douglas Andrade.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32802.440 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryApp - Douglas Andrade", "LibrayApp\LibraryApp - Douglas Andrade.csproj", "{562C35BE-C13C-406B-BDDE-CAEFAE293973}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {562C35BE-C13C-406B-BDDE-CAEFAE293973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {562C35BE-C13C-406B-BDDE-CAEFAE293973}.Debug|Any CPU.Build.0 = Debug|Any CPU + {562C35BE-C13C-406B-BDDE-CAEFAE293973}.Release|Any CPU.ActiveCfg = Release|Any CPU + {562C35BE-C13C-406B-BDDE-CAEFAE293973}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B5A460EA-178F-407B-8EBE-A661D47B9780} + EndGlobalSection +EndGlobal diff --git a/LibrayApp/Controllers/BookTbController.cs b/LibrayApp/Controllers/BookTbController.cs new file mode 100644 index 00000000..f1382732 --- /dev/null +++ b/LibrayApp/Controllers/BookTbController.cs @@ -0,0 +1,205 @@ + +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Services; +using LibraryApp.Data; +using LibraryApp.Models; +using LibraryApp.Dto.Book; + +namespace LibraryApp.Controllers +{ + [ApiController] + [Route("api/[controller]")] + [Authorize] + public class BookTbController : ControllerBase + { + + private readonly ILogger _logger; + private readonly LibraryAppContext _context; + private readonly BookServices bookService; + + public BookTbController(ILogger logger, LibraryAppContext context) + { + _logger = logger; + _context = context; + bookService = new BookServices(_context); + } + + [AllowAnonymous] + [HttpGet("GetAllBooks")] + public async Task GetAll([FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetAllBooks"); + try + { + var books = bookService.GetAllBooks() + .Skip((pgNumber-1)*pgSize) + .Take(pgSize) + .ToList(); + if (books == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + _logger.LogInformation($"{books.Count} Books returned."); + return Ok(books); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [AllowAnonymous] + [HttpGet("GetBooksFromName/{name}")] + public async Task GetBooksFromName([FromRoute] string name, [FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetBooksFromName"); + try + { + var books = bookService.GetBooksFromName(name) + .Skip((pgNumber - 1) * pgSize) + .Take(pgSize) + .ToList(); ; + if (books == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + _logger.LogInformation($"{books.Count} Books returned."); + return Ok(books); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [AllowAnonymous] + [HttpGet("GetBooksFromBarCode/{barcode}")] + public async Task GetBooksFromBarCode([FromRoute] string barcode) + { + _logger.LogInformation("GetBooksFromBarCode"); + try + { + var books = bookService.GetBooksFromBarCode(barcode); + if (books == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + _logger.LogInformation($"Book '{books.Name}' returned."); + return Ok(books); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [AllowAnonymous] + [HttpGet("GetBooksFromId/{id}")] + public async Task GetBooksFromId([FromRoute] int id) + { + _logger.LogInformation("GetBooksFromId"); + + try + { + var books = bookService.GetBooksFromId(id); + if (books == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + _logger.LogInformation($"Book '{books.Name}' returned."); + return Ok(books); + } + catch (Exception ex) + { + + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPost] + public async Task CreateBook([FromBody] BookTbDto book) + { + _logger.LogInformation("CreateBook"); + + try + { + var bookReturn = await bookService.CreateBook(book); + if (bookReturn == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + _logger.LogInformation($"Book '{bookReturn.Name}' created."); + return CreatedAtAction("PostBook", new { name = bookReturn.Name }, bookReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPut("{id}")] + public async Task UpdateBook([FromRoute] int id, [FromBody] BookTb book) + { + _logger.LogInformation("UpdateBook"); + + if (id != book.IdBook) + { + _logger.LogWarning("No Content"); + return BadRequest(); + } + try + { + var bookReturn = await bookService.UpdateBook(book); + if (bookReturn == null) + { + return NotFound(); + } + _logger.LogInformation($"Book '{bookReturn.IdBook}' updated."); + return CreatedAtAction("UpdateBook", new { id = book.IdBook, name = bookReturn.Name }, bookReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + [HttpDelete("{id}")] + public async Task DeleteBook([FromRoute] int id) + { + _logger.LogInformation("DeleteBook"); + + try + { + var bookReturn = await bookService.DeleteBook(id); + if (bookReturn == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + _logger.LogInformation($"Book '{bookReturn.Name}' deleted."); + return CreatedAtAction("DeleteBook", new { id = bookReturn.IdBook, name = bookReturn.Name }, bookReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Controllers/PersonTbController.cs b/LibrayApp/Controllers/PersonTbController.cs new file mode 100644 index 00000000..ce3f3a60 --- /dev/null +++ b/LibrayApp/Controllers/PersonTbController.cs @@ -0,0 +1,180 @@ + +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Services; +using LibraryApp.Data; +using LibraryApp.Models; +using LibraryApp.Dto.Person; + +namespace LibraryApp.Controllers +{ + [ApiController] + [Route("api/[controller]")] + [Authorize] + public class PersonTbController : ControllerBase + { + + private readonly ILogger _logger; + private readonly LibraryAppContext _context; + private readonly PersonServices personService; + + public PersonTbController(ILogger logger, LibraryAppContext context) + { + _logger = logger; + _context = context; + personService = new PersonServices(_context); + } + + + [HttpGet("GetAllPeople")] + public async Task GetAllPeople([FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetAllPeople"); + try + { + var people = personService.GetAllPeople() + .Skip((pgNumber - 1) * pgSize) + .Take(pgSize) + .ToList(); + if (people == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + _logger.LogInformation($"'{people.Count}' Costumers returned."); + return Ok(people); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpGet("GetPersonFromName/{name}")] + public async Task GetPersonFromName([FromRoute] string name, [FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetPersonFromName"); + try + { + var people = personService.GetPersonFromName(name) + .Skip((pgNumber - 1) * pgSize) + .Take(pgSize) + .ToList(); + if (people == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + _logger.LogInformation($"'{people.Count}' Costumers returned."); + return Ok(people); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpGet("GetPersonFromCPF/{cpf}")] + public async Task GetPersonFromCpf([FromRoute] long cpf) + { + _logger.LogInformation("GetPersonFromCpf"); + + try + { + var person = personService.GetPersonFromCpf(cpf); + if (person == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + _logger.LogInformation($"Costumer '{person.Name}' returned."); + return Ok(person); + } + catch (Exception ex) + { + + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPost] + public async Task CreatePerson([FromBody] PersonTbDto person) + { + _logger.LogInformation("CreatePerson"); + + try + { + var personReturn = await personService.CreatePerson(person); + if (personReturn == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + _logger.LogInformation($"Costumer '{personReturn.Name}' created."); + return CreatedAtAction("PostPerson", new { name = personReturn.Name }, personReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPut("{id}")] + public async Task UpdatePerson([FromRoute] int id, [FromBody] PersonTb person) + { + _logger.LogInformation("UpdatePerson"); + + if (id != person.Cpf) + { + _logger.LogWarning("No Content"); + return BadRequest(); + } + try + { + var personReturn = await personService.UpdatePerson(person); + if (personReturn == null) + { + return NotFound(); + } + _logger.LogInformation($"Costumer '{personReturn.Name}' updated."); + return CreatedAtAction("UpdatePerson", new { CPF = person.Cpf, name = personReturn.Name }, personReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + [HttpDelete("{id}")] + public async Task DeletePerson([FromRoute] int id) + { + _logger.LogInformation("DeletePerson"); + + try + { + var personReturn = await personService.DeletePerson(id); + if (personReturn == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + _logger.LogInformation($"Costumer '{personReturn.Name}' deleted."); + return CreatedAtAction("DeletePerson", new { CPF = personReturn.Cpf, name = personReturn.Name }, personReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Controllers/RentTbController.cs b/LibrayApp/Controllers/RentTbController.cs new file mode 100644 index 00000000..1606eb30 --- /dev/null +++ b/LibrayApp/Controllers/RentTbController.cs @@ -0,0 +1,244 @@ + +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Services; +using LibraryApp.Data; +using LibraryApp.Models; +using LibraryApp.Dto.Rent; + +namespace LibraryApp.Controllers +{ + [ApiController] + [Route("api/[controller]")] + [Authorize] + public class RentTbController : ControllerBase + { + + private readonly ILogger _logger; + private readonly LibraryAppContext _context; + private readonly RentServices rentService; + + public RentTbController(ILogger logger, LibraryAppContext context) + { + _logger = logger; + _context = context; + rentService = new RentServices(_context); + } + + + [HttpGet("GetAllRents")] + public async Task GetAll([FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetAllRents"); + try + { + var rents = rentService.GetAllRents() + .Skip((pgNumber - 1) * pgSize) + .Take(pgSize) + .ToList(); + if (rents == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + return Ok(rents); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + [HttpGet("GetAllRentsStatus/{status}")] + public async Task GetAllRentsStatus([FromRoute] string status, [FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetAllRentsStatus"); + try + { + var rents = rentService.GetAllRentsStatus(status) + .Skip((pgNumber - 1) * pgSize) + .Take(pgSize) + .ToList(); + if (rents == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + return Ok(rents); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + [HttpGet("GetRentsFromRenterCpf/{cpf}")] + public async Task GetRentsFromRenterCpf([FromRoute] long cpf, [FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetRentsFromName"); + try + { + var rents = rentService.GetRentsFromRenterCpf(cpf) + .Skip((pgNumber - 1) * pgSize) + .Take(pgSize) + .ToList(); + if (rents == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + return Ok(rents); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpGet("GetRentsFromBookId/{id}")] + public async Task GetRentsFromBookId([FromRoute] int id, [FromQuery] int pgNumber, [FromQuery] int pgSize) + { + _logger.LogInformation("GetRentsFromBookId"); + + try + { + var rents = rentService.GetRentsFromBookId(id) + .Skip((pgNumber - 1) * pgSize) + .Take(pgSize) + .ToList(); + if (rents == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + return Ok(rents); + } + catch (Exception ex) + { + + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpGet("GetRentsFromId/{id}")] + public async Task GetRentsFromId([FromRoute] int id) + { + _logger.LogInformation("GetRentsFromId"); + + try + { + var rents = rentService.GetRentsFromId(id); + if (rents == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + return Ok(rents); + } + catch (Exception ex) + { + + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPost] + public async Task RentBook([FromBody] RentTbDto rent) + { + _logger.LogInformation("RentBook"); + + try + { + var rentReturn = await rentService.RentBook(rent); + if (rentReturn == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + return Ok(); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPut("ReturnBook")] + public async Task ReturnBook([FromBody] RentTb rent) + { + _logger.LogInformation("ReturnBook"); + + try + { + var rentReturn = await rentService.ReturnBook(rent); + if (rentReturn == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + return Ok(); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPut("{id}")] + public async Task UpdateRent([FromRoute] int id, [FromBody] RentTb rent) + { + _logger.LogInformation("UpdateRent"); + + if (id != rent.IdRent) + { + _logger.LogWarning("No Content"); + return BadRequest(); + } + try + { + var rentReturn = await rentService.UpdateRent(rent); + if (rentReturn == null) + { + return NotFound(); + } + return Ok(rentReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + [HttpDelete("{id}")] + public async Task DeleteRent([FromRoute] int id) + { + _logger.LogInformation("DeleteRent"); + + try + { + var rentReturn = await rentService.DeleteRent(id); + if (rentReturn == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + return Ok(rentReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Controllers/UserTbController.cs b/LibrayApp/Controllers/UserTbController.cs new file mode 100644 index 00000000..5ec419ed --- /dev/null +++ b/LibrayApp/Controllers/UserTbController.cs @@ -0,0 +1,133 @@ + +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Services; +using LibraryApp.Data; +using LibraryApp.Models; +using LibraryApp.Dto.User; +using Microsoft.Extensions.Configuration; + +namespace LibraryApp.Controllers +{ + [ApiController] + [Route("api/[controller]")] + [Authorize] + public class UserTbController : ControllerBase + { + + private readonly ILogger _logger; + private readonly LibraryAppContext _context; + private readonly UserServices userService; + private readonly IConfiguration _config; + + public UserTbController(ILogger logger, LibraryAppContext context, IConfiguration config) + { + _logger = logger; + _context = context; + _config = config; + userService = new UserServices(_context, _config); + } + + + + + [AllowAnonymous] + [HttpGet("Login")] + public async Task Login([FromQuery] UserTbDto user) + { + _logger.LogInformation("Login"); + + try + { + var token = userService.Login(user); + if (string.IsNullOrEmpty(token)) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + + return Ok(token); + } + catch (Exception ex) + { + + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPost] + public async Task CreateUser([FromBody] UserTbDto user) + { + _logger.LogInformation("CreateUser"); + + try + { + var userReturn = await userService.CreateUser(user); + if (userReturn == null) + { + _logger.LogWarning("No Content"); + return NoContent(); + } + return Ok(userReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + + [HttpPut("{id}")] + public async Task UpdateUser([FromRoute] int id, [FromBody] UserTb user) + { + _logger.LogInformation("UpdateUser"); + + if (id != user.IdUser) + { + _logger.LogWarning("No Content"); + return BadRequest(); + } + try + { + var userReturn = await userService.UpdateUser(user); + if (userReturn == null) + { + return NotFound(); + } + return Ok(userReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + [HttpDelete("{id}")] + public async Task DeleteUser([FromRoute] int id) + { + _logger.LogInformation("DeleteUser"); + + try + { + var userReturn = await userService.DeleteUser(id); + if (userReturn == null) + { + _logger.LogWarning("No Content"); + return NotFound(); + } + return Ok(userReturn); + } + catch (Exception ex) + { + _logger.LogError(ex.Message + ex.StackTrace); + return BadRequest(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Data/LibraryAppContext.cs b/LibrayApp/Data/LibraryAppContext.cs new file mode 100644 index 00000000..79fd42f0 --- /dev/null +++ b/LibrayApp/Data/LibraryAppContext.cs @@ -0,0 +1,148 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; +using LibraryApp.Models; + +#nullable disable + +namespace LibraryApp.Data +{ + public partial class LibraryAppContext : DbContext + { + public LibraryAppContext(DbContextOptions options) + : base(options) + { + } + + public virtual DbSet BookTbs { get; set; } + public virtual DbSet PersonTbs { get; set; } + public virtual DbSet RentTbs { get; set; } + public virtual DbSet UserTbs { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + optionsBuilder.UseMySql("name=LibraryAppDB", Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.30-mysql")); + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.HasCharSet("utf8mb4") + .UseCollation("utf8mb4_0900_ai_ci"); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.IdBook) + .HasName("PRIMARY"); + + entity.ToTable("booktb"); + + entity.HasIndex(e => e.IdBook, "idBookTb_UNIQUE") + .IsUnique(); + + entity.Property(e => e.Author) + .IsRequired() + .HasMaxLength(45); + + entity.Property(e => e.Genre).HasMaxLength(45); + + entity.Property(e => e.Name) + .IsRequired() + .HasMaxLength(45); + + entity.Property(e => e.WrittenDate).HasColumnType("datetime"); + + entity.Property(e => e.BarCode) + .IsRequired() + .HasMaxLength(45); + + entity.Property(e => e.AvailableQuantity).HasColumnType("int"); + + entity.Property(e => e.RentedQuantity).HasColumnType("int"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Cpf) + .HasName("PRIMARY"); + + entity.ToTable("persontb"); + + entity.HasIndex(e => e.Cpf, "IdPerson_UNIQUE") + .IsUnique(); + + entity.Property(e => e.Cpf) + .ValueGeneratedNever() + .HasColumnName("CPF"); + + entity.Property(e => e.Birth).HasColumnType("date"); + + entity.Property(e => e.Email).HasMaxLength(45); + + entity.Property(e => e.Name) + .IsRequired() + .HasMaxLength(45); + + entity.Property(e => e.Phone).HasMaxLength(45); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.IdRent) + .HasName("PRIMARY"); + + entity.ToTable("renttb"); + + entity.HasIndex(e => e.IdBook, "IdBook_idx"); + + entity.HasIndex(e => e.Cpf, "_idx"); + + entity.Property(e => e.Cpf).HasColumnName("CPF"); + + entity.Property(e => e.RentedDate).HasColumnType("datetime"); + + entity.Property(e => e.ReturnDate).HasColumnType("datetime"); + + entity.HasOne(d => d.CpfNavigation) + .WithMany(p => p.RentTbs) + .HasForeignKey(d => d.Cpf) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("CPF"); + + entity.HasOne(d => d.IdBookNavigation) + .WithMany(p => p.RentTbs) + .HasForeignKey(d => d.IdBook) + .HasConstraintName("IdBook"); + + entity.Property(e => e.Status) + .IsRequired() + .HasMaxLength(45); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.IdUser) + .HasName("PRIMARY"); + + entity.ToTable("usertb"); + + entity.HasIndex(e => e.IdUser, "IdUser_UNIQUE") + .IsUnique(); + + entity.Property(e => e.Email) + .IsRequired() + .HasMaxLength(45); + + entity.Property(e => e.Password) + .IsRequired() + .HasMaxLength(45); + }); + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + } +} diff --git a/LibrayApp/Dockerfile b/LibrayApp/Dockerfile new file mode 100644 index 00000000..66606099 --- /dev/null +++ b/LibrayApp/Dockerfile @@ -0,0 +1,22 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build +WORKDIR /src +COPY ["LibraryApp/LibraryApp.csproj", "LibraryApp/"] +RUN dotnet restore "LibraryApp/LibraryApp.csproj" +COPY . . +WORKDIR "/src/LibraryApp" +RUN dotnet build "LibraryApp.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "LibraryApp.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "LibraryApp.dll"] \ No newline at end of file diff --git a/LibrayApp/Dtos/Book/BookTbDto.cs b/LibrayApp/Dtos/Book/BookTbDto.cs new file mode 100644 index 00000000..2039dc9f --- /dev/null +++ b/LibrayApp/Dtos/Book/BookTbDto.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Dto.Book +{ + public partial class BookTbDto + { + public string Name { get; set; } + public string Genre { get; set; } + public string Author { get; set; } + public DateTime? WrittenDate { get; set; } + public string BarCode { get; set; } + public int AvailableQuantity { get; set; } + public int RentedQuantity { get; set; } + } +} diff --git a/LibrayApp/Dtos/Person/PersonTbDto.cs b/LibrayApp/Dtos/Person/PersonTbDto.cs new file mode 100644 index 00000000..3d0af715 --- /dev/null +++ b/LibrayApp/Dtos/Person/PersonTbDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Dto.Person +{ + public partial class PersonTbDto + { + public long Cpf { get; set; } + public string Name { get; set; } + public DateTime? Birth { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + } +} diff --git a/LibrayApp/Dtos/Rent/RentTbDto.cs b/LibrayApp/Dtos/Rent/RentTbDto.cs new file mode 100644 index 00000000..30ce9864 --- /dev/null +++ b/LibrayApp/Dtos/Rent/RentTbDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Dto.Rent +{ + public partial class RentTbDto + { + public int IdBook { get; set; } + public long Cpf { get; set; } + public DateTime RentedDate { get; set; } + public DateTime ReturnDate { get; set; } + } +} diff --git a/LibrayApp/Dtos/User/UserTbDto.cs b/LibrayApp/Dtos/User/UserTbDto.cs new file mode 100644 index 00000000..db7f1cca --- /dev/null +++ b/LibrayApp/Dtos/User/UserTbDto.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Dto.User +{ + public partial class UserTbDto + { + public string Email { get; set; } + public string Password { get; set; } + } +} diff --git a/LibrayApp/LibraryApp - Douglas Andrade.csproj b/LibrayApp/LibraryApp - Douglas Andrade.csproj new file mode 100644 index 00000000..a952d11d --- /dev/null +++ b/LibrayApp/LibraryApp - Douglas Andrade.csproj @@ -0,0 +1,31 @@ + + + + net5.0 + 1ef34cc1-ff95-4457-a74d-7f7939bd5dfc + Linux + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/LibrayApp/LibrayApp.csproj b/LibrayApp/LibrayApp.csproj new file mode 100644 index 00000000..88a55094 --- /dev/null +++ b/LibrayApp/LibrayApp.csproj @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/LibrayApp/Models/BookTb.cs b/LibrayApp/Models/BookTb.cs new file mode 100644 index 00000000..7ea67d90 --- /dev/null +++ b/LibrayApp/Models/BookTb.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Models +{ + public partial class BookTb + { + public BookTb() + { + RentTbs = new HashSet(); + } + + public int IdBook { get; set; } + public string Name { get; set; } + public string Genre { get; set; } + public string Author { get; set; } + public DateTime? WrittenDate { get; set; } + public string BarCode { get; set; } + public int AvailableQuantity { get; set; } + public int RentedQuantity { get; set; } + + public virtual ICollection RentTbs { get; set; } + } +} diff --git a/LibrayApp/Models/PersonTb.cs b/LibrayApp/Models/PersonTb.cs new file mode 100644 index 00000000..5b74a73c --- /dev/null +++ b/LibrayApp/Models/PersonTb.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Models +{ + public partial class PersonTb + { + public PersonTb() + { + RentTbs = new HashSet(); + } + + public long Cpf { get; set; } + public string Name { get; set; } + public DateTime? Birth { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + + public virtual ICollection RentTbs { get; set; } + } +} diff --git a/LibrayApp/Models/RentTb.cs b/LibrayApp/Models/RentTb.cs new file mode 100644 index 00000000..073f971e --- /dev/null +++ b/LibrayApp/Models/RentTb.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Models +{ + public partial class RentTb + { + public int IdRent { get; set; } + public int IdBook { get; set; } + public long Cpf { get; set; } + public DateTime RentedDate { get; set; } + public DateTime ReturnDate { get; set; } + public string Status { get; set; } + + public virtual PersonTb CpfNavigation { get; set; } + public virtual BookTb IdBookNavigation { get; set; } + } +} diff --git a/LibrayApp/Models/UserTb.cs b/LibrayApp/Models/UserTb.cs new file mode 100644 index 00000000..b3736ebd --- /dev/null +++ b/LibrayApp/Models/UserTb.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +#nullable disable + +namespace LibraryApp.Models +{ + public partial class UserTb + { + public int IdUser { get; set; } + public string Email { get; set; } + public string Password { get; set; } + } +} diff --git a/LibrayApp/Program.cs b/LibrayApp/Program.cs new file mode 100644 index 00000000..e0f68edb --- /dev/null +++ b/LibrayApp/Program.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace LibraryApp +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + + } +} diff --git a/LibrayApp/Properties/launchSettings.json b/LibrayApp/Properties/launchSettings.json new file mode 100644 index 00000000..dfb8eb19 --- /dev/null +++ b/LibrayApp/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:55362", + "sslPort": 44383 + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "LibraryApp": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": "true", + "applicationUrl": "https://localhost:5001;http://localhost:5000" + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "publishAllPorts": true, + "useSSL": true + } + } +} \ No newline at end of file diff --git a/LibrayApp/Repositories/BookRepository.cs b/LibrayApp/Repositories/BookRepository.cs new file mode 100644 index 00000000..4227e5a7 --- /dev/null +++ b/LibrayApp/Repositories/BookRepository.cs @@ -0,0 +1,162 @@ +using LibraryApp.Data; +using LibraryApp.Dto.Book; +using LibraryApp.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace LibraryApp.Repositories +{ + public class BookRepository + { + private readonly LibraryAppContext _context; + + public BookRepository(LibraryAppContext context) + { + _context = context; + } + + public IEnumerable GetAllBooksRepo() + { + try + { + IEnumerable books = null; + books = (from book in _context.BookTbs select book).ToList(); + foreach (var book in books) + { + var rentList = (from rents in _context.RentTbs where rents.IdBook.Equals(book.IdBook) select rents).ToList(); + foreach (var rent in rentList) + { + book.RentTbs.Add(rent); + } + } + return books.OrderBy(b => b.Name); + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetBooksFromNameRepo(string name) + { + try + { + IEnumerable bookList = null; + bookList = (from books in _context.BookTbs where books.Name.Contains(name) select books).ToList(); + foreach (var book in bookList) + { + var rentList = (from rents in _context.RentTbs where rents.IdBook.Equals(book.IdBook) select rents).ToList(); + foreach (var rent in rentList) + { + book.RentTbs.Add(rent); + } + } + + return bookList; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public BookTb GetBooksFromBarCodeRepo(string barcode) + { + try + { + BookTb book = null; + book = (from books in _context.BookTbs where books.BarCode.Equals(barcode) select books).FirstOrDefault(); + var rentList = (from rents in _context.RentTbs where rents.IdBook.Equals(book.IdBook) select rents).ToList(); + foreach (var rent in rentList) + { + book.RentTbs.Add(rent); + } + return book; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public BookTb GetBooksFromIdRepo(int id) + { + try + { + BookTb book = null; + book = (from books in _context.BookTbs where books.IdBook.Equals(id) select books).FirstOrDefault(); + var rentList = (from rents in _context.RentTbs where rents.IdBook.Equals(book.IdBook) select rents).ToList(); + foreach (var rent in rentList) + { + book.RentTbs.Add(rent); + } + return book; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task CreateBookRepo(BookTbDto bookDto) + { + try + { + BookTb book = new BookTb + { + Name = bookDto.Name, + Author = bookDto.Author, + Genre = bookDto.Genre, + WrittenDate = bookDto.WrittenDate, + BarCode = bookDto.BarCode, + AvailableQuantity = bookDto.AvailableQuantity, + RentedQuantity = bookDto.RentedQuantity + }; + _context.BookTbs.Add(book); + await _context.SaveChangesAsync(); + + return bookDto; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdateBookRepo(BookTb book) + { + try + { + _context.Entry(book).State = EntityState.Modified; + await _context.SaveChangesAsync(); + + return book; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task DeleteBookRepo(int id) + { + try + { + var book = (from books in _context.BookTbs select books).FirstOrDefault(); + if (book == null) + { + return null; + } + _context.BookTbs.Remove(book); + await _context.SaveChangesAsync(); + + return book; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Repositories/PersonRepository.cs b/LibrayApp/Repositories/PersonRepository.cs new file mode 100644 index 00000000..efafde74 --- /dev/null +++ b/LibrayApp/Repositories/PersonRepository.cs @@ -0,0 +1,143 @@ +using LibraryApp.Data; +using LibraryApp.Dto.Person; +using LibraryApp.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace LibraryApp.Repositories +{ + public class PersonRepository + { + private readonly LibraryAppContext _context; + + public PersonRepository(LibraryAppContext context) + { + _context = context; + } + + public IEnumerable GetAllPeopleRepo() + { + try + { + IEnumerable people = null; + people = (from person in _context.PersonTbs select person).ToList(); + foreach (var person in people) + { + var rentList = (from rents in _context.RentTbs where rents.Cpf.Equals(person.Cpf) select rents).ToList(); + foreach (var rent in rentList) + { + person.RentTbs.Add(rent); + } + } + return people.OrderBy(p => p.Name); + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetPersonFromNameRepo(string name) + { + try + { + IEnumerable peopleList = null; + peopleList = (from people in _context.PersonTbs where people.Name.Contains(name) select people).ToList(); + foreach (var person in peopleList) + { + var rentList = (from rents in _context.RentTbs where rents.Cpf.Equals(person.Cpf) select rents).ToList(); + foreach (var rent in rentList) + { + person.RentTbs.Add(rent); + } + } + + return peopleList; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public PersonTb GetPersonFromCpfRepo(long cpf) + { + try + { + PersonTb person = null; + person = (from people in _context.PersonTbs where people.Cpf.Equals(cpf) select people).FirstOrDefault(); + var rentList = (from rents in _context.RentTbs where rents.Cpf.Equals(person.Cpf) select rents).ToList(); + foreach (var rent in rentList) + { + person.RentTbs.Add(rent); + } + return person; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task CreatePersonRepo(PersonTbDto personDto) + { + try + { + PersonTb person = new PersonTb + { + Name = personDto.Name, + Cpf = personDto.Cpf, + Email = personDto.Email, + Phone = personDto.Phone, + Birth = personDto.Birth + }; + _context.PersonTbs.Add(person); + await _context.SaveChangesAsync(); + + return personDto; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdatePersonRepo(PersonTb person) + { + try + { + _context.Entry(person).State = EntityState.Modified; + await _context.SaveChangesAsync(); + + return person; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task DeletePersonRepo(int id) + { + try + { + var person = (from people in _context.PersonTbs select people).FirstOrDefault(); + if (person == null) + { + return null; + } + _context.PersonTbs.Remove(person); + await _context.SaveChangesAsync(); + + return person; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Repositories/RentRepository.cs b/LibrayApp/Repositories/RentRepository.cs new file mode 100644 index 00000000..e17818b4 --- /dev/null +++ b/LibrayApp/Repositories/RentRepository.cs @@ -0,0 +1,168 @@ +using LibraryApp.Data; +using LibraryApp.Dto.Rent; +using LibraryApp.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace LibraryApp.Repositories +{ + public class RentRepository + { + private readonly LibraryAppContext _context; + + public RentRepository(LibraryAppContext context) + { + _context = context; + } + + public IEnumerable GetAllRentsRepo() + { + try + { + IEnumerable rents = null; + rents = (from rent in _context.RentTbs select rent).ToList(); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetAllRentsStatusRepo(string status) + { + try + { + IEnumerable rents = null; + rents = (from rent in _context.RentTbs where rent.Status.Equals(status) select rent).ToList(); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetRentsFromRenterCpfRepo(long cpf) + { + try + { + IEnumerable rent = null; + rent = (from rents in _context.RentTbs where rents.Cpf.Equals(cpf) select rents).ToList(); + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public IEnumerable GetRentsFromBookIdRepo(int id) + { + try + { + IEnumerable rent = null; + rent = (from rents in _context.RentTbs where rents.IdBook.Equals(id) select rents).ToList(); + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetRentsFromIdRepo(int id) + { + try + { + IEnumerable rent = null; + rent = (from rents in _context.RentTbs where rents.IdRent.Equals(id) select rents).ToList(); + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task RentBookRepo(RentTbDto rentDto) + { + try + { + + RentTb rent = new RentTb + { + IdBook = rentDto.IdBook, + Cpf = rentDto.Cpf, + RentedDate = rentDto.RentedDate, + ReturnDate = rentDto.ReturnDate, + Status = "Rented" + }; + _context.RentTbs.Add(rent); + await _context.SaveChangesAsync(); + + rent = (from rents in _context.RentTbs select rents).OrderByDescending(r=>r.IdRent).FirstOrDefault(); + + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task ReturnBookRepo(RentTb rent) + { + try + { + rent.Status = "Returned"; + _context.Entry(rent).State = EntityState.Modified; + await _context.SaveChangesAsync(); + + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdateRentRepo(RentTb rent) + { + try + { + _context.Entry(rent).State = EntityState.Modified; + await _context.SaveChangesAsync(); + + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task DeleteRentRepo(int id) + { + try + { + var rent = (from rents in _context.RentTbs select rents).FirstOrDefault(); + if (rent == null) + { + return null; + } + _context.RentTbs.Remove(rent); + await _context.SaveChangesAsync(); + + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Repositories/UserRepository.cs b/LibrayApp/Repositories/UserRepository.cs new file mode 100644 index 00000000..e73b6a27 --- /dev/null +++ b/LibrayApp/Repositories/UserRepository.cs @@ -0,0 +1,96 @@ +using LibraryApp.Data; +using LibraryApp.Dto.User; +using LibraryApp.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace LibraryApp.Repositories +{ + public class UserRepository + { + private readonly LibraryAppContext _context; + + public UserRepository(LibraryAppContext context) + { + _context = context; + } + + public UserTbDto LoginRepo(UserTbDto userDto) + { + try + { + UserTb user = null; + user = (from users in _context.UserTbs where users.Email == userDto.Email select users).FirstOrDefault(); + if (user == null) + throw new Exception("Invalid Email."); + else if (!user.Password.Equals(userDto.Password)) + throw new Exception("Invalid Password."); + else + return userDto; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task CreateUserRepo(UserTbDto userDto) + { + try + { + UserTb user = new UserTb + { + Email = userDto.Email, + Password = userDto.Password + }; + _context.UserTbs.Add(user); + await _context.SaveChangesAsync(); + + return userDto; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdateUserRepo(UserTb user) + { + try + { + _context.Entry(user).State = EntityState.Modified; + await _context.SaveChangesAsync(); + + return user; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task DeleteUserRepo(int id) + { + try + { + var user = (from users in _context.UserTbs select users).FirstOrDefault(); + if (user == null) + { + return null; + } + _context.UserTbs.Remove(user); + await _context.SaveChangesAsync(); + + return user; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Services/BookServices.cs b/LibrayApp/Services/BookServices.cs new file mode 100644 index 00000000..230fbc5f --- /dev/null +++ b/LibrayApp/Services/BookServices.cs @@ -0,0 +1,119 @@ +using LibraryApp.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Repositories; +using LibraryApp.Data; +using LibraryApp.Dto.Book; +using Microsoft.Extensions.Logging; + +namespace LibraryApp.Services +{ + public class BookServices + { + private LibraryAppContext _context { get; set; } + private readonly BookRepository bookRepository; + public BookServices(LibraryAppContext context) + { + _context = context; + bookRepository = new BookRepository(_context); + } + + + + public IEnumerable GetAllBooks() + { + try + { + IEnumerable books = bookRepository.GetAllBooksRepo(); + return books; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetBooksFromName(string name) + { + try + { + IEnumerable books = null; + books = bookRepository.GetBooksFromNameRepo(name); + return books; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public BookTb GetBooksFromId(int id) + { + try + { + BookTb books = null; + books = bookRepository.GetBooksFromIdRepo(id); + return books; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public BookTb GetBooksFromBarCode(string barcode) + { + try + { + BookTb books = null; + books = bookRepository.GetBooksFromBarCodeRepo(barcode); + return books; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task CreateBook (BookTbDto book) + { + try + { + BookTbDto books = null; + books = await bookRepository.CreateBookRepo(book); + return books; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdateBook(BookTb book) + { + try + { + BookTb books = null; + books = await bookRepository.UpdateBookRepo(book); + return books; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public async Task DeleteBook(int id) + { + try + { + BookTb book = null; + book = await bookRepository.DeleteBookRepo(id); + return book; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Services/PersonServices.cs b/LibrayApp/Services/PersonServices.cs new file mode 100644 index 00000000..848656fa --- /dev/null +++ b/LibrayApp/Services/PersonServices.cs @@ -0,0 +1,106 @@ +using LibraryApp.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Repositories; +using LibraryApp.Data; +using LibraryApp.Dto.Person; +using Microsoft.Extensions.Logging; + +namespace LibraryApp.Services +{ + public class PersonServices + { + private LibraryAppContext _context { get; set; } + private readonly PersonRepository personRepository; + public PersonServices(LibraryAppContext context) + { + _context = context; + personRepository = new PersonRepository(_context); + } + + + + public IEnumerable GetAllPeople() + { + try + { + IEnumerable people = personRepository.GetAllPeopleRepo(); + return people; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetPersonFromName(string name) + { + try + { + IEnumerable people = null; + people = personRepository.GetPersonFromNameRepo(name); + return people; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public PersonTb GetPersonFromCpf(long cpf) + { + try + { + PersonTb people = null; + people = personRepository.GetPersonFromCpfRepo(cpf); + return people; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task CreatePerson (PersonTbDto person) + { + try + { + PersonTbDto people = null; + people = await personRepository.CreatePersonRepo(person); + return people; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdatePerson(PersonTb person) + { + try + { + PersonTb people = null; + people = await personRepository.UpdatePersonRepo(person); + return people; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public async Task DeletePerson(int id) + { + try + { + PersonTb person = null; + person = await personRepository.DeletePersonRepo(id); + return person; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Services/RentServices.cs b/LibrayApp/Services/RentServices.cs new file mode 100644 index 00000000..e0c15e5b --- /dev/null +++ b/LibrayApp/Services/RentServices.cs @@ -0,0 +1,173 @@ +using LibraryApp.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Repositories; +using LibraryApp.Data; +using LibraryApp.Dto.Rent; +using Microsoft.Extensions.Logging; + +namespace LibraryApp.Services +{ + public class RentServices + { + private LibraryAppContext _context { get; set; } + private readonly RentRepository rentRepository; + private readonly BookRepository bookRepository; + private readonly PersonRepository personRepository; + public RentServices(LibraryAppContext context) + { + _context = context; + rentRepository = new RentRepository(_context); + bookRepository = new BookRepository(_context); + personRepository = new PersonRepository(_context); + } + + + + public IEnumerable GetAllRents() + { + try + { + IEnumerable rents = rentRepository.GetAllRentsRepo(); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public IEnumerable GetAllRentsStatus(string status) + { + try + { + IEnumerable rents = rentRepository.GetAllRentsStatusRepo(status); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public IEnumerable GetRentsFromRenterCpf(long cpf) + { + try + { + IEnumerable rents = null; + rents = rentRepository.GetRentsFromRenterCpfRepo(cpf); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public IEnumerable GetRentsFromBookId(int id) + { + try + { + IEnumerable rents = null; + rents = rentRepository.GetRentsFromBookIdRepo(id); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public IEnumerable GetRentsFromId(int id) + { + try + { + IEnumerable rents = null; + rents = rentRepository.GetRentsFromIdRepo(id); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task RentBook(RentTbDto rent) + { + try + { + RentTb rents = null; + + var book = bookRepository.GetBooksFromIdRepo(rent.IdBook); + + if (book.AvailableQuantity <= book.RentedQuantity) + throw new Exception("No books available."); + + rents = await rentRepository.RentBookRepo(rent); + + book.RentTbs.Add(rents); + book.RentedQuantity += 1; + + var person = personRepository.GetPersonFromCpfRepo(rent.Cpf); + person.RentTbs.Add(rents); + + await bookRepository.UpdateBookRepo(book); + await personRepository.UpdatePersonRepo(person); + + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task ReturnBook(RentTb rent) + { + try + { + RentTb rents = null; + + rents = await rentRepository.ReturnBookRepo(rent); + + var book = bookRepository.GetBooksFromIdRepo(rent.IdBook); + + book.RentedQuantity += 1; + + await bookRepository.UpdateBookRepo(book); + + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdateRent(RentTb rent) + { + try + { + RentTb rents = null; + rents = await rentRepository.UpdateRentRepo(rent); + return rents; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public async Task DeleteRent(int id) + { + try + { + RentTb rent = null; + rent = await rentRepository.DeleteRentRepo(id); + return rent; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Services/UserServices.cs b/LibrayApp/Services/UserServices.cs new file mode 100644 index 00000000..27be2976 --- /dev/null +++ b/LibrayApp/Services/UserServices.cs @@ -0,0 +1,104 @@ +using LibraryApp.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LibraryApp.Repositories; +using LibraryApp.Data; +using LibraryApp.Dto.User; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; +using System.Text; +using System.Security.Claims; +using System.IdentityModel.Tokens.Jwt; +using Microsoft.Extensions.Configuration; + +namespace LibraryApp.Services +{ + public class UserServices + { + private LibraryAppContext _context { get; set; } + private readonly UserRepository userRepository; + private readonly IConfiguration _config; + public UserServices(LibraryAppContext context, IConfiguration config) + { + _context = context; + _config = config; + userRepository = new UserRepository(_context); + } + + public string Login(UserTbDto userDto) + { + try + { + UserTbDto user = null; + user = userRepository.LoginRepo(userDto); + var token = GenerateToken(user); + return token; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + private string GenerateToken(UserTbDto user) + { + var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_config["Jwt:Key"])); + var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier,user.Email) + }; + var token = new JwtSecurityToken(_config["Jwt:Issuer"], + _config["Jwt:Audience"], + claims: claims, + expires: DateTime.Now.AddMinutes(60), + signingCredentials: credentials); + + return new JwtSecurityTokenHandler().WriteToken(token); + + } + + public async Task CreateUser (UserTbDto user) + { + try + { + UserTbDto users = null; + users = await userRepository.CreateUserRepo(user); + return users; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + + public async Task UpdateUser(UserTb user) + { + try + { + UserTb users = null; + users = await userRepository.UpdateUserRepo(user); + return users; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + public async Task DeleteUser(int id) + { + try + { + UserTb user = null; + user = await userRepository.DeleteUserRepo(id); + return user; + } + catch (Exception ex) + { + throw new Exception(ex.Message + ex.StackTrace); + } + } + } +} diff --git a/LibrayApp/Startup.cs b/LibrayApp/Startup.cs new file mode 100644 index 00000000..f317e11f --- /dev/null +++ b/LibrayApp/Startup.cs @@ -0,0 +1,118 @@ +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace LibraryApp +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + string mySqlConnection = + Configuration.GetConnectionString("LibraryAppDB"); + + services.AddDbContextPool(options => + options.UseMySql(mySqlConnection, + ServerVersion.AutoDetect(mySqlConnection))); + + services.AddControllers().AddJsonOptions(x => + x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve); + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { + options.RequireHttpsMetadata = false; + options.SaveToken = true; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = false, + ValidateAudience = false, + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + ValidIssuer = Configuration["Jwt:Issuer"], + ValidAudience = Configuration["Jwt:Audience"], + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) + }; + }); + + services.AddEntityFrameworkMySql(); + + services.AddControllers(); + + services.AddSwaggerGen(c => + { + var securitySchema = new OpenApiSecurityScheme + { + Description = + "JWT Authorization Header - utilizado com Bearer Authentication.\r\n\r\n" + + "Digite 'Bearer' [espaço] e então seu token no campo abaixo.\r\n\r\n" + + "Exemplo (informar sem as aspas): 'Bearer 12345abcdef'", + Name = "Authorization", + In = ParameterLocation.Header, + Type = SecuritySchemeType.ApiKey, + Scheme = "Bearer", + BearerFormat = "JWT", + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "Bearer" + } + }; + c.AddSecurityDefinition("Bearer", securitySchema); + var securityRequirement = new OpenApiSecurityRequirement + { + {securitySchema, new [] {"Bearer"}} + }; + + c.AddSecurityRequirement(securityRequirement); + + c.SwaggerDoc("v1", new OpenApiInfo { Title = "LibraryApp", Version = "v1" }); + }); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "LibraryApp v1")); + } + + app.UseHttpsRedirection(); + + app.UseRouting(); + + app.UseAuthentication(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } +} diff --git a/LibrayApp/appsettings.Development.json b/LibrayApp/appsettings.Development.json new file mode 100644 index 00000000..8983e0fc --- /dev/null +++ b/LibrayApp/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/LibrayApp/appsettings.json b/LibrayApp/appsettings.json new file mode 100644 index 00000000..bde52596 --- /dev/null +++ b/LibrayApp/appsettings.json @@ -0,0 +1,20 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + + "Jwt": { + "Key": "ACDt1vR3lXToPQ1g3MyN", //Generate random String from https://www.random.org/strings + "Issuer": "https://localhost:44383/", //Project Property-> Debug-> IIS-->App URL (you can local host url as well) + "Audience": "https://localhost:44383/" + }, + "ConnectionStrings": { + "LibraryAppDB": "Server=localhost;Database=library_app_db;Uid=root;Pwd=root" + + } +}