Skip to content

Commit

Permalink
Merge pull request #59 from Team-HMH/feat/#51-modify-challenge-api
Browse files Browse the repository at this point in the history
feat - μ±Œλ¦°μ§€ 생성 api μˆ˜μ •
  • Loading branch information
jumining authored Jan 17, 2024
2 parents a0759fc + 430c926 commit c990f83
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public ResponseEntity<ApiResponse<?>> orderAddApp(
@RequestHeader("OS") final String os,
@RequestBody final AppArrayGoalTimeRequest request
) {
appService.addAppsByUserId(userId, request.apps(), os);
appService.addAppsAndUpdateRemainingDailyChallenge(userId, request.apps(), os);
return ResponseEntity
.status(AppSuccess.ADD_APP_SUCCESS.getHttpStatus())
.body(ApiResponse.success(AppSuccess.ADD_APP_SUCCESS, new EmptyJsonResponse()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ public record AppGoalTimeRequest(
String appCode,
Long goalTime
) {
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package sopt.org.HMH.domain.app.dto.response;

import sopt.org.HMH.domain.app.domain.App;

public record AppGoalTimeResponse(
String appCode,
Long goalTime
) {
public static AppGoalTimeResponse of(App app) {
return new AppGoalTimeResponse(app.getAppCode(), app.getGoalTime());
}
}
34 changes: 21 additions & 13 deletions src/main/java/sopt/org/HMH/domain/app/service/AppService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import sopt.org.HMH.domain.app.dto.request.AppDeleteRequest;
import sopt.org.HMH.domain.app.dto.request.AppGoalTimeRequest;
import sopt.org.HMH.domain.app.repository.AppRepository;
import sopt.org.HMH.domain.dailychallenge.domain.DailyChallenge;
import sopt.org.HMH.domain.dailychallenge.service.DailyChallengeService;
import java.util.ArrayList;

import java.util.List;

@Service
Expand All @@ -21,22 +22,29 @@ public class AppService {

@Transactional
public void removeApp(Long userId, AppDeleteRequest request, String os) {
Long todayDailyChallengeId = dailyChallengeService.getTodayDailyChallengeByUserId(userId).getId();
App app = appRepository.findByDailyChallengeIdAndAppCodeAndOs(todayDailyChallengeId, request.appCode(), os);
App app = appRepository.findByDailyChallengeIdAndAppCodeAndOs(
dailyChallengeService.getTodayDailyChallengeByUserId(userId).getId(),
request.appCode(),
os);

appRepository.deleteById(app.getId());
}

@Transactional
public void addAppsByUserId(Long userId, List<AppGoalTimeRequest> requests, String os) {
List<App> apps = new ArrayList<>();
for (AppGoalTimeRequest request : requests) {
apps.add(App.builder()
.dailyChallenge(dailyChallengeService.getTodayDailyChallengeByUserId(userId))
.appCode(request.appCode())
.goalTime(request.goalTime())
.os(os).build());
}
appRepository.saveAll(apps);
public void addAppsAndUpdateRemainingDailyChallenge(Long userId, List<AppGoalTimeRequest> requests, String os) {
dailyChallengeService.getRemainingDailyChallengesByUserId(userId).stream()
.map((dailyChallenge -> addApps(dailyChallenge, requests, os)));
}

@Transactional
public List<App> addApps(DailyChallenge dailyChallenge, List<AppGoalTimeRequest> requests, String os) {
List<App> appStream = requests.stream()
.map(request -> App.builder().dailyChallenge(dailyChallenge)
.appCode(request.appCode())
.goalTime(request.goalTime())
.os(os).build()
).toList();

return appRepository.saveAll(appStream);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
import org.springframework.web.bind.annotation.RestController;
import sopt.org.HMH.domain.challenge.domain.exception.ChallengeSuccess;
import sopt.org.HMH.domain.challenge.dto.request.ChallengeRequest;
import sopt.org.HMH.domain.challenge.dto.response.AddChallengeResponse;
import sopt.org.HMH.domain.challenge.dto.response.ChallengeResponse;
import sopt.org.HMH.domain.challenge.service.ChallengeService;
import sopt.org.HMH.global.auth.UserId;
import sopt.org.HMH.global.common.response.ApiResponse;
import sopt.org.HMH.global.common.response.EmptyJsonResponse;

@RestController
@RequiredArgsConstructor
Expand All @@ -24,12 +24,17 @@ public class ChallengeController {
private final ChallengeService challengeService;

@PostMapping
public ResponseEntity<ApiResponse<AddChallengeResponse>> orderAddChallenge(@UserId final Long userId,
@RequestBody final ChallengeRequest request) {
public ResponseEntity<ApiResponse<?>> orderAddChallenge(@UserId final Long userId,
@RequestHeader("OS") final String os,
@RequestBody final ChallengeRequest request) {
challengeService.updateChallengeForPeriodWithInfo(
challengeService.addChallenge(userId, request.period(), request.goalTime()),
challengeService.getLastApps(userId),
os);

return ResponseEntity
.status(ChallengeSuccess.ADD_CHALLENGE_SUCCESS.getHttpStatus())
.body(ApiResponse.success(ChallengeSuccess.ADD_CHALLENGE_SUCCESS,
challengeService.addChallenge(userId, request.period(), request.goalTime())));
.body(ApiResponse.success(ChallengeSuccess.ADD_CHALLENGE_SUCCESS, new EmptyJsonResponse()));
}

@GetMapping
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package sopt.org.HMH.domain.challenge.dto.request;

import sopt.org.HMH.domain.app.dto.request.AppGoalTimeRequest;
import java.util.List;

public record ChallengeRequest(
Integer period,
Long goalTime
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package sopt.org.HMH.domain.challenge.dto.response;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.val;
import sopt.org.HMH.domain.app.dto.response.AppGoalTimeResponse;
import sopt.org.HMH.domain.challenge.domain.Challenge;
import sopt.org.HMH.domain.dailychallenge.domain.DailyChallenge;
import sopt.org.HMH.domain.dailychallenge.domain.Status;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

@Builder(access = AccessLevel.PRIVATE)
@Builder
public record ChallengeResponse(
Integer period,
List<Status> statuses,
Expand All @@ -21,25 +19,24 @@ public record ChallengeResponse(
List<AppGoalTimeResponse> apps
) {
public static ChallengeResponse of(Challenge challenge, String os) {
val dailyChallenges = challenge.getDailyChallenges();
List<DailyChallenge> dailyChallenges = challenge.getDailyChallenges();

val statuses = new ArrayList<Status>();
for (val dailyChallenge : dailyChallenges) {
statuses.add(dailyChallenge.getStatus());
}

val todayIndex = calculateDaysSinceToday(challenge.getCreatedAt());
val todayDailyChallenge = dailyChallenges.get(todayIndex);
int daysSinceToday = (int) ChronoUnit.DAYS.between(LocalDateTime.now().toLocalDate(),
challenge.getDailyChallenges().get(0).getCreatedAt().toLocalDate());
int todayIndex = daysSinceToday >= challenge.getPeriod() ? -1 : daysSinceToday;
int dailyChallengeIndex = todayIndex == -1 ? dailyChallenges.size()-1 : todayIndex;

return ChallengeResponse.builder()
.period(challenge.getPeriod())
.statuses(statuses)
.statuses(dailyChallenges.stream()
.map(dailyChallenge -> { return dailyChallenge.getStatus(); })
.toList())
.todayIndex(todayIndex)
.goalTime(todayDailyChallenge.getGoalTime())
.apps(todayDailyChallenge.getApps()
.goalTime(dailyChallenges.get(dailyChallengeIndex).getGoalTime())
.apps(dailyChallenges.get(dailyChallengeIndex).getApps()
.stream()
.filter(app -> os.equals(app.getOs()))
.map(AppGoalTimeResponse::of)
.map(app -> new AppGoalTimeResponse(app.getAppCode(), app.getGoalTime()))
.toList())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,55 @@
package sopt.org.HMH.domain.challenge.service;

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sopt.org.HMH.domain.app.dto.request.AppGoalTimeRequest;
import sopt.org.HMH.domain.app.service.AppService;
import sopt.org.HMH.domain.challenge.domain.Challenge;
import sopt.org.HMH.domain.challenge.dto.response.AddChallengeResponse;
import sopt.org.HMH.domain.challenge.dto.response.ChallengeResponse;
import sopt.org.HMH.domain.challenge.repository.ChallengeRepository;
import sopt.org.HMH.domain.dailychallenge.domain.DailyChallenge;
import sopt.org.HMH.domain.dailychallenge.service.DailyChallengeService;

import java.util.List;

@Service
@RequiredArgsConstructor
public class ChallengeService {

private final ChallengeRepository challengeRepository;
private final DailyChallengeService dailyChallengeService;
private final AppService appService;

@Transactional
public Challenge addChallenge(Long userId, Integer period, Long goalTime) {
return challengeRepository.save(Challenge.builder()
.period(period)
.goalTime(goalTime)
.userId(userId).build());
}

@Transactional
public AddChallengeResponse addChallenge(Long userId, Integer period, Long goalTime) {
Challenge challenge = challengeRepository.save(Challenge.builder()
.period(period)
.goalTime(goalTime)
.userId(userId).build());
dailyChallengeService.addDailyChallengesForPeriod(challenge, period, goalTime);
return AddChallengeResponse.of(challenge.getId());
public Challenge updateChallengeForPeriodWithInfo(Challenge challenge, List<AppGoalTimeRequest> apps, String os) {
for (int count = 0; count < challenge.getPeriod(); count++) {
DailyChallenge dailyChallenge = dailyChallengeService.addDailyChallenge(challenge);
appService.addApps(dailyChallenge, apps, os);
}

return challenge;
}

public List<AppGoalTimeRequest> getLastApps(Long userId) {
List<DailyChallenge> lastDailyChallenges = challengeRepository.findFirstByUserIdOrderByCreatedAtDesc(userId).getDailyChallenges();
List<AppGoalTimeRequest> lastApps = lastDailyChallenges.get(lastDailyChallenges.size()-1)
.getApps()
.stream()
.map(app -> new AppGoalTimeRequest(app.getAppCode(), app.getGoalTime()))
.toList();
return lastApps;
}

public ChallengeResponse getChallenge(Long userId, String os) {
val challenge = challengeRepository.findFirstByUserIdOrderByCreatedAtDesc(userId);
return ChallengeResponse.of(challenge, os);
return ChallengeResponse.of(challengeRepository.findFirstByUserIdOrderByCreatedAtDesc(userId), os);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package sopt.org.HMH.domain.dailychallenge.dto.response;

import lombok.AccessLevel;
import lombok.Builder;
import sopt.org.HMH.domain.app.dto.response.AppGoalTimeResponse;
import sopt.org.HMH.domain.dailychallenge.domain.DailyChallenge;

import java.util.List;

@Builder(access = AccessLevel.PRIVATE)
@Builder
public record DailyChallengeResponse(
String status,
Long goalTime,
Expand All @@ -20,7 +19,7 @@ public static DailyChallengeResponse of(DailyChallenge dailyChallenge, String os
.apps(dailyChallenge.getApps()
.stream()
.filter(app -> os.equals(app.getOs()))
.map(AppGoalTimeResponse::of)
.map(app -> new AppGoalTimeResponse(app.getAppCode(), app.getGoalTime()))
.toList())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package sopt.org.HMH.domain.dailychallenge.service;

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sopt.org.HMH.domain.app.domain.App;
Expand All @@ -16,36 +15,27 @@

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Transactional
public class DailyChallengeService {

private final DailyChallengeRepository dailyChallengeRepository;
private final ChallengeRepository challengeRepository;
private final AppRepository appRepository;

@Transactional
public List<DailyChallenge> addDailyChallengesForPeriod(Challenge challenge, Integer period, Long goalTime) {
List<DailyChallenge> dailyChallenges = new ArrayList<>();
for (int count = 0; count < period; count++) {
dailyChallenges.add(DailyChallenge.builder()
.challenge(challenge)
.goalTime(goalTime)
.build());
}
dailyChallengeRepository.saveAll(dailyChallenges);

return dailyChallenges;
public DailyChallenge addDailyChallenge(Challenge challenge) {
return dailyChallengeRepository.save(DailyChallenge.builder()
.challenge(challenge)
.goalTime(challenge.getGoalTime())
.build());
}

public DailyChallengeResponse getDailyChallenge(Long userId, String os) {
DailyChallenge dailyChallenge = getTodayDailyChallengeByUserId(userId);

return DailyChallengeResponse.of(dailyChallenge, os);
return DailyChallengeResponse.of(getTodayDailyChallengeByUserId(userId), os);
}

@Transactional
Expand All @@ -57,24 +47,31 @@ public void modifyDailyChallengeStatusFailure(Long userId) {
@Transactional
public void modifyDailyChallengeStatus(Long userId, List<AppUsageTimeRequest> requests, String os) {
DailyChallenge todayDailyChallenge = getTodayDailyChallengeByUserId(userId);
long successCount = requests.stream()
.map(request -> {
long successCount = requests.stream()
.filter(request -> {
App app = appRepository.findByDailyChallengeIdAndAppCodeAndOs(
todayDailyChallenge.getId(), request.appCode(), os);
app.setUsageTime(request.usageTime());
return request.usageTime() <= app.getGoalTime();
})
.filter(Boolean::booleanValue)
.count();
return (request.usageTime() <= app.getGoalTime());
}).count();
Status status = (successCount == requests.size()) ? Status.UNEARNED : Status.FAILURE;
todayDailyChallenge.setStatus(status);
}

public DailyChallenge getTodayDailyChallengeByUserId(Long userId) {
Challenge challenge = challengeRepository.findFirstByUserIdOrderByCreatedAtDesc(userId);
val startDateOfChallenge = challenge.getCreatedAt().toLocalDate();
val todayDailyChallengeIndex = (int) ChronoUnit.DAYS.between(startDateOfChallenge, LocalDateTime.now().toLocalDate());

return challenge.getDailyChallenges().get(todayDailyChallengeIndex);

return challenge.getDailyChallenges().get(calculateDaysSinceToday(challenge.getCreatedAt()));
}

public List<DailyChallenge> getRemainingDailyChallengesByUserId(Long userId) {
Challenge challenge = challengeRepository.findFirstByUserIdOrderByCreatedAtDesc(userId);

return challenge.getDailyChallenges()
.subList(calculateDaysSinceToday(challenge.getCreatedAt()), challenge.getDailyChallenges().size());
}

private Integer calculateDaysSinceToday(LocalDateTime dateToCompare) {
return (int) ChronoUnit.DAYS.between(LocalDateTime.now().toLocalDate(), dateToCompare.toLocalDate());
}
}
Loading

0 comments on commit c990f83

Please sign in to comment.