Skip to content

Commit

Permalink
Feature/products (#28)
Browse files Browse the repository at this point in the history
* Develop (#27)

* feat(auth): Add Google Login integration

- Implemented Google Login functionality for user authentication.
- Added necessary components and libraries for Google authentication.
- Configured OAuth settings and credentials.
- Integrated the Google Login button into the user interface.

This commit introduces Google Login as an authentication option for users.

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* Feature/order (#22)

* Develop (#21)

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* feat: Implement order processing in the e-commerce system

Details:
- Added Order entity to the data model
- Implemented order creation and validation logic
- Integrated order processing with existing product and customer services
- Updated API endpoints for order management

* chore: Configure authorization for order endpoints

Details:
- Implemented role-based access control for order creation and modification
- Configured method-level security using Spring Security annotations
- Added custom access denied handler for unauthorized requests
- Updated Swagger documentation to reflect new access restrictions

* Develop (#23)

* feat(entity): add Product entity

Add the Product entity class with SKU, name, description, category, images, and variations properties.

* feat: view products and product detail

* config: install querydsl to project

* feat(auth): Add Google Login integration

- Implemented Google Login functionality for user authentication.
- Added necessary components and libraries for Google authentication.
- Configured OAuth settings and credentials.
- Integrated the Google Login button into the user interface.

This commit introduces Google Login as an authentication option for users.

* feat(api): Implement shop owner product addition APIs

- Added API endpoints to allow shop owners to add products.
- Created corresponding database models and controllers.
- Implemented input validation and access control for shop owners.

This commit introduces new APIs for shop owners to add products to their stores.

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* Feature/order (#22)

* Develop (#21)

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* feat: Implement order processing in the e-commerce system

Details:
- Added Order entity to the data model
- Implemented order creation and validation logic
- Integrated order processing with existing product and customer services
- Updated API endpoints for order management

* chore: Configure authorization for order endpoints

Details:
- Implemented role-based access control for order creation and modification
- Configured method-level security using Spring Security annotations
- Added custom access denied handler for unauthorized requests
- Updated Swagger documentation to reflect new access restrictions

* feat(user/address): Add getDefaultAddress functionality

Implement the getDefaultAddress service method for retrieving the default user address.

* Develop (#25)

* feat(api): Implement shop owner product addition APIs

- Added API endpoints to allow shop owners to add products.
- Created corresponding database models and controllers.
- Implemented input validation and access control for shop owners.

This commit introduces new APIs for shop owners to add products to their stores.

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* Feature/order (#22)

* Develop (#21)

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* feat: Implement order processing in the e-commerce system

Details:
- Added Order entity to the data model
- Implemented order creation and validation logic
- Integrated order processing with existing product and customer services
- Updated API endpoints for order management

* chore: Configure authorization for order endpoints

Details:
- Implemented role-based access control for order creation and modification
- Configured method-level security using Spring Security annotations
- Added custom access denied handler for unauthorized requests
- Updated Swagger documentation to reflect new access restrictions

* Develop (#23)

* feat(entity): add Product entity

Add the Product entity class with SKU, name, description, category, images, and variations properties.

* feat: view products and product detail

* config: install querydsl to project

* feat(auth): Add Google Login integration

- Implemented Google Login functionality for user authentication.
- Added necessary components and libraries for Google authentication.
- Configured OAuth settings and credentials.
- Integrated the Google Login button into the user interface.

This commit introduces Google Login as an authentication option for users.

* feat(api): Implement shop owner product addition APIs

- Added API endpoints to allow shop owners to add products.
- Created corresponding database models and controllers.
- Implemented input validation and access control for shop owners.

This commit introduces new APIs for shop owners to add products to their stores.

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* Feature/order (#22)

* Develop (#21)

* feat(cart): Implement shopping cart feature

- Created the shopping cart component and functionality.
- Added the ability to add, remove, and update items in the cart.
- Integrated cart data with the backend API.
- Updated UI to display cart contents and total.

This commit introduces the shopping cart feature, allowing users to manage their cart items.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Updated the conditional statement from logical AND (&&) to logical OR (||).

Closes #18

This commit addresses a security issue by ensuring that user access is granted if the user is enabled or not currently disabled, and it closes issue #18.

* fix(auth): Correct security authentication logic

- Fixed the security authentication logic to allow access when the user is either enabled or not disabled.
- Redo issue #18.

* feat: Implement order processing in the e-commerce system

Details:
- Added Order entity to the data model
- Implemented order creation and validation logic
- Integrated order processing with existing product and customer services
- Updated API endpoints for order management

* chore: Configure authorization for order endpoints

Details:
- Implemented role-based access control for order creation and modification
- Configured method-level security using Spring Security annotations
- Added custom access denied handler for unauthorized requests
- Updated Swagger documentation to reflect new access restrictions

* feat(user/address): Add getDefaultAddress functionality

Implement the getDefaultAddress service method for retrieving the default user address.

* feat(user/address): Add getDefaultAddress functionality

Implement the getDefaultAddress service method for retrieving the default user address.

* feat: add update product api to update product function
  • Loading branch information
thongdanghoang authored Nov 12, 2023
1 parent 1f710b5 commit b2d86a1
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

@Data
public class ProductAddingDto {
private long id;
private String name;
private String sku;
private int price;
private float discount;
private long categoryId;
private String description;
private List<ClassifyClotheDto> classifyClothes;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
@Table(name = "PRODUCT")
public class Product extends BaseEntity{
public class Product extends BaseEntity {

@Column(name = "SKU", nullable = false, unique = true)
private String sku;
Expand All @@ -32,7 +33,14 @@ public class Product extends BaseEntity{
@Column(name = "RATED")
private float rated;

@ManyToOne(cascade = CascadeType.ALL)
@Lob
@Column(name = "DESCRIPTION")
private String description;

@Column(name = "CREATED_DATE")
private LocalDateTime createdDate;

@ManyToOne()
@JoinColumn(name = "category_id")
private Category category;

Expand All @@ -41,8 +49,18 @@ public class Product extends BaseEntity{

@OneToMany(mappedBy = "product", orphanRemoval = true)
private List<Quantity> quantities = new ArrayList<>();

public Product() {
this.numberOfSold = 0;
this.rated = 0;
}

public Long getGrandTotal() {
return (long) (this.price * (1 - this.discount));
}

@PrePersist
public void prePersist() {
this.createdDate = LocalDateTime.now();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package fptu.swp391.shoppingcart.product.exceptions;

public class ProductNotFoundException extends RuntimeException {

public ProductNotFoundException() {
super();
}

public ProductNotFoundException(String message) {
super(message);
}

public ProductNotFoundException(String message, Throwable cause) {
super(message, cause);
}

public ProductNotFoundException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,62 @@
@Component
public class ProductDetailMapper implements IMapper<Product, ProductDetailDto> {

private static List<QuantityBySizeDto> mapQuantityToProductQuantityDto(Long colorId, List<Quantity> quantities) {
List<QuantityBySizeDto> quantitiesBySize = new ArrayList<>();
for (Quantity quantity : quantities) {
if (Objects.equals(quantity.getColor().getId(), colorId)) {
QuantityBySizeDto quantityBySizeDto = new QuantityBySizeDto();
quantityBySizeDto.setSize(quantity.getSize().getSizeName());
quantityBySizeDto.setQuantityInStock(quantity.getQuantityInStock());
quantityBySizeDto.setQuantityId(quantity.getId());
quantitiesBySize.add(quantityBySizeDto);
}
}
return quantitiesBySize;
}

@Override
public Product toEntity(ProductDetailDto productDetailDto) {
throw new UnsupportedOperationException("Not implemented yet");
}

@Override
public List<Product> toEntities(List<ProductDetailDto> productDetailDtos) {
public List<Product> toEntities(List<ProductDetailDto> productDetailDTOs) {
throw new UnsupportedOperationException("Not implemented yet");
}

@Override
public ProductDetailDto toDTO(Product product) {
ProductDetailDto productDto = new ProductDetailDto();
List<ClassifyClotheDto> classifyClotheDtos = new ArrayList<>();
List<ClassifyClotheDto> classifyClotheDTOs = new ArrayList<>();
List<Image> images = product.getImages();
List<Quantity> quantities = product.getQuantities();

// group images by images.color
Map<Long, String> colours = new HashMap<>();
for (Image image : images) {
if(!colours.containsKey(image.getColor().getId())){
colours.put(image.getColor().getId(), image.getColor().getColorName());
if (!images.isEmpty()) {
for (Image image : images) {
if (image.getColor() != null
&& (!colours.containsKey(image.getColor().getId()))) {
colours.put(image.getColor().getId(), image.getColor().getColorName());
}
}
}
colours.forEach((colorId, colorName) -> {
ClassifyClotheDto classifyClotheDto = new ClassifyClotheDto();

colours.forEach((colorId, colorName) -> {
ClassifyClotheDto classifyClotheDto = new ClassifyClotheDto();
classifyClotheDto.setColor(colorName);

classifyClotheDto.setColor(colorName);
List<String> imageUrls = images.stream()
.filter(image -> Objects.equals(image.getColor().getId(), colorId))
.map(Image::getUrl)
.collect(Collectors.toList());
classifyClotheDto.setImages(imageUrls);

List<String> imageUrls = images.stream()
.filter(image -> Objects.equals(image.getColor().getId(), colorId))
.map(Image::getUrl)
.collect(Collectors.toList());
classifyClotheDto.setImages(imageUrls);
List<QuantityBySizeDto> quantitiesBySize = mapQuantityToProductQuantityDto(colorId, quantities);
classifyClotheDto.setQuantities(quantitiesBySize);
classifyClotheDTOs.add(classifyClotheDto);
});
}

List<QuantityBySizeDto> quantitiesBySize = new ArrayList<>();
for (Quantity quantity : quantities) {
Expand All @@ -64,6 +85,7 @@ public ProductDetailDto toDTO(Product product) {
classifyClotheDto.setQuantities(quantitiesBySize);
classifyClotheDtos.add(classifyClotheDto);
});

productDto.setId(product.getId());
productDto.setSku(product.getSku());
productDto.setName(product.getName());
Expand All @@ -72,8 +94,8 @@ public ProductDetailDto toDTO(Product product) {
productDto.setPrice(product.getPrice());
productDto.setDiscount(product.getDiscount());
productDto.setCategory(product.getCategory().getFullName());
productDto.setDescription("Not implemented yet");
productDto.setClassifyClothes(classifyClotheDtos);
productDto.setDescription(product.getDescription());
productDto.setClassifyClothes(classifyClotheDTOs);
return productDto;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
Expand All @@ -30,7 +31,7 @@ public ProductDto toDTO(Product product) {
productDto.setId(product.getId());
productDto.setSku(product.getSku());
productDto.setName(product.getName());
productDto.setImage(product.getImages().stream().findFirst().orElseThrow().getUrl());
productDto.setImage(product.getImages().stream().findFirst().map(Image::getUrl).orElse(null));
productDto.setRated(product.getRated());
productDto.setNumberOfSold(product.getNumberOfSold());
productDto.setPrice(product.getPrice());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import fptu.swp391.shoppingcart.product.entity.Image;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface ImageRepository extends JpaRepository<Image, Long> {
Optional<Image> findByProductIdAndColorIdAndUrl(Long productId, Long colorId, String url);

void deleteByProductId(Long productId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,10 @@
import fptu.swp391.shoppingcart.product.entity.Quantity;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface QuantityRepository extends JpaRepository<Quantity, Long> {
Optional<Quantity> findByProductIdAndColorIdAndSizeId(Long productId, Long colorId, Long sizeId);

void deleteByProductId(Long productId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import fptu.swp391.shoppingcart.product.entity.Product;
import fptu.swp391.shoppingcart.product.entity.QCategory;
import fptu.swp391.shoppingcart.product.entity.QProduct;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
import java.util.stream.Collectors;

public class ProductRepositoryCustomImpl implements ProductRepositoryCustom {

Expand Down Expand Up @@ -42,15 +43,15 @@ public Page<Product> search(String keyword, String sort, String category, String
}
}

if (category != null && !category.isEmpty()) {
QCategory present = product.category;
while (present != null) {
conditions = conditions == null ? present.name.containsIgnoreCase(category) :
conditions.or(present.name.containsIgnoreCase(category));
present = present.parentCategory;
}
// if (category != null && !category.isEmpty()) {
// QCategory present = product.category;
// while (present != null) {
// conditions = conditions == null ? present.name.containsIgnoreCase(category) :
// conditions.or(present.name.containsIgnoreCase(category));
// present = present.parentCategory;
// }
// }

}
if (minPrice > 0) {
conditions = conditions == null ? product.price.goe(minPrice) :
conditions.and(product.price.goe(minPrice));
Expand Down Expand Up @@ -116,7 +117,11 @@ public Page<Product> search(String keyword, String sort, String category, String
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();

if (!StringUtils.isEmpty(category)) {
results = results.stream()
.filter(o -> o.getCategory().getFullName().contains(category.toUpperCase()))
.collect(Collectors.toList());
}
return PageableExecutionUtils.getPage(results, pageable, () -> totalCount);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package fptu.swp391.shoppingcart.product.services;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.*;
import java.util.Objects;
import java.util.UUID;

@Service
public class ImageService {
private final Path imageUploadPath;

@Autowired
private RestTemplate restTemplate;

public ImageService(@Value("${products-image-dir}") String uploadDir) {
this.imageUploadPath = Paths.get(uploadDir).toAbsolutePath().normalize();
try {
Expand All @@ -37,6 +45,30 @@ public String uploadImage(MultipartFile file) throws IOException {
}
}

public String uploadImageFromUrl(String imageUrl) throws IOException {
// Generate a unique filename
String fileName = UUID.randomUUID().toString();

// Create a final array to store the file extension
final String[] fileExtension = { "jpg" }; // Default to jpg

restTemplate.execute(imageUrl, HttpMethod.GET, null, clientHttpResponse -> {
String contentType = Objects.requireNonNull(clientHttpResponse.getHeaders().getContentType()).getSubtype();
if (!contentType.isEmpty()) {
fileExtension[0] = contentType;
}

// Save the image with the determined filename and extension
Path targetLocation = this.imageUploadPath.resolve(fileName + "." + fileExtension[0]);
Files.copy(clientHttpResponse.getBody(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

return null;
});

return fileName + "." + fileExtension[0];
}


public Path getImagePath(String fileName) {
return this.imageUploadPath.resolve(fileName).normalize();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ public interface ProductService {

ProductAddingDto createProduct(ProductAddingDto productDto);

public void deleteProductById(Long id);

List<CategoryDto> getAllCategory();
}
Loading

0 comments on commit b2d86a1

Please sign in to comment.