diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/CategoryController.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/CategoryController.java index 0eab1ca..cd50772 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/CategoryController.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/CategoryController.java @@ -63,7 +63,7 @@ public ResponseEntity> getById(@PathVariable int i @PostMapping("") @PreAuthorize("hasRole('ROLE_MANAGER')") - public ResponseEntity> create( + public ResponseEntity>> create( @Valid @RequestBody CategoryDTO categoryDTO, BindingResult result ) { @@ -72,7 +72,7 @@ public ResponseEntity> create( throw new MethodArgumentNotValidException(result); } return ResponseEntity.status(HttpStatus.CREATED).body( - ApiResponse.builder() + ApiResponse.>builder() .message("Create category successfully") .statusCode(HttpStatus.CREATED.value()) .isSuccess(true) diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/ProductController.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/ProductController.java index a9f8285..5c6dd0d 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/ProductController.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/ProductController.java @@ -1,13 +1,16 @@ package com.lcaohoanq.shoppe.controllers; +import com.github.javafaker.Faker; import com.lcaohoanq.shoppe.components.LocalizationUtils; import com.lcaohoanq.shoppe.dtos.request.ProductDTO; import com.lcaohoanq.shoppe.dtos.request.ProductImageDTO; import com.lcaohoanq.shoppe.dtos.responses.ProductResponse; import com.lcaohoanq.shoppe.dtos.responses.base.ApiResponse; import com.lcaohoanq.shoppe.dtos.responses.base.PageResponse; +import com.lcaohoanq.shoppe.enums.ProductStatus; import com.lcaohoanq.shoppe.exceptions.MethodArgumentNotValidException; import com.lcaohoanq.shoppe.metadata.MediaMeta; +import com.lcaohoanq.shoppe.models.Category; import com.lcaohoanq.shoppe.models.ProductImage; import com.lcaohoanq.shoppe.repositories.CategoryRepository; import com.lcaohoanq.shoppe.services.category.CategoryService; @@ -16,6 +19,7 @@ import jakarta.validation.Valid; import java.util.ArrayList; import java.util.List; +import java.util.Random; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.PageRequest; @@ -155,41 +159,43 @@ public ResponseEntity> deleteProduct( ); } -// @PostMapping("/generateFakeProducts") -// @PreAuthorize("hasAnyRole('ROLE_MANAGER')") -// public ResponseEntity generateFakeProducts() { -// Faker faker = new Faker(); -// Random random = new Random(); -// -// List categoryList = categoryRepository.findAll(); -// -// for (int i = 10_001; i <= 1_000_000; i++) { -//// String productName = faker.commerce().productName(); -//// if(productService.existsByName(productName)) { -//// continue; -//// } -// -// String randomCategory = categoryList.get(random.nextInt(categoryList.size())).getName(); -// -// ProductDTO productDTO = new ProductDTO( -// faker.commerce().productName(), -// faker.lorem().sentence(), //description -// faker.internet().image(), //thumbnail -// randomCategory, //category -// (double)faker.number().numberBetween(10, 90_000_000), //price -// (double)faker.number().numberBetween(10, 90_000_000), //priceBeforeDiscount -// faker.number().numberBetween(1, 10000), //quantity -// faker.number().numberBetween(0, 10000), //sold -// faker.number().numberBetween(0, 10000), //view -// faker.number().randomDouble(1, 0, 5) //rating -// ); -// try{ -// productService.createProduct(productDTO); -// } catch (Exception e) { -// return ResponseEntity.badRequest().body(e.getMessage()); + @PostMapping("/generateFakeProducts") + @PreAuthorize("hasAnyRole('ROLE_MANAGER')") + public ResponseEntity generateFakeProducts() { + Faker faker = new Faker(); + Random random = new Random(); + + List categoryList = categoryRepository.findAll(); + + for (int i = 1; i <= 500; i++) { +// String productName = faker.commerce().productName(); +// if(productService.existsByName(productName)) { +// continue; // } -// } -// return ResponseEntity.ok("Fake products generated"); -// } + + String randomCategory = categoryList.get(random.nextInt(categoryList.size())).getName(); + + ProductDTO productDTO = new ProductDTO( + faker.commerce().productName(), + faker.lorem().sentence(), //description + randomCategory, //category + 3L, //shopOwnerId + (double)faker.number().numberBetween(10, 90_000_000), //price + (double)faker.number().numberBetween(10, 90_000_000), //priceBeforeDiscount + faker.number().numberBetween(1, 10000), //quantity + faker.number().numberBetween(0, 10000), //sold + faker.number().numberBetween(0, 10000), //view + faker.number().randomDouble(1, 0, 5), //rating, + ProductStatus.VERIFIED, //status + true //isActive + ); + try{ + productService.create(productDTO); + } catch (Exception e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + return ResponseEntity.ok("Fake products generated"); + } } diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/RoleController.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/RoleController.java index e24c4c9..b64f33b 100755 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/RoleController.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/controllers/RoleController.java @@ -55,7 +55,7 @@ public ResponseEntity> getById(@PathVariable Long id) } @PostMapping("") - @PreAuthorize("hasRole('ROLE_MANAGER')") +// @PreAuthorize("hasRole('ROLE_MANAGER')") public ResponseEntity> create( @Valid @RequestBody RoleDTO roleDTO, BindingResult bindingResult) { diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/CategoryDTO.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/CategoryDTO.java index d9d668f..0378401 100755 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/CategoryDTO.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/CategoryDTO.java @@ -1,9 +1,10 @@ package com.lcaohoanq.shoppe.dtos.request; import jakarta.validation.constraints.NotEmpty; +import java.util.List; import lombok.Builder; @Builder public record CategoryDTO( - @NotEmpty(message = "Category name is required") String name + @NotEmpty(message = "Category name is required") List name ) {} diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/ProductDTO.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/ProductDTO.java index eb521ad..c0fa40f 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/ProductDTO.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/dtos/request/ProductDTO.java @@ -13,9 +13,6 @@ public record ProductDTO( @NotNull(message = "Product's description must not be null") String description, - @NotNull(message = "Product's thumbnail must not be null") - String thumbnail, - @NotNull(message = "Product's category must not be null") String category, diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/filters/JwtTokenFilter.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/filters/JwtTokenFilter.java index 6cd1d48..b8ac39f 100755 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/filters/JwtTokenFilter.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/filters/JwtTokenFilter.java @@ -166,7 +166,7 @@ private boolean isPublicEndpoint(String path, HttpServletRequest request) { // Check roles endpoint if (path.startsWith(apiPrefix + "/roles")) { - boolean isGet = request.getMethod().equals("GET"); + boolean isGet = request.getMethod().equals("GET") || request.getMethod().equals("POST"); log.info("Roles endpoint - Is GET? {}", isGet); return isGet; } diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Cart.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Cart.java new file mode 100644 index 0000000..39ad155 --- /dev/null +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Cart.java @@ -0,0 +1,51 @@ +package com.lcaohoanq.shoppe.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.lcaohoanq.shoppe.models.base.BaseEntity; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "carts") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class Cart extends BaseEntity { + + @Id + @SequenceGenerator(name = "carts_seq", sequenceName = "carts_id_seq", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "carts_seq") + @Column(name="id", unique=true, nullable=false) + @JsonProperty("id") + private Long id; + + @Column(name = "total_quantity") + private int totalQuantity; + + @Column(name = "total_price") + private double totalPrice; + + @OneToOne + @JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false) + private User user; + + @OneToMany(mappedBy = "cart", cascade = CascadeType.ALL, orphanRemoval = true) + private List cartProducts = new ArrayList<>(); + +} \ No newline at end of file diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/CartProduct.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/CartProduct.java new file mode 100644 index 0000000..4ca5771 --- /dev/null +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/CartProduct.java @@ -0,0 +1,46 @@ +package com.lcaohoanq.shoppe.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.lcaohoanq.shoppe.models.base.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "cart_products") +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CartProduct extends BaseEntity { + + @Id + @SequenceGenerator(name = "cartproducts_seq", sequenceName = "cartproducts_id_seq", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cartproducts_seq") + @Column(name="id", unique=true, nullable=false) + @JsonProperty("id") + private Long id; + + @ManyToOne + @JoinColumn(name = "cart_id") + private Cart cart; + + @ManyToOne + @JoinColumn(name = "product_id") + private Product product; + + @Column(name = "quantity") + private int quantity; +} \ No newline at end of file diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Coupon.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Coupon.java index 3af1841..a010a6f 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Coupon.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Coupon.java @@ -1,6 +1,7 @@ package com.lcaohoanq.shoppe.models; import com.fasterxml.jackson.annotation.JsonProperty; +import com.lcaohoanq.shoppe.models.base.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -21,7 +22,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class Coupon { +public class Coupon extends BaseEntity { @Id @SequenceGenerator(name = "coupons_seq", sequenceName = "coupons_id_seq", allocationSize = 1) diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/CouponCondition.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/CouponCondition.java index 1d16ed8..1d2f86b 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/CouponCondition.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/CouponCondition.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonProperty; +import com.lcaohoanq.shoppe.models.base.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -27,7 +28,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class CouponCondition { +public class CouponCondition extends BaseEntity { @Id @SequenceGenerator(name = "coupon_conditions_seq", sequenceName = "coupon_conditions_id_seq", allocationSize = 1) diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Product.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Product.java index f20373d..8bbddae 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Product.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Product.java @@ -1,5 +1,6 @@ package com.lcaohoanq.shoppe.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.lcaohoanq.shoppe.enums.ProductStatus; import com.lcaohoanq.shoppe.models.base.BaseEntity; @@ -15,6 +16,7 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; +import java.util.ArrayList; import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; @@ -66,6 +68,9 @@ public class Product extends BaseEntity { private User shopOwner; @OneToMany(mappedBy = "product") - private List images; + private List images = new ArrayList<>(); + + @OneToMany(mappedBy = "product") + private List cartProducts = new ArrayList<>(); } diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/ShippingCarrier.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/ShippingCarrier.java index e66f371..63f8982 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/ShippingCarrier.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/ShippingCarrier.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.lcaohoanq.shoppe.enums.ShippingCarrierName; +import com.lcaohoanq.shoppe.models.base.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -24,7 +25,7 @@ @Builder @AllArgsConstructor @NoArgsConstructor -public class ShippingCarrier { +public class ShippingCarrier extends BaseEntity { @Id @SequenceGenerator(name = "orders_seq", sequenceName = "orders_id_seq", allocationSize = 1) diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/User.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/User.java index 72410c1..24b883d 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/User.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/User.java @@ -1,6 +1,7 @@ package com.lcaohoanq.shoppe.models; import com.fasterxml.jackson.annotation.JsonProperty; +import com.lcaohoanq.shoppe.constants.Regex; import com.lcaohoanq.shoppe.enums.Country; import com.lcaohoanq.shoppe.enums.Currency; import com.lcaohoanq.shoppe.enums.Gender; @@ -20,6 +21,7 @@ import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Pattern; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; @@ -80,11 +82,16 @@ public class User extends BaseEntity implements UserDetails { private String address; + @Unique + @Column(name="phone_number",nullable = false, length = 100) @JsonProperty("phone_number") private String phoneNumber; @OneToOne(cascade = CascadeType.ALL) - @JoinColumn(name="wallet_id") + @JoinColumn(name = "cart_id") + private Cart cart; + + @OneToOne(mappedBy = "user", cascade = CascadeType.ALL) private Wallet wallet; @ManyToOne diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Wallet.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Wallet.java index d02bc90..a10a91b 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Wallet.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/models/Wallet.java @@ -1,11 +1,13 @@ package com.lcaohoanq.shoppe.models; import com.fasterxml.jackson.annotation.JsonProperty; +import com.lcaohoanq.shoppe.models.base.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToOne; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; @@ -22,11 +24,11 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class Wallet { +public class Wallet extends BaseEntity { @Id - @SequenceGenerator(name = "products_seq", sequenceName = "products_id_seq", allocationSize = 1) - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "products_seq") + @SequenceGenerator(name = "wallets_seq", sequenceName = "wallets_id_seq", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "wallets_seq") @Column(name="id", unique=true, nullable=false) @JsonProperty("id") private Long id; @@ -34,7 +36,8 @@ public class Wallet { @Column(name = "balance", nullable = false) private Float balance; - @OneToOne(mappedBy = "wallet") + @OneToOne + @JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false) private User user; } diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/repositories/CategoryRepository.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/repositories/CategoryRepository.java index ed4bb4c..13c8d70 100644 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/repositories/CategoryRepository.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/repositories/CategoryRepository.java @@ -1,11 +1,14 @@ package com.lcaohoanq.shoppe.repositories; import com.lcaohoanq.shoppe.models.Category; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface CategoryRepository extends JpaRepository { Optional findByName(String name); + + Boolean existsByNameIn(List names); } diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/CategoryService.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/CategoryService.java index 2c4e2e5..f7e4f56 100755 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/CategoryService.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/CategoryService.java @@ -26,17 +26,23 @@ public class CategoryService implements ICategoryService, DTOConverter, private final CategoryRepository categoryRepository; @Override - public CategoryResponse createCategory(CategoryDTO category) throws DataAlreadyExistException { + public List createCategory(CategoryDTO category) throws DataAlreadyExistException { + List categories = category.name(); - categoryRepository.findByName(category.name()).ifPresent(c -> { + //check if category already exist + if (categoryRepository.existsByNameIn(categories)) { throw new CategoryAlreadyExistException("Category already exist"); + } + + categories.forEach(name -> { + Category newCategory = new Category(); + newCategory.setName(name); + categoryRepository.save(newCategory); }); - - Category newCategory = Category.builder() - .name(category.name()) - .build(); - - return toCategoryResponse(categoryRepository.save(newCategory)); + + return categories.stream() + .map(name -> toCategoryResponse(categoryRepository.findByName(name).get())) + .collect(Collectors.toList()); } @Override @@ -61,7 +67,7 @@ public void update(long categoryId, CategoryDTO category) Category existingCategory = categoryRepository.findById(categoryId) .orElseThrow(() -> new CategoryNotFoundException("Category not found")); - existingCategory.setName(category.name()); + existingCategory.setName(String.valueOf(category.name())); categoryRepository.save(existingCategory); } diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/ICategoryService.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/ICategoryService.java index b9c3c65..2f134ef 100755 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/ICategoryService.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/services/category/ICategoryService.java @@ -10,7 +10,7 @@ public interface ICategoryService { - CategoryResponse createCategory(CategoryDTO categoryDTO) throws DataAlreadyExistException; + List createCategory(CategoryDTO categoryDTO) throws DataAlreadyExistException; CategoryResponse getById(long id) throws DataNotFoundException; List getAllCategories(); void update(long categoryId, CategoryDTO categoryDTO) throws DataNotFoundException; diff --git a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/utils/DTOConverter.java b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/utils/DTOConverter.java index 4b35369..8a22ec5 100755 --- a/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/utils/DTOConverter.java +++ b/SPCServer/springboot/src/main/java/com/lcaohoanq/shoppe/utils/DTOConverter.java @@ -14,6 +14,10 @@ import com.lcaohoanq.shoppe.models.ProductImage; import com.lcaohoanq.shoppe.models.Role; import com.lcaohoanq.shoppe.models.User; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; public interface DTOConverter { @@ -81,11 +85,17 @@ default OrderResponse toOrderResponse(Order order) { } default ProductResponse toProductResponse(Product product) { + List productImageResponses = Optional.ofNullable(product.getImages()) + .orElse(Collections.emptyList()) + .stream() + .map(this::toProductImageResponse) + .toList(); + return new ProductResponse( product.getId(), product.getName(), - product.getDescription(), - product.getImages().stream().map(this::toProductImageResponse).toList(), + product.getDescription(), + productImageResponses, toCategoryResponse(product.getCategory()), product.getPrice(), product.getShopOwner().getId(),