@@ -0,0 +1,153 @@
+package store.custom.service.editor;
+
+import static store.custom.constants.StringConstants.AFTER_PROMOTION_END;
+import static store.custom.constants.StringConstants.BEFORE_PROMOTION_START;
+import static store.custom.constants.StringConstants.RESPONSE_NO;
+import static store.custom.constants.StringConstants.RESPONSE_YES;
+
+import camp.nextstep.edu.missionutils.DateTimes;
+import java.time.LocalDate;
+import store.custom.model.PromotionResult.PromotionResult;
+import store.custom.model.order.OrderSheet;
+import store.custom.model.order.OrderedProduct;
+import store.custom.model.product.Product;
+import store.custom.model.product.Products;
+import store.custom.model.promotion.Promotion;
+import store.custom.model.promotion.Promotions;
+
+public class OrderSheetEditor {
+    // 주문서 초기 설정: 가격과 프로모션 정보 추가
+    public void addPromotionInfo(Products productCatalog, Promotions promotions, OrderSheet orderSheet) {
+        for (OrderedProduct orderProduct : orderSheet.getOrderSheet()) {
+            setProductPriceAndPromotion(orderProduct, productCatalog); // 총 가격과 프로모션 추가
+            setPromotionDetails(orderProduct, promotions); // 프로모션 관련 정보 추가
+        }
+    }
+
+    private void setProductPriceAndPromotion(OrderedProduct orderProduct, Products productCatalog) {
+        Product product = findOrderedProduct(orderProduct, productCatalog);
+        if (product != null) {
+            orderProduct.setTotalPrice(product.getPrice() * orderProduct.getQuantity());
+            setPromotionIfExist(orderProduct, product);
+        }
+    }
+
+    private Product findOrderedProduct(OrderedProduct orderProduct, Products productCatalog) {
+        for (Product product : productCatalog.getProducts()) {
+            if (product.getName().equals(orderProduct.getName())) {
+                return product;
+            }
+        }
+        return null;
+    }
+
+    private void setPromotionIfExist(OrderedProduct orderProduct, Product product) {
+        if (product.getPromotion() != null) {
+            orderProduct.setPromotion(product.getPromotion());
+        }
+    }
+
+    private void setPromotionDetails(OrderedProduct orderProduct, Promotions promotions) {
+        if (orderProduct.getPromotion() != null) {
+            LocalDate today = DateTimes.now().toLocalDate();
+            Promotion promotion = findPromotion(orderProduct.getPromotion(), promotions);
+            if (promotion != null) {
+                applyPromotionDates(orderProduct, today, promotion);
+                applyPromotionBuyAndGet(orderProduct, promotion);
+            }
+        }
+    }
+
+    private Promotion findPromotion(String promotionName, Promotions promotions) {
+        for (Promotion promotion : promotions.getPromotions()) {
+            if (promotion.getName().equals(promotionName)) {
+                return promotion;
+            }
+        }
+        return null;
+    }
+
+    private void applyPromotionDates(OrderedProduct orderProduct, LocalDate today, Promotion promotion) {
+        if (today.isBefore(LocalDate.parse(promotion.getStartDate()))) {
+            orderProduct.setPromotion(BEFORE_PROMOTION_START);
+        }
+
+        if (today.isAfter(LocalDate.parse(promotion.getEndDate()))) {
+            orderProduct.setPromotion(AFTER_PROMOTION_END);
+        }
+    }
+
+    private void applyPromotionBuyAndGet(OrderedProduct orderProduct, Promotion promotion) {
+        String orderProductPromotion = orderProduct.getPromotion();
+
+        if (orderProductPromotion != null && !orderProductPromotion.equals(BEFORE_PROMOTION_START)
+                && !orderProductPromotion.equals(AFTER_PROMOTION_END)) {
+            orderProduct.setBuy(promotion.getBuy());
+            orderProduct.setGet(promotion.getGet());
+        }
+    }
+
+    // 주문서 수정: 주문 수량에 다른 프로모션 적용 결과 반영
+    public void applyResponseForNoPromotion(String response, PromotionResult promotionResult,
+                                            OrderedProduct orderedProduct) {
+        if (response.equals(RESPONSE_YES)) {
+            processPurchaseWithNoDiscount(orderedProduct, promotionResult);
+        }
+        if (response.equals(RESPONSE_NO)) {
+            processNonPurchaseWithNoDiscount(orderedProduct, promotionResult);
+        }
+    }
+
+    private void processPurchaseWithNoDiscount(OrderedProduct orderedProduct, PromotionResult promotionResult) {
+        int promotionAppliedCount = promotionResult.getApplicablePromotionCount();
+        int nonPromotionProductCount = promotionResult.getNonPromotionProductCount();
+
+        orderedProduct.setBuy(orderedProduct.getBuy() * promotionAppliedCount + nonPromotionProductCount);
+        orderedProduct.setGet(orderedProduct.getGet() * promotionAppliedCount);
+    }
+
+    private void processNonPurchaseWithNoDiscount(OrderedProduct orderedProduct, PromotionResult promotionResult) {
+        int promotionAppliedCount = promotionResult.getApplicablePromotionCount();
+        int nonPromotionProductCount = promotionResult.getNonPromotionProductCount();
+
+        orderedProduct.setBuy(orderedProduct.getBuy() * promotionAppliedCount);
+        orderedProduct.setGet(orderedProduct.getGet() * promotionAppliedCount);
+        int productPrice = orderedProduct.getTotalPrice() / orderedProduct.getQuantity();
+        orderedProduct.setQuantity(orderedProduct.getQuantity() - nonPromotionProductCount); // 수량 감소
+        orderedProduct.setTotalPrice(productPrice * orderedProduct.getQuantity()); // 수량 감소에 따른 총 가격 변경
+    }
+
+    public void applyResponseForFreeProduct(String response, PromotionResult promotionResult,
+                                            OrderedProduct orderedProduct) {
+        if (response.equals(RESPONSE_YES)) {
+            processAdditionalPromotionApplied(orderedProduct, promotionResult);
+        }
+        if (response.equals(RESPONSE_NO)) {
+            processAdditionalPromotionNotApplied(orderedProduct, promotionResult);
+        }
+    }
+
+    private void processAdditionalPromotionApplied(OrderedProduct orderedProduct, PromotionResult promotionResult) {
+        int promotionAppliedCount = promotionResult.getApplicablePromotionCount();
+
+        orderedProduct.setBuy(orderedProduct.getBuy() * (promotionAppliedCount + 1));
+        int productPrice = orderedProduct.getTotalPrice() / orderedProduct.getQuantity();
+        orderedProduct.setQuantity(orderedProduct.getQuantity() + orderedProduct.getGet()); // 수량 증가
+        orderedProduct.setTotalPrice(productPrice * orderedProduct.getQuantity()); // 수량 증가에 따른 총 가격 변경
+        orderedProduct.setGet(orderedProduct.getGet() * (promotionAppliedCount + 1));
+    }
+
+    private void processAdditionalPromotionNotApplied(OrderedProduct orderedProduct, PromotionResult promotionResult) {
+        int promotionAppliedCount = promotionResult.getApplicablePromotionCount();
+
+        orderedProduct.setBuy(orderedProduct.getBuy() * (promotionAppliedCount + 1));
+        orderedProduct.setGet(orderedProduct.getGet() * promotionAppliedCount);
+    }
+
+    public void computeTotalWithPromotion(OrderedProduct orderedProduct, PromotionResult promotionResult) {
+        int promotionAppliedCount = promotionResult.getApplicablePromotionCount();
+
+        orderedProduct.setBuy(orderedProduct.getBuy() * promotionAppliedCount);
+        orderedProduct.setGet(orderedProduct.getGet() * promotionAppliedCount);
+    }
+}
\ No newline at end of file

리뷰: OrderSheetEditor의 역할이 많다는 점에서 저도 비슷한 생각입니다! 
+ **3주차 피드백 중 객체를 객체답게 사용한다** 피드백이 떠올랐어요. 일부 로직 중에서는 모델 내부에서 책임을 가져갈 수 있는 것들도 있는 것 같습니다. 

대표적으로 아래 메서드가 그런 것 같아요!
```
    private void setPromotionIfExist(OrderedProduct orderProduct, Product product) {
        if (product.getPromotion() != null) {
            orderProduct.setPromotion(product.getPromotion()); 
        }
    }
```
product.getPromotion()이 String이기 때문에 orderProduct 내부에서 처리할 수 있을 것 같습니다.

위 처럼 각 도메인에서 처리가능한 로직들은 없었을지 생각해보면 어떨까 싶습니다.