diff --git a/src/main/java/me/barion/capstoneprojectbarion/Entity/Sales.java b/src/main/java/me/barion/capstoneprojectbarion/Entity/Sales.java index 5d6d4ff..9e2bc96 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/Entity/Sales.java +++ b/src/main/java/me/barion/capstoneprojectbarion/Entity/Sales.java @@ -22,11 +22,15 @@ public class Sales { @Column(nullable = false) private Integer totalSales; // 총 매출 금액 + @Column(nullable = false) + private Integer totalCost; // 총 비용 + public Sales() { } - public Sales(LocalDateTime salesDate, Integer totalSales) { + public Sales(LocalDateTime salesDate, Integer totalSales, Integer totalCost) { this.salesDate = salesDate; this.totalSales = totalSales; + this.totalCost = totalCost; } } diff --git a/src/main/java/me/barion/capstoneprojectbarion/controller/SalesController.java b/src/main/java/me/barion/capstoneprojectbarion/controller/SalesController.java index 7280b29..a6bc4e1 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/controller/SalesController.java +++ b/src/main/java/me/barion/capstoneprojectbarion/controller/SalesController.java @@ -50,4 +50,18 @@ public ResponseEntity> getMonthlySales() { List monthlySales = salesService.calculateMonthlySales(); return ResponseEntity.ok(monthlySales); } + + @Operation(summary = "총 순이익 조회", description = "총 순이익을 조회합니다.") + @GetMapping("/totalProfit") + public ResponseEntity getTotalProfit() { + SalesDto totalProfit = salesService.calculateTotalProfit(); + return ResponseEntity.ok(totalProfit); + } + + @Operation(summary = "월별 순이익 조회", description = "월별 순이익을 조회합니다.") + @GetMapping("/monthlyProfit") + public ResponseEntity> getMonthlyProfit() { + List monthlyProfit = salesService.calculateMonthlyProfit(); + return ResponseEntity.ok(monthlyProfit); + } } diff --git a/src/main/java/me/barion/capstoneprojectbarion/repository/SalesRepository.java b/src/main/java/me/barion/capstoneprojectbarion/repository/SalesRepository.java index 90e20af..b9b926a 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/repository/SalesRepository.java +++ b/src/main/java/me/barion/capstoneprojectbarion/repository/SalesRepository.java @@ -2,10 +2,13 @@ import me.barion.capstoneprojectbarion.Entity.Sales; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository public interface SalesRepository extends JpaRepository { + @Query("SELECT SUM(s.totalSales - s.totalCost) FROM Sales s") + Integer sumTotalProfit(); } diff --git a/src/main/java/me/barion/capstoneprojectbarion/service/SalesService.java b/src/main/java/me/barion/capstoneprojectbarion/service/SalesService.java index 09963c3..7c04880 100644 --- a/src/main/java/me/barion/capstoneprojectbarion/service/SalesService.java +++ b/src/main/java/me/barion/capstoneprojectbarion/service/SalesService.java @@ -1,7 +1,7 @@ package me.barion.capstoneprojectbarion.service; import me.barion.capstoneprojectbarion.dto.SalesDto; -import me.barion.capstoneprojectbarion.Entity.Order; +import me.barion.capstoneprojectbarion.Entity.Order; // Order 엔티티는 이 메소드에서 직접 사용하지 않음 import me.barion.capstoneprojectbarion.Entity.Sales; import me.barion.capstoneprojectbarion.repository.OrderRepository; import me.barion.capstoneprojectbarion.repository.SalesRepository; @@ -11,6 +11,9 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; +import java.util.Map; +import java.time.YearMonth; @Service public class SalesService { @@ -21,87 +24,101 @@ public class SalesService { @Autowired private SalesRepository salesRepository; - // 총 매출 계산 (모든 주문의 총 금액 합산) public SalesDto calculateTotalSales() { - Integer totalAmount = orderRepository.sumTotalAmount(); // 모든 주문의 총 금액 합산 + Integer totalAmount = orderRepository.sumTotalAmount(); return new SalesDto(LocalDateTime.now(), totalAmount != null ? totalAmount : 0); } - // 연도별 매출 계산 (Order 데이터를 기반으로 그룹화) public List calculateYearlySales() { List orders = orderRepository.findAll(); List yearlySalesDtos = new ArrayList<>(); - orders.stream() - .map(order -> order.getOrderDate().withMonth(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0)) // 연도 단위로 그룹화 - .distinct() - .forEach(year -> { - Integer yearlyTotal = orders.stream() - .filter(order -> order.getOrderDate().getYear() == year.getYear()) - .mapToInt(Order::getTotalAmount) - .sum(); - yearlySalesDtos.add(new SalesDto(year, yearlyTotal)); - }); + Map salesByYear = orders.stream() + .collect(Collectors.groupingBy( + order -> order.getOrderDate().getYear(), + Collectors.summingInt(Order::getTotalAmount) + )); + salesByYear.forEach((year, total) -> { + yearlySalesDtos.add(new SalesDto(LocalDateTime.of(year, 1, 1, 0, 0), total)); + }); + yearlySalesDtos.sort((s1, s2) -> s1.getSalesDate().compareTo(s2.getSalesDate())); return yearlySalesDtos; } - // 월별 매출 계산 (Order 데이터를 기반으로 그룹화) public List calculateMonthlySales() { List orders = orderRepository.findAll(); List monthlySalesDtos = new ArrayList<>(); - orders.stream() - .map(order -> order.getOrderDate().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0)) // 월 단위로 그룹화 - .distinct() - .forEach(month -> { - Integer monthlyTotal = orders.stream() - .filter(order -> order.getOrderDate().getYear() == month.getYear() - && order.getOrderDate().getMonth() == month.getMonth()) - .mapToInt(Order::getTotalAmount) - .sum(); - monthlySalesDtos.add(new SalesDto(month, monthlyTotal)); - }); + Map salesByMonth = orders.stream() + .collect(Collectors.groupingBy( + order -> YearMonth.from(order.getOrderDate()), + Collectors.summingInt(Order::getTotalAmount) + )); + salesByMonth.forEach((yearMonth, total) -> { + monthlySalesDtos.add(new SalesDto(yearMonth.atDay(1).atStartOfDay(), total)); + }); + monthlySalesDtos.sort((s1, s2) -> s1.getSalesDate().compareTo(s2.getSalesDate())); return monthlySalesDtos; } - - - // 시간별 매출 계산 (Order 데이터를 기반으로 그룹화) public List calculateHourlySales() { - List orders = orderRepository.findAll(); // 모든 주문 조회 + List orders = orderRepository.findAll(); List hourlySalesDtos = new ArrayList<>(); - orders.stream() - .map(order -> order.getOrderDate().withMinute(0).withSecond(0).withNano(0)) // 시간 단위로 그룹화 - .distinct() - .forEach(hour -> { - Integer hourlyTotal = orders.stream() - .filter(order -> order.getOrderDate().withMinute(0).withSecond(0).withNano(0).equals(hour)) - .mapToInt(Order::getTotalAmount) - .sum(); - hourlySalesDtos.add(new SalesDto(hour, hourlyTotal)); - }); + Map salesByHour = orders.stream() + .collect(Collectors.groupingBy( + order -> order.getOrderDate().withMinute(0).withSecond(0).withNano(0), + Collectors.summingInt(Order::getTotalAmount) + )); + salesByHour.forEach((hour, total) -> { + hourlySalesDtos.add(new SalesDto(hour, total)); + }); + hourlySalesDtos.sort((s1, s2) -> s1.getSalesDate().compareTo(s2.getSalesDate())); return hourlySalesDtos; } - // 일별 매출 계산 (Order 데이터를 기반으로 그룹화) public List calculateDailySales() { - List orders = orderRepository.findAll(); // 모든 주문 조회 + List orders = orderRepository.findAll(); List dailySalesDtos = new ArrayList<>(); - orders.stream() - .map(order -> order.getOrderDate().toLocalDate()) // 날짜 단위로 그룹화 - .distinct() - .forEach(date -> { - Integer dailyTotal = orders.stream() - .filter(order -> order.getOrderDate().toLocalDate().equals(date)) - .mapToInt(Order::getTotalAmount) - .sum(); - dailySalesDtos.add(new SalesDto(date.atStartOfDay(), dailyTotal)); - }); + Map salesByDay = orders.stream() + .collect(Collectors.groupingBy( + order -> order.getOrderDate().toLocalDate().atStartOfDay(), + Collectors.summingInt(Order::getTotalAmount) + )); + salesByDay.forEach((day, total) -> { + dailySalesDtos.add(new SalesDto(day, total)); + }); + dailySalesDtos.sort((s1, s2) -> s1.getSalesDate().compareTo(s2.getSalesDate())); return dailySalesDtos; } + + public SalesDto calculateTotalProfit() { + + Integer totalProfit = salesRepository.sumTotalProfit(); + return new SalesDto(LocalDateTime.now(), totalProfit != null ? totalProfit : 0); + } + + public List calculateMonthlyProfit() { + List salesList = salesRepository.findAll(); // 모든 Sales 데이터 조회 + List monthlyProfitDtos = new ArrayList<>(); + + Map profitByMonth = salesList.stream() + .collect(Collectors.groupingBy( + sales -> YearMonth.from(sales.getSalesDate()), // salesDate에서 YearMonth 추출 + Collectors.summingInt(sales -> sales.getTotalSales() - sales.getTotalCost()) // 순이익 계산 + )); + + profitByMonth.forEach((yearMonth, profit) -> { + + monthlyProfitDtos.add(new SalesDto(yearMonth.atDay(1).atStartOfDay(), profit)); + }); + + monthlyProfitDtos.sort((dto1, dto2) -> dto1.getSalesDate().compareTo(dto2.getSalesDate())); + + return monthlyProfitDtos; + } }