Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 0 additions & 29 deletions HELP.md

This file was deleted.

1 change: 0 additions & 1 deletion README.md

This file was deleted.

3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ dependencies {

// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

// WebClient (for Cafe24 API integration)
implementation 'org.springframework.boot:spring-boot-starter-webflux'
}

tasks.named('test') {
Expand Down
45 changes: 45 additions & 0 deletions docs/rds_create_tables.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
-- 카페24 고객 주문 관련 테이블 생성 SQL
-- 배포 전에 RDS에서 실행해야 합니다.

-- 1. customer_orders 테이블 생성
CREATE TABLE IF NOT EXISTS customer_orders (
customer_order_id BIGINT AUTO_INCREMENT PRIMARY KEY,
cafe24_order_id VARCHAR(50) NOT NULL UNIQUE,
order_at DATETIME NOT NULL,
is_paid BOOLEAN NOT NULL DEFAULT FALSE,
is_canceled BOOLEAN NOT NULL DEFAULT FALSE,
payment_method VARCHAR(100),
payment_amount DECIMAL(10, 2) NOT NULL,
billing_name VARCHAR(100) NOT NULL,
member_id VARCHAR(100),
member_email VARCHAR(100),
initial_order_price_amount DECIMAL(10, 2) NOT NULL,
shipping_fee DECIMAL(10, 2) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_cafe24_order_id (cafe24_order_id),
INDEX idx_order_at (order_at),
INDEX idx_is_paid (is_paid),
INDEX idx_is_canceled (is_canceled)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 2. customer_order_items 테이블 생성
CREATE TABLE IF NOT EXISTS customer_order_items (
customer_order_item_id BIGINT AUTO_INCREMENT PRIMARY KEY,
customer_order_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
product_code VARCHAR(50) NOT NULL,
product_name VARCHAR(255) NOT NULL,
quantity INT NOT NULL,
option_value VARCHAR(255),
variant_code VARCHAR(50),
item_code VARCHAR(50),
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (customer_order_id) REFERENCES customer_orders(customer_order_id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES products(product_id) ON DELETE RESTRICT,
INDEX idx_customer_order_id (customer_order_id),
INDEX idx_product_id (product_id),
INDEX idx_product_code (product_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableJpaAuditing
@SpringBootApplication
@EnableScheduling
public class InventoryServerApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.almang.inventory.customerorder.controller;

import com.almang.inventory.customerorder.dto.request.CustomerOrderRequest;
import com.almang.inventory.customerorder.service.CustomerOrderService;
import com.almang.inventory.global.api.ApiResponse;
import com.almang.inventory.global.api.SuccessMessage;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/customer-orders") // 카페24 연동을 위한 기본 경로
public class CustomerOrderController {

private final CustomerOrderService customerOrderService;

/**
* 카페24로부터 주문 정보를 수신하고 처리하는 API 엔드포인트
* (재고 감소 로직은 CustomerOrderService에서 정책에 따라 구현 대기 중)
*/
@PostMapping
@ResponseStatus(HttpStatus.CREATED) // 성공적으로 생성되었음을 의미
public ApiResponse<Long> receiveCafe24Order(@Valid @RequestBody CustomerOrderRequest request) {
log.info("카페24로부터 주문 정보 수신: Order ID = {}", request.getCafe24OrderId());

Long customerOrderId = customerOrderService.createCustomerOrderAndProcessStock(request);

return ApiResponse.success(SuccessMessage.CUSTOMER_ORDER_CREATED, customerOrderId);
}

// 추가적인 고객 주문 관련 API 엔드포인트가 필요할 수 있습니다.
// 예: 특정 기간 동안의 고객 주문 조회, 특정 고객의 주문 내역 조회 등
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.almang.inventory.customerorder.domain;

import com.almang.inventory.global.entity.BaseTimeEntity;
import com.almang.inventory.user.domain.User; // 고객 정보가 필요하다면 나중에 User 엔티티와 연결할 수 있습니다.
import jakarta.persistence.*;
import lombok.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "customer_orders")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class CustomerOrder extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_order_id")
private Long id;

// 카페24 주문 고유 번호
@Column(name = "cafe24_order_id", unique = true, nullable = false, length = 50)
private String cafe24OrderId;

// 주문 일시
@Column(name = "order_at", nullable = false)
private LocalDateTime orderAt;

// 결제 완료 여부
@Column(name = "is_paid", nullable = false)
private boolean isPaid;

// 취소 여부
@Column(name = "is_canceled", nullable = false)
private boolean isCanceled;

// 결제 수단 명
@Column(name = "payment_method", length = 100)
private String paymentMethod;

// 실제 결제 금액
@Column(name = "payment_amount", precision = 10, scale = 2, nullable = false)
private BigDecimal paymentAmount;

// 주문자 이름 (Billing Name)
@Column(name = "billing_name", nullable = false, length = 100)
private String billingName;

// 회원 ID (Cafe24 회원 ID)
@Column(name = "member_id", length = 100)
private String memberId;

// 회원 이메일
@Column(name = "member_email", length = 100)
private String memberEmail;

// 초기 주문 금액 (상품 가격 합계)
@Column(name = "initial_order_price_amount", precision = 10, scale = 2, nullable = false)
private BigDecimal initialOrderPriceAmount;

// 배송비
@Column(name = "shipping_fee", precision = 10, scale = 2, nullable = false)
private BigDecimal shippingFee;

// 고객 주문 상품 상세 목록
@OneToMany(mappedBy = "customerOrder", cascade = CascadeType.ALL, orphanRemoval = true)
@Builder.Default
private List<CustomerOrderItem> items = new ArrayList<>();

// 편의 메서드: 주문 항목 추가
public void addOrderItem(CustomerOrderItem item) {
items.add(item);
item.setCustomerOrder(this);
}

// 결제 상태 업데이트
public void updatePaidStatus(boolean isPaid) {
this.isPaid = isPaid;
}

// 취소 상태 업데이트
public void updateCanceledStatus(boolean isCanceled) {
this.isCanceled = isCanceled;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.almang.inventory.customerorder.domain;

import com.almang.inventory.global.entity.BaseTimeEntity;
import com.almang.inventory.product.domain.Product;
import jakarta.persistence.*;
import lombok.*;

import java.math.BigDecimal;

@Entity
@Table(name = "customer_order_items")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class CustomerOrderItem extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_order_item_id")
private Long id;

// 어떤 고객 주문에 속하는지
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "customer_order_id", nullable = false)
private CustomerOrder customerOrder;

// 어떤 상품인지 (기존 Product 엔티티와 연결)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "product_id", nullable = false)
private Product product;

// 카페24에서 넘어오는 상품 코드 (Product 엔티티의 code와 매핑)
@Column(name = "product_code", nullable = false, length = 50)
private String productCode;

// 상품명 (주문 시점의 상품명)
@Column(name = "product_name", nullable = false, length = 255)
private String productName;

// 주문 수량
@Column(name = "quantity", nullable = false)
private Integer quantity;

// 상품 옵션 값 (예: 종류=반짝반짝 스피아민트 미백)
@Column(name = "option_value", length = 255)
private String optionValue;

// 상품 옵션별 고유 코드 (Variant Code)
@Column(name = "variant_code", length = 50)
private String variantCode;

// (카페24) 주문 내 상품 항목 코드 (Item Code)
@Column(name = "item_code", length = 50)
private String itemCode;

// 편의 메서드: 부모 주문 설정
public void setCustomerOrder(CustomerOrder customerOrder) {
this.customerOrder = customerOrder;
}

// 편의 메서드: 상품 설정
public void setProduct(Product product) {
this.product = product;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.almang.inventory.customerorder.dto.request;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CustomerOrderItemRequest {

@NotBlank
@JsonProperty("product_code")
private String productCode;

@NotBlank
@JsonProperty("product_name")
private String productName;

@NotNull
@JsonProperty("quantity")
private Integer quantity;

@JsonProperty("option_value")
private String optionValue;

@JsonProperty("variant_code")
private String variantCode;

@JsonProperty("item_code")
private String itemCode;
}
Loading