Fakultas Ilmu Komputer UI

Commit af749c32 authored by MUHAMMAD AAQIL ABDULLAH's avatar MUHAMMAD AAQIL ABDULLAH
Browse files

Implement product card

parent b34908b1
......@@ -30,6 +30,7 @@ dependencies {
implementation 'org.springframework.security:spring-security-test'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'io.micrometer:micrometer-registry-prometheus'
implementation 'commons-fileupload:commons-fileupload:1.4'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
......
......@@ -3,11 +3,9 @@ package id.ac.ui.cs.advprog.landiandfriends;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LandiAndFriendsApplication {
public static void main(String[] args) {
SpringApplication.run(LandiAndFriendsApplication.class, args);
}
......
......@@ -24,14 +24,11 @@ public class AdminController {
private final UserServiceImpl userService;
private final PaymentServiceImpl paymentService;
String usernameAttr = "username";
@GetMapping(path={"/list-user"})
public String allUser(Principal principal, Model model){
if(principal != null){
model.addAttribute(usernameAttr, principal.getName());
} else {
model.addAttribute(usernameAttr, "");
}
model.addAttribute(usernameAttr,principal != null ? principal.getName() : "");
List<User> allUsers = userService.allUsers();
model.addAttribute("all_users",allUsers);
return "listuser";
......@@ -62,19 +59,6 @@ public class AdminController {
return ResponseEntity.ok(user);
}
@GetMapping(path="/admin-add-card")
public String addPayment(Model model){
model.addAttribute("form", new AddPaymentForm());
return "admin-add-card";
}
@PostMapping(path="/admin-add-card")
public String addPayment(@RequestBody AddPaymentForm form) {
PaymentModel payment = paymentService.addPayment(form.getName(), form.getCardName(), form.getCardNumber(), form.getExpiryDate(), form.getCvv());
paymentService.savePayment(payment);
return "redirect:/admin/list-payment";
}
@GetMapping(path="/list-payment")
public String paymentList(Model model){
model.addAttribute("payments", paymentService.getAllPayments());
......
......@@ -3,6 +3,8 @@ package id.ac.ui.cs.advprog.landiandfriends.controller;
import id.ac.ui.cs.advprog.landiandfriends.model.Articles;
import id.ac.ui.cs.advprog.landiandfriends.model.Role;
import id.ac.ui.cs.advprog.landiandfriends.model.User;
import id.ac.ui.cs.advprog.landiandfriends.model.productcard.ArticleProductCard;
import id.ac.ui.cs.advprog.landiandfriends.model.productcard.BookProductCard;
import id.ac.ui.cs.advprog.landiandfriends.repository.UserRepository;
import id.ac.ui.cs.advprog.landiandfriends.service.ArticleServiceImpl;
import id.ac.ui.cs.advprog.landiandfriends.service.BookServiceImpl;
......@@ -20,6 +22,8 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.util.List;
import java.security.Principal;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Controller
......@@ -34,7 +38,11 @@ public class BaseController {
@GetMapping(path = "/")
public String getHomePage(Principal principal, Model model) {
model.addAttribute("books", bookStoreService.getRandomBooks(6));
model.addAttribute("products",
Stream.concat(
bookStoreService.getRandomBooks(6).stream().map(BookProductCard::new),
articleService.getRandomArticles(6).stream().map(ArticleProductCard::new))
.collect(Collectors.toList()));
model.addAttribute(USERNAME_ATTR, (principal != null) ? principal.getName() : "");
return "home";
......@@ -42,11 +50,8 @@ public class BaseController {
@GetMapping(path = "/articles")
public String getArticles(Model model,Principal principal) {
if(principal != null){
model.addAttribute(USERNAME_ATTR, principal.getName());
} else {
model.addAttribute(USERNAME_ATTR, "");
}
model.addAttribute(USERNAME_ATTR, (principal != null) ? principal.getName() : "");
List<Articles> allArticles = articleService.getAllArticles();
model.addAttribute("all_art",allArticles);
try{
......@@ -60,11 +65,8 @@ public class BaseController {
}
@GetMapping( "/articles/{id}")
public String getArticle(@PathVariable("id") Integer id , Model model,Principal principal ){
if(principal != null){
model.addAttribute(USERNAME_ATTR, principal.getName());
} else {
model.addAttribute(USERNAME_ATTR, "");
}
model.addAttribute(USERNAME_ATTR, (principal != null) ? principal.getName() : "");
var art = articleService.getArticle(id);
model.addAttribute("article",art);
return "the-article";
......
......@@ -2,7 +2,6 @@ package id.ac.ui.cs.advprog.landiandfriends.controller;
import id.ac.ui.cs.advprog.landiandfriends.forms.CreateArticleForm;
import id.ac.ui.cs.advprog.landiandfriends.forms.CreateBookForm;
import id.ac.ui.cs.advprog.landiandfriends.model.Book;
import id.ac.ui.cs.advprog.landiandfriends.service.ArticleServiceImpl;
import id.ac.ui.cs.advprog.landiandfriends.service.BookServiceImpl;
import id.ac.ui.cs.advprog.landiandfriends.service.GenreServiceImpl;
......@@ -16,6 +15,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.security.Principal;
import java.util.List;
@Controller
@RequestMapping("/curator")
......@@ -49,9 +49,10 @@ public class CuratorController {
}
@PostMapping(path={"/create-book"})
public ResponseEntity<String> addBook(@RequestBody CreateBookForm form) {
public ResponseEntity<String> addBook(@RequestParam MultipartFile image, @RequestParam String title, @RequestParam String author, @RequestParam String description, @RequestParam String stock, @RequestParam float price, @RequestParam List<String> genres) {
CreateBookForm form = new CreateBookForm(title, author, description,stock,genres,price);
try {
var book = bookService.createBook(form);
var book = bookService.createBook(form, image);
return ResponseEntity.ok(book.getBookId().toString());
} catch (Exception e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
......@@ -76,38 +77,42 @@ public class CuratorController {
}
@PutMapping(path={"/edit-book/{id}"})
public ResponseEntity<String> modifyBook(@PathVariable String id, @RequestBody CreateBookForm form) {
public ResponseEntity<String> modifyBook(@PathVariable String id, @RequestParam MultipartFile image, @RequestParam String title, @RequestParam String author, @RequestParam String description, @RequestParam String stock, @RequestParam float price, @RequestParam List<String> genres) {
CreateBookForm form = new CreateBookForm(title, author, description,stock,genres,price);
try {
var book = bookService.updateBook(id, form);
var book = bookService.updateBook(id, form, image);
return ResponseEntity.ok(book.getBookId().toString());
} catch (Exception e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
@GetMapping(path={ "/create-article"})
public String createArticle(Model model){
model.addAttribute("form", new CreateArticleForm());
return "article-create";
}
@PostMapping(path={"/create-article"})
public String addArticle(@RequestParam("image") final MultipartFile multipartFile,@RequestParam String title,@RequestParam String author,@RequestParam String desc) throws IOException {
articleService.createArticle(title,author,desc,multipartFile);
@PostMapping(path={"/create-article"})
public String addArticle(@RequestParam MultipartFile image,@RequestParam String title,@RequestParam String author,@RequestParam String desc) throws IOException {
articleService.createArticle(title,author,desc,image.getBytes(),image.getOriginalFilename());
return REDIRECT_ARTICLE;
}
@GetMapping(path ={"/update/{id}"})
public String updateItem(@PathVariable("id") Integer id, Model model) {
model.addAttribute("article",articleService.getArticle(id));
return "updateArticle";
}
@PostMapping(path={"/update/{id}"})
public String updateArticle(@PathVariable(value = "id") Integer id, @RequestParam("image") final MultipartFile multipartFile,@RequestParam String title,@RequestParam String author,@RequestParam String desc) throws IOException {
articleService.updateArticle(id, title,author,desc,multipartFile);
@PostMapping(path={"/update/{id}"})
public String updateArticle(@PathVariable(value = "id") Integer id, @RequestParam("image") final MultipartFile image,@RequestParam String title,@RequestParam String author,@RequestParam String desc) throws IOException {
articleService.updateArticle(id, title,author,desc,image.getBytes(),image.getOriginalFilename());
return REDIRECT_ARTICLE;
}
@PostMapping(path={"/delete/{id}"})
public String deleteArticle(@PathVariable(value = "id") Integer id) {
......
package id.ac.ui.cs.advprog.landiandfriends.controller;
import id.ac.ui.cs.advprog.landiandfriends.service.ImageService;
import id.ac.ui.cs.advprog.landiandfriends.service.ImageServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/image")
@RequiredArgsConstructor
public class ImageController {
private final ImageServiceImpl imageService;
@GetMapping(path = "{imageId}", produces= MediaType.IMAGE_JPEG_VALUE)
public FileSystemResource findImage(@PathVariable Long imageId){
return imageService.findImage(imageId);
}
}
......@@ -19,13 +19,13 @@ public class PaymentController {
this.paymentService = paymentService;
}
@GetMapping(path="/add-card")
@GetMapping(path={"/add-card"})
public String addPayment(Model model){
model.addAttribute("form", new AddPaymentForm());
return "add-card";
}
@PostMapping(path="/add-card")
@PostMapping(path={"/add-card"})
public String addPayment(@RequestBody AddPaymentForm form) {
PaymentModel payment = paymentService.addPayment(form.getName(), form.getCardName(), form.getCardNumber(), form.getExpiryDate(), form.getCvv());
paymentService.savePayment(payment);
......@@ -34,15 +34,8 @@ public class PaymentController {
@GetMapping(path="/payment-methods")
public String paymentList(Model model){
try{
paymentService.getUserPayments();
}
catch (Exception e){
}
finally {
model.addAttribute("payments", paymentService.getUserPayments());
}
paymentService.getUserPayments();
model.addAttribute("payments", paymentService.getUserPayments());
return "payment-methods";
}
......
package id.ac.ui.cs.advprog.landiandfriends.forms;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CreateBookForm {
private String title;
......
......@@ -26,17 +26,7 @@ public class Articles {
@Column(nullable = false, columnDefinition ="TEXT", name = "description", length = Integer.MAX_VALUE)
private String content;
@Type(type="org.hibernate.type.BinaryType")
@Lob
@Column(name="photos",nullable=true)
private byte[] photos;
@Column(name="encode",columnDefinition="text", length=10485760)
private String theImage;
public Integer getId() {
return articleId;
}
@Column(name="image_id")
private Long imageId;
}
......@@ -35,6 +35,9 @@ public class Book {
@Column(name = "price", nullable = false)
private float price;
@Column(name="image_id")
private Long imageId;
@ManyToMany
@JsonIgnore
@JoinTable(
......
package id.ac.ui.cs.advprog.landiandfriends.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "image_model")
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "image_id")
private Long imageId;
@Column(nullable = false, name = "path")
private String path;
}
......@@ -31,7 +31,4 @@ public class Role {
this.id = id;
}
public Integer getId() {
return id;
}
}
\ No newline at end of file
package id.ac.ui.cs.advprog.landiandfriends.model.productcard;
import id.ac.ui.cs.advprog.landiandfriends.model.Articles;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class ArticleProductCard implements ProductCard {
private Articles article;
@Override
public Long getImageId() {
return article.getImageId();
}
@Override
public String getTitle() {
return article.getTitle();
}
@Override
public String getCreator() {
return article.getAuthor();
}
@Override
public String getInfo() {
return "Article";
}
@Override
public String getLink() {
return "/articles/"+article.getArticleId();
}
}
package id.ac.ui.cs.advprog.landiandfriends.model.productcard;
import id.ac.ui.cs.advprog.landiandfriends.model.Book;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class BookProductCard implements ProductCard {
private Book book;
@Override
public Long getImageId() {
return book.getImageId();
}
@Override
public String getTitle() {
return book.getTitle();
}
@Override
public String getCreator() {
return book.getAuthor();
}
@Override
public String getInfo() {
if(book.getGenres().isEmpty()) return "";
return book.getGenres().iterator().next().toString();
}
@Override
public String getLink() {
return "/book/"+book.getBookId();
}
}
package id.ac.ui.cs.advprog.landiandfriends.model.productcard;
public interface ProductCard {
Long getImageId();
String getTitle();
String getCreator();
String getInfo();
String getLink();
}
package id.ac.ui.cs.advprog.landiandfriends.repository;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ImageRepository extends JpaRepository<Image, Long> {
}
......@@ -7,8 +7,9 @@ import java.io.IOException;
import java.util.List;
public interface ArticleService {
Articles createArticle(String title, String author, String content, MultipartFile file ) throws IOException;
Articles createArticle(String title, String author, String content, byte[] image, String imageName);
void updateArticle(Integer id, String title, String author, String content, byte[] image, String imageName);
List<Articles> getAllArticles();
Articles getArticle(Integer id);
List<Articles> getRandomArticles(int amount);
}
package id.ac.ui.cs.advprog.landiandfriends.service;
import id.ac.ui.cs.advprog.landiandfriends.model.Articles;
import id.ac.ui.cs.advprog.landiandfriends.model.Book;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import id.ac.ui.cs.advprog.landiandfriends.repository.ArticleRepository;
import id.ac.ui.cs.advprog.landiandfriends.util.ImageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@Service
public class ArticleServiceImpl implements ArticleService{
@RequiredArgsConstructor
public class ArticleServiceImpl implements ArticleService {
private final ArticleRepository repo;
@Autowired
public ArticleServiceImpl(ArticleRepository repo) {
this.repo = repo;
private final ImageServiceImpl imageService;
private final Logger logger = LoggerFactory.getLogger(ArticleServiceImpl.class);
private void createImageForArticle(Articles article, byte[] images, String imageName){
try{
Image image = imageService.createImage(images, imageName);
article.setImageId(image.getImageId());
} catch (Exception e){
logger.error("Exception during image upload for article {}: {}", article.getArticleId(), e.getMessage());
}
}
@Override
public Articles createArticle(String title, String author, String content, MultipartFile file) throws IOException {
var imageconvert = ImageConverter.getInstance();
var image = imageconvert.getString(file);
public Articles createArticle(String title, String author, String content, byte[] imageBytes, String imageName) {
var art = new Articles();
art.setTitle(title);
art.setAuthor(author);
art.setContent(content);
art.setTheImage(image);
createImageForArticle(art, imageBytes, imageName);
repo.save(art);
return art;
}
......@@ -40,18 +50,14 @@ public class ArticleServiceImpl implements ArticleService{
return repo.findAll();
}
public void updateArticle(Integer id,String title,String author,String desc,MultipartFile multipartFile) throws IOException {
public void updateArticle(Integer id,String title,String author,String desc,byte[] image, String imageName) {
Optional<Articles> art = repo.findById(id);
if(art.isPresent()){
Articles objArt = art.get();
if (!multipartFile.isEmpty()){
var imageconvert = ImageConverter.getInstance();
var image = imageconvert.getString(multipartFile);
objArt.setTheImage(image);
}
objArt.setTitle(title);
objArt.setAuthor(author);
objArt.setContent(desc);
createImageForArticle(objArt, image, imageName);
repo.save(objArt);
}
}
......@@ -60,7 +66,13 @@ public class ArticleServiceImpl implements ArticleService{
Optional<Articles> art = repo.findById(id);
Articles objArt = art.get();
repo.delete(objArt);
}
@Override
public List<Articles> getRandomArticles(int amount){
List<Articles> articles = repo.findAll();
Collections.shuffle(articles);
return articles.subList(0, Math.min(amount, articles.size()));
}
}
......
......@@ -3,12 +3,13 @@ package id.ac.ui.cs.advprog.landiandfriends.service;
import id.ac.ui.cs.advprog.landiandfriends.forms.CreateBookForm;
import id.ac.ui.cs.advprog.landiandfriends.model.Book;
import org.springframework.data.domain.Page;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface BookService {
Book createBook(CreateBookForm form);
Book updateBook(String bookId, CreateBookForm form);
Book createBook(CreateBookForm form, MultipartFile image);
Book updateBook(String bookId, CreateBookForm form, MultipartFile image);
Book removeBook(String bookId);
List<Book> getRandomBooks(int amount);
Page<Book> getBookPage(int page);
......
......@@ -3,6 +3,7 @@ package id.ac.ui.cs.advprog.landiandfriends.service;
import id.ac.ui.cs.advprog.landiandfriends.exception.InvalidStockException;
import id.ac.ui.cs.advprog.landiandfriends.forms.CreateBookForm;
import id.ac.ui.cs.advprog.landiandfriends.model.Book;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import id.ac.ui.cs.advprog.landiandfriends.repository.BookRepository;
import id.ac.ui.cs.advprog.landiandfriends.repository.GenreRepository;
import lombok.RequiredArgsConstructor;
......@@ -11,6 +12,7 @@ import org.slf4j.LoggerFactory;