diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/SecurityConfiguration.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/SecurityConfiguration.java index 64111588f6..f07944271e 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/SecurityConfiguration.java +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/config/SecurityConfiguration.java @@ -101,6 +101,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() + .antMatchers("/api/books/purchase/**").authenticated() .antMatchers("/api/register").permitAll() .antMatchers("/api/activate").permitAll() .antMatchers("/api/authenticate").permitAll() diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java index bb052dc03c..6422d1a424 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java @@ -40,4 +40,11 @@ public interface BookService { * @param id the id of the entity */ void delete(Long id); + + /** + * Simulates purchasing a book by reducing the stock of a book by 1. + * @param id the id of the book + * @return Updated BookDTO, empty if not found, or throws exception if an error occurs. + */ + Optional purchase(Long id); } diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java index 00f68b84af..23cd59584c 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java @@ -5,6 +5,7 @@ import com.baeldung.jhipster5.domain.Book; import com.baeldung.jhipster5.repository.BookRepository; import com.baeldung.jhipster5.service.dto.BookDTO; import com.baeldung.jhipster5.service.mapper.BookMapper; +import com.baeldung.jhipster5.web.rest.errors.BadRequestAlertException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,4 +88,22 @@ public class BookServiceImpl implements BookService { log.debug("Request to delete Book : {}", id); bookRepository.deleteById(id); } + + @Override + public Optional purchase(Long id) { + Optional bookDTO = findOne(id); + if(bookDTO.isPresent()) { + int quantity = bookDTO.get().getQuantity(); + if(quantity > 0) { + bookDTO.get().setQuantity(quantity - 1); + Book book = bookMapper.toEntity(bookDTO.get()); + book = bookRepository.save(book); + return bookDTO; + } + else { + throw new BadRequestAlertException("Book is not in stock", "book", "notinstock"); + } + } + return Optional.empty(); + } } diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java index efcc2c3495..0360ea05ed 100644 --- a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java @@ -109,4 +109,10 @@ public class BookResource { bookService.delete(id); return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build(); } + + @GetMapping("/books/purchase/{id}") + public ResponseEntity purchase(@PathVariable Long id) { + Optional bookDTO = bookService.purchase(id); + return ResponseUtil.wrapOrNotFound(bookDTO); + } } diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html index 0aef73282a..4a3c20e841 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html @@ -38,6 +38,12 @@ class="btn btn-primary">   Edit + + diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts index 50a6bec9ad..6b84c0ba73 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts @@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { IBook } from 'app/shared/model/book.model'; +import { BookService } from 'app/entities/book/book.service'; +import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; @Component({ selector: 'jhi-book-detail', @@ -10,7 +12,7 @@ import { IBook } from 'app/shared/model/book.model'; export class BookDetailComponent implements OnInit { book: IBook; - constructor(protected activatedRoute: ActivatedRoute) {} + constructor(protected activatedRoute: ActivatedRoute, protected bookService: BookService) {} ngOnInit() { this.activatedRoute.data.subscribe(({ book }) => { @@ -21,4 +23,14 @@ export class BookDetailComponent implements OnInit { previousState() { window.history.back(); } + + purchase(id: number) { + console.log('Purchasing book ' + id); + this.bookService.purchase(id).subscribe( + (res: HttpResponse) => { + this.book = res.body; + }, + (res: HttpErrorResponse) => console.log(res.message) + ); + } } diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts index 3ff649d25d..bff511f7e6 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts @@ -38,6 +38,13 @@ export class BookService { .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res))); } + purchase(id: number): Observable { + console.log('Calling /api/books/purchase/ ' + id); + return this.http + .get(`${this.resourceUrl}/purchase/${id}`, { observe: 'response' }) + .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res))); + } + query(req?: any): Observable { const options = createRequestOption(req); return this.http