Skip to content

Commit 324ea51

Browse files
authored
Merge pull request #76 from JA-yeong-eop-JA-moeu-JA/dev
🚀 deploy: dev -> main 병합
2 parents cdacefd + e35bb75 commit 324ea51

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1116
-69
lines changed

.github/workflows/ci-cd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,4 @@ jobs:
107107
if [ ! -z "$LATEST_IMAGE_ID" ]; then
108108
sudo docker rmi $LATEST_IMAGE_ID
109109
fi
110-
exit 1
110+
exit 1

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ configurations {
2121

2222
repositories {
2323
mavenCentral()
24+
maven { url 'https://jitpack.io' }
2425
}
2526

2627
dependencies {
@@ -54,6 +55,9 @@ dependencies {
5455
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
5556
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
5657

58+
// iamport
59+
implementation 'com.github.iamport:iamport-rest-client-java:0.2.23'
60+
5761
// S3
5862
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
5963
}

src/main/java/com/jajaja/domain/cart/entity/CartProduct.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ private void recalculateTotalPrice() {
7070
this.totalPrice = unitPrice * this.quantity;
7171
}
7272

73+
/**
74+
* 단위가격을 반환합니다.
75+
*/
76+
public int getUnitPrice() {
77+
return (this.productOption != null) ? this.productOption.getPrice() : this.product.getPrice();
78+
}
79+
7380
/**
7481
* Cart에서 CartProduct를 추가할 때 부모가 누구인지 알려주기 위해 호출하는 연관관계 편의 메소드입니다.
7582
*/

src/main/java/com/jajaja/domain/cart/service/CartCommandService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.List;
66

77
public interface CartCommandService {
8-
public void addOrUpdateCartProduct(Long memberId, List<CartProductAddRequestDto> request);
9-
public void deleteCartProduct(Long memberId, Long productId, Long optionId);
8+
void addOrUpdateCartProduct(Long memberId, List<CartProductAddRequestDto> request);
9+
void deleteCartProduct(Long memberId, Long productId, Long optionId);
10+
void deleteCartProducts(Long memberId, List<Long> cartProductIds);
1011
}

src/main/java/com/jajaja/domain/cart/service/CartCommandServiceImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,26 @@ public void deleteCartProduct(Long memberId, Long productId, Long optionId) {
7373
}
7474
revalidateAppliedCouponIfExists(cart);
7575
}
76+
77+
@Override
78+
public void deleteCartProducts(Long memberId, List<Long> cartProductIds) {
79+
log.info("[CartCommandService] 사용자 {}의 장바구니에서 선택된 아이템들 삭제: {}", memberId, cartProductIds);
80+
Cart cart = cartCommonService.findCart(memberId);
81+
82+
List<CartProduct> cartProductsToDelete = cartProductRepository.findAllById(cartProductIds);
83+
84+
// 해당 카트의 상품인지 검증
85+
cartProductsToDelete.forEach(cartProduct -> {
86+
if (!cartProduct.getCart().getId().equals(cart.getId())) {
87+
throw new CartHandler(ErrorStatus.CART_PRODUCT_NOT_FOUND);
88+
}
89+
});
90+
91+
cartProductRepository.deleteAll(cartProductsToDelete);
92+
cart.getCartProducts().removeAll(cartProductsToDelete);
93+
94+
revalidateAppliedCouponIfExists(cart);
95+
}
7696

7797
/**
7898
* 장바구니 내 아이템 명령 실행에 필요한 도메인 객체를 불러오는 과정입니다.

src/main/java/com/jajaja/domain/coupon/service/CouponCommonService.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ public void validateCouponEligibility(Cart cart, Coupon coupon) {
3535
validateCartNotEmpty(cart);
3636
}
3737

38+
/**
39+
* 선택된 아이템들을 대상으로 쿠폰 적용 가능 여부를 검증합니다.
40+
* 주문 생성 시 사용합니다.
41+
*/
42+
public void validateCouponForSelectedItems(List<CartProduct> selectedItems, Coupon coupon) {
43+
validateCouponStatus(coupon);
44+
validateMinOrderAmountForSelectedItems(selectedItems, coupon);
45+
validateCouponConditionsForSelectedItems(selectedItems, coupon);
46+
validateSelectedItemsNotEmpty(selectedItems);
47+
}
48+
3849
/**
3950
* 쿠폰 할인 금액을 계산합니다.
4051
*/
@@ -242,4 +253,79 @@ private Map<Long, List<String>> getProductCategoryMap(Cart cart) {
242253

243254
return productCategoryMap;
244255
}
256+
257+
private void validateMinOrderAmountForSelectedItems(List<CartProduct> selectedItems, Coupon coupon) {
258+
if (coupon.getMinOrderAmount() != null) {
259+
int selectedItemsAmount = selectedItems.stream()
260+
.mapToInt(CartProduct::getTotalPrice)
261+
.sum();
262+
263+
if (selectedItemsAmount <= coupon.getMinOrderAmount()) {
264+
throw new CouponHandler(ErrorStatus.COUPON_MIN_ORDER_AMOUNT_NOT_MET);
265+
}
266+
}
267+
}
268+
269+
private void validateCouponConditionsForSelectedItems(List<CartProduct> selectedItems, Coupon coupon) {
270+
ConditionType conditionType = coupon.getConditionType();
271+
String conditionValues = coupon.getConditionValues();
272+
273+
switch (conditionType) {
274+
case ALL:
275+
break;
276+
case BRAND:
277+
validateBrandConditionForSelectedItems(selectedItems, conditionValues);
278+
break;
279+
case CATEGORY:
280+
validateCategoryConditionForSelectedItems(selectedItems, conditionValues);
281+
break;
282+
default:
283+
throw new CouponHandler(ErrorStatus.INVALID_COUPON_TYPE);
284+
}
285+
}
286+
287+
private void validateBrandConditionForSelectedItems(List<CartProduct> selectedItems, String brandNames) {
288+
List<String> allowedBrands = parseConditionValues(brandNames);
289+
if (allowedBrands.isEmpty()) {
290+
return;
291+
}
292+
293+
boolean hasValidBrand = selectedItems.stream()
294+
.anyMatch(cartProduct -> {
295+
return matchesBrandCondition(cartProduct.getProduct().getStore(), allowedBrands);
296+
});
297+
298+
if (!hasValidBrand) {
299+
throw new CouponHandler(ErrorStatus.COUPON_BRAND_CONDITION_NOT_MET);
300+
}
301+
}
302+
303+
private void validateCategoryConditionForSelectedItems(List<CartProduct> selectedItems, String categoryNames) {
304+
List<String> allowedCategories = parseConditionValues(categoryNames);
305+
if (allowedCategories.isEmpty()) {
306+
return;
307+
}
308+
309+
validateSelectedItemsNotEmpty(selectedItems);
310+
311+
List<Long> productIds = selectedItems.stream()
312+
.map(cp -> cp.getProduct().getId())
313+
.toList();
314+
315+
List<String> productCategoryNames = couponValidationRepository.findCategoryNamesByProductIds(productIds)
316+
.stream()
317+
.map(result -> (String) result[1])
318+
.toList();
319+
320+
boolean hasValidCategory = matchesCategoryCondition(productCategoryNames, allowedCategories);
321+
if (!hasValidCategory) {
322+
throw new CouponHandler(ErrorStatus.COUPON_CATEGORY_CONDITION_NOT_MET);
323+
}
324+
}
325+
326+
private void validateSelectedItemsNotEmpty(List<CartProduct> selectedItems) {
327+
if (selectedItems == null || selectedItems.isEmpty()) {
328+
throw new CouponHandler(ErrorStatus.CART_EMPTY);
329+
}
330+
}
245331
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.jajaja.domain.delivery.dto;
2+
3+
import com.jajaja.domain.order.entity.Order;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
7+
import java.time.LocalDate;
8+
9+
@Getter
10+
@Builder
11+
public class DeliveryInfoDto {
12+
private Long addressId;
13+
private String deliveryRequest;
14+
private String estimatedDeliveryDate;
15+
16+
public static DeliveryInfoDto of(Order order) {
17+
return DeliveryInfoDto.builder()
18+
.addressId(order.getDelivery().getId())
19+
.deliveryRequest(order.getDeliveryRequest())
20+
.estimatedDeliveryDate(LocalDate.now().plusDays(2).toString())
21+
.build();
22+
}
23+
}

src/main/java/com/jajaja/domain/delivery/entity/Delivery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class Delivery extends BaseEntity {
3232
@Column(nullable = false, length = 255)
3333
private String addressDetail;
3434

35-
@Column(length = 5)
35+
@Column(nullable = false, length = 5)
3636
private String zipcode;
3737

3838
@Column(length = 255)

src/main/java/com/jajaja/domain/member/entity/Member.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ public class Member extends BaseEntity {
4444

4545
@Column(nullable = false)
4646
private String email;
47+
48+
@Column(nullable = false)
49+
private Integer point;
4750

4851
@OneToOne(mappedBy = "member", fetch = FetchType.LAZY)
4952
private MemberBusinessCategory memberBusinessCategory;
@@ -83,8 +86,8 @@ public void updatePhone(String phone) {
8386
public void updateEmail(String email) {
8487
this.email = email;
8588
}
86-
87-
public void updateProfileUrl(String profileUrl) {
88-
this.profileUrl = profileUrl;
89-
}
89+
90+
public void updatePoint(int point) { this.point = point; }
91+
92+
public void updateProfileUrl(String profileUrl) { this.profileUrl = profileUrl; }
9093
}

src/main/java/com/jajaja/domain/member/entity/MemberCoupon.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import jakarta.persistence.*;
77
import lombok.*;
88

9+
import java.time.LocalDateTime;
10+
911
@Entity
1012
@Getter
1113
@Builder
@@ -21,11 +23,19 @@ public class MemberCoupon extends BaseEntity {
2123
@Column(nullable = false, length = 20)
2224
private CouponStatus status;
2325

26+
@Column
27+
private LocalDateTime usedAt;
28+
2429
@ManyToOne(fetch = FetchType.LAZY)
2530
@JoinColumn(name = "member_id")
2631
private Member member;
2732

2833
@ManyToOne(fetch = FetchType.LAZY)
2934
@JoinColumn(name = "coupon_id")
3035
private Coupon coupon;
36+
37+
public void use() {
38+
this.status = CouponStatus.USED;
39+
this.usedAt = LocalDateTime.now();
40+
}
3141
}

0 commit comments

Comments
 (0)