Skip to content

Commit

Permalink
Merge branch 'refs/heads/main' into gib/#12
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/com/demo/chattodo/domain/controller/ScheduleController.java
#	src/main/java/com/demo/chattodo/domain/service/ScheduleService.java
#	src/main/resources/init.sql
  • Loading branch information
swandevson committed Sep 6, 2024
2 parents d5e944a + 141bb84 commit d434f9f
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 12 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,6 @@ gradle-app.setting
# Java heap dump
*.hprof

# End of https://www.toptal.com/developers/gitignore/api/intellij+all,java,gradle
# End of https://www.toptal.com/developers/gitignore/api/intellij+all,java,gradle

**/main/generated
20 changes: 20 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,28 @@ dependencies {
// Database
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'

// Querydsl
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
}

tasks.named('test') {
useJUnitPlatform()
}

def querydslDir = "src/main/generated"

sourceSets {
main.java.srcDirs += [ querydslDir ]
}

tasks.withType(JavaCompile).configureEach {
options.getGeneratedSourceOutputDirectory().set(file(querydslDir))
}

clean {
delete file(querydslDir)
}
20 changes: 20 additions & 0 deletions src/main/java/com/demo/chattodo/configure/QuerydslConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.demo.chattodo.configure;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.querydsl.jpa.impl.JPAQueryFactory;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

@Configuration
public class QuerydslConfig {
@PersistenceContext
private EntityManager entityManager;

@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.demo.chattodo.domain.controller;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

Expand All @@ -19,6 +20,7 @@
import com.demo.chattodo.domain.dto.request.ScheduleCreateDTO;
import com.demo.chattodo.domain.dto.request.ScheduleUpdateDTO;
import com.demo.chattodo.domain.dto.response.ScheduleCountResponseDTO;
import com.demo.chattodo.domain.dto.response.ScheduleInfoResponseDTO;
import com.demo.chattodo.domain.service.ScheduleService;

import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -54,14 +56,6 @@ public List<ScheduleCountResponseDTO> countScheduleOfEachDay(
);
}

@PostMapping
public ResponseEntity<?> createSchedule(
@RequestHeader("member_id") String memberId,
@RequestBody ScheduleCreateDTO dto) {

return ResponseEntity.ok().body(scheduleService.saveSchedule(memberId, dto));
}

@DeleteMapping("/{scheduleId}")
public ResponseEntity<?> deleteSchedule(
@RequestHeader("member_id") String memberId,
Expand All @@ -83,4 +77,42 @@ public ResponseEntity<?> updateSchedule(
scheduleService.updateSchedule(memberId, scheduleId, dto);
return ResponseEntity.ok().build();
}

@PostMapping
public ResponseEntity<?> createSchedule(
@RequestHeader("member_id") String memberId,
@RequestBody ScheduleCreateDTO dto) {

return ResponseEntity.ok().body(scheduleService.saveSchedule(memberId, dto));
}

@GetMapping("/search")
public List<ScheduleInfoResponseDTO> searchAllByConditions(
@RequestHeader("member_id") String memberId,
@RequestParam(value = "start_date", required = false) LocalDate startDate,
@RequestParam(value = "start_time", required = false) LocalTime startTime,
@RequestParam(value = "end_date", required = false) LocalDate endDate,
@RequestParam(value = "end_time", required = false) LocalTime endTime,
@RequestParam(value = "title", required = false) String title,
@RequestParam(value = "place", required = false) String place) {

LocalDateTime startDateTime = null;

if (startDate != null) {
startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
if (startTime != null) {
startDateTime = LocalDateTime.of(startDate, startTime);
}
}

LocalDateTime endDateTime = null;
if (endDate != null) {
endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
if (endTime != null) {
endDateTime = LocalDateTime.of(endDate, endTime);
}
}

return scheduleService.searchAllByConditions(memberId, startDateTime, endDateTime, title, place);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.demo.chattodo.domain.dto.response;

import java.time.LocalDateTime;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class ScheduleInfoResponseDTO {
private Long id;
private String title;
private LocalDateTime startDateTime;
private LocalDateTime endDateTime;
private String place;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import com.demo.chattodo.domain.entity.Schedule;

public interface ScheduleRepository extends JpaRepository<Schedule, Long> {
public interface ScheduleRepository extends JpaRepository<Schedule, Long>, ScheduleRepositoryCustom {
// 유저의 일정기간내 모든 일정 가져오기
@Query("SELECT s FROM Schedule s WHERE s.memberId = :memberId AND s.startDateTime >= :startDate AND s.endDateTime <= :endDate ORDER BY s.startDateTime ASC ")
List<Schedule> findAllByDateRangeAndMemberId(@Param("startDate") LocalDateTime startDate,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.demo.chattodo.domain.repository;

import java.time.LocalDateTime;
import java.util.List;

import com.demo.chattodo.domain.entity.Schedule;

public interface ScheduleRepositoryCustom {
// 여러 조건들을 통해 일정 가져오기
List<Schedule> searchAllByConditions(String memberId, LocalDateTime startDateTime, LocalDateTime endDateTime,
String title, String place);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.demo.chattodo.domain.repository;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.stereotype.Repository;

import com.demo.chattodo.domain.entity.QSchedule;
import com.demo.chattodo.domain.entity.Schedule;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class ScheduleRepositoryImpl implements ScheduleRepositoryCustom {
private final JPAQueryFactory queryFactory;

// 여러 조건들을 통해 일정 가져오기
@Override
public List<Schedule> searchAllByConditions(String memberId, LocalDateTime startDateTime, LocalDateTime endDateTime,
String title,
String place) {
QSchedule schedule = QSchedule.schedule;

BooleanBuilder builder = new BooleanBuilder();

// 멤버 ID는 필수 조건
builder.and(schedule.memberId.eq(memberId));

// 시작일시 조건
if (startDateTime != null) {
builder.and(schedule.startDateTime.goe(startDateTime));
}

// 종료일시 조건
if (endDateTime != null) {
builder.and(schedule.endDateTime.loe(endDateTime));
}

// 제목 조건 (부분 일치)
if (title != null && !title.isEmpty()) {
builder.and(schedule.title.containsIgnoreCase(title));
}

// 장소 조건 (부분 일치)
if (place != null && !place.isEmpty()) {
builder.and(schedule.place.containsIgnoreCase(place));
}

return queryFactory
.selectFrom(schedule)
.where(builder)
.orderBy(schedule.startDateTime.asc())
.fetch();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.demo.chattodo.domain.dto.request.ScheduleCreateDTO;
import com.demo.chattodo.domain.dto.request.ScheduleUpdateDTO;
import com.demo.chattodo.domain.dto.response.ScheduleCountResponseDTO;
import com.demo.chattodo.domain.dto.response.ScheduleInfoResponseDTO;
import com.demo.chattodo.domain.entity.Schedule;
import com.demo.chattodo.domain.repository.ScheduleRepository;
import com.demo.chattodo.domain.utils.DateTimeUtil;
Expand Down Expand Up @@ -52,6 +53,7 @@ public List<ScheduleCountResponseDTO> countScheduleOfEachDay(String memberId, Lo
.forEach(entry -> response.add(new ScheduleCountResponseDTO(entry.getKey(), entry.getValue())));

return response;

}

@Transactional
Expand Down Expand Up @@ -90,4 +92,29 @@ public void updateSchedule(String memberId, Long scheduleId, ScheduleUpdateDTO d
DateTimeUtil.getEndLocalDateTime(dto.getEndDate(), dto.getEndTime()),
dto.getPlace()));
}

public List<ScheduleInfoResponseDTO> searchAllByConditions(String memberId, LocalDateTime startDateTime,
LocalDateTime endDateTime, String title, String place) {
List<Schedule> schedules = scheduleRepository.searchAllByConditions(
memberId,
startDateTime,
endDateTime,
title,
place
);

List<ScheduleInfoResponseDTO> response = new ArrayList<>();
for (Schedule schedule : schedules) {
response.add(ScheduleInfoResponseDTO.builder()
.id(schedule.getId())
.title(schedule.getTitle())
.startDateTime(schedule.getStartDateTime())
.endDateTime(schedule.getEndDateTime())
.place(schedule.getPlace())
.build());
}

return response;
}

}
6 changes: 5 additions & 1 deletion src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ spring:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
sql:
init:
mode: always
schema-locations: classpath:init.sql
h2:
console:
enabled: true
enabled: true
56 changes: 55 additions & 1 deletion src/main/resources/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,58 @@ VALUES (42, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Annual Company Retreat', '2
(45, 'd4e5f6g7-h8i9-0123-j4k5-l6m7n8o9p0q1', 'Year-End Financial Review', '2024-12-20 09:00:00',
'2024-12-31 17:00:00', 'Corporate Headquarters'),
(46, 'e5f6g7h8-i9j0-1234-k5l6-m7n8o9p0q1r2', 'New Year Strategic Planning', '2025-01-02 08:00:00',
'2025-01-15 18:00:00', 'Executive Retreat Center');
'2025-01-15 18:00:00', 'Executive Retreat Center');
VALUES
(1, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Team Meeting', '2024-09-10 10:13:47', '2024-09-10 11:22:14', 'Conference Room 1'),
(2, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Project Kickoff', '2024-09-07 13:27:32', '2024-09-07 14:35:59', 'Conference Room 2'),
(3, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Client Presentation', '2024-09-09 09:49:16', '2024-09-09 11:05:37', 'Main Office'),
(4, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Design Review', '2024-09-06 14:08:11', '2024-09-06 15:40:18', 'Design Lab'),
(5, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Sprint Planning', '2024-09-08 09:14:23', '2024-09-08 10:53:12', 'Meeting Room 3'),
(6, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Code Review', '2024-09-10 11:42:55', '2024-09-10 12:33:18', 'Meeting Room 1'),
(7, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Team Building', '2024-09-12 15:03:20', '2024-09-12 17:12:45', 'Outdoor Garden'),
(8, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Product Demo', '2024-09-06 13:37:51', '2024-09-06 14:48:30', 'Main Hall'),
(9, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Sales Review', '2024-09-12 16:43:09', '2024-09-12 17:28:22', 'Conference Room 2'),
(10, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Strategy Session', '2024-09-11 09:23:44', '2024-09-11 10:11:13', 'Executive Room'),
(11, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Marketing Discussion', '2024-09-10 15:36:05', '2024-09-10 16:47:33', 'Conference Room 3'),
(12, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Finance Review', '2024-09-06 14:19:14', '2024-09-06 15:52:51', 'Main Office'),
(13, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'HR Policy Update', '2024-09-07 09:07:39', '2024-09-07 10:29:04', 'HR Office'),
(14, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'IT Infrastructure Meeting', '2024-09-08 11:43:27', '2024-09-08 12:27:58', 'IT Room'),
(15, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Legal Compliance', '2024-09-09 10:50:31', '2024-09-09 11:39:42', 'Legal Department'),
(16, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Board Meeting', '2024-09-11 14:16:19', '2024-09-11 15:42:01', 'Board Room'),
(17, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Budget Planning', '2024-09-07 09:14:55', '2024-09-07 10:24:03', 'Finance Office'),
(18, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Audit Discussion', '2024-09-12 10:21:18', '2024-09-12 11:43:50', 'Audit Room'),
(19, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Research Meeting', '2024-09-08 14:44:31', '2024-09-08 15:33:18', 'Research Lab'),
(20, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Performance Review', '2024-09-10 15:17:39', '2024-09-10 16:27:45', 'HR Office'),
(21, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Training Session', '2024-09-11 10:04:12', '2024-09-11 12:16:44', 'Training Room'),
(22, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Press Conference', '2024-09-08 09:38:50', '2024-09-08 10:51:12', 'Media Room'),
(23, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Annual General Meeting', '2024-09-09 13:08:05', '2024-09-09 14:55:48', 'Main Hall'),
(24, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Investor Meeting', '2024-09-07 09:31:18', '2024-09-07 10:43:59', 'Investor Relations Room'),
(25, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'CEO Briefing', '2024-09-06 09:08:27', '2024-09-06 10:16:50', 'Executive Room'),
(26, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Company Anniversary', '2024-09-11 11:35:48', '2024-09-11 12:45:59', 'Main Hall'),
(27, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Vendor Meeting', '2024-09-12 14:28:34', '2024-09-12 15:32:01', 'Vendor Room'),
(28, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Product Launch', '2024-09-10 09:17:55', '2024-09-10 10:29:18', 'Main Hall'),
(29, 'b1c2d3e4-f5g6-7890-h1i2-j3k4l5m6n7o8', 'Team Outing', '2024-09-06 15:43:27', '2024-09-06 17:12:58', 'Outdoor Garden'),
(30, 'c1d2e3f4-g5h6-7890-i1j2-k3l4m5n6o7p8', 'Training Workshop', '2024-09-08 10:50:31', '2024-09-08 12:39:42', 'Training Room');

-- 시작 시간이 00:00:00인 경우 (3개)
INSERT INTO schedule (id, member_id, title, start_date_time, end_date_time, place)
VALUES
(31, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Early Morning Meeting', '2024-09-15 00:00:00', '2024-09-15 10:30:00', 'Conference Room A'),
(32, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Day-long Workshop', '2024-09-20 00:00:00', '2024-09-20 18:00:00', 'Training Center'),
(33, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Overnight Project Kickoff', '2024-09-25 00:00:00', '2024-09-26 08:00:00', 'Main Office');

-- 종료 시간이 23:59:59인 경우 (3개)
INSERT INTO schedule (id, member_id, title, start_date_time, end_date_time, place)
VALUES
(34, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Late Night Coding Session', '2024-09-18 20:00:00', '2024-09-18 23:59:59', 'Development Lab'),
(35, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'End-of-Month Review', '2024-09-30 14:00:00', '2024-09-30 23:59:59', 'Board Room'),
(36, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'International Conference Call', '2024-09-22 22:00:00', '2024-09-22 23:59:59', 'Virtual Meeting Room');

-- 9월 1일부터 30일 중 랜덤으로 5개의 일정 추가
INSERT INTO schedule (id, member_id, title, start_date_time, end_date_time, place)
VALUES
(37, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Quarterly Planning', '2024-09-03 09:30:00', '2024-09-03 12:30:00', 'Strategy Room'),
(38, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Client Lunch Meeting', '2024-09-17 12:00:00', '2024-09-17 14:00:00', 'Fancy Restaurant'),
(39, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Team Building Exercise', '2024-09-24 14:00:00', '2024-09-24 17:00:00', 'City Park'),
(40, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Product Development Review', '2024-09-11 10:00:00', '2024-09-11 11:30:00', 'Innovation Lab'),
(41, 'a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8', 'Annual Performance Evaluation', '2024-09-29 13:00:00', '2024-09-29 16:00:00', 'HR Office');

0 comments on commit d434f9f

Please sign in to comment.