Skip to content

Commit 40bf1fc

Browse files
authored
Merge pull request #114 from volodymyrlp/feature/Trip-new-fields
feat: add destination and dates to trip creation, auto-generate trip …
2 parents 3624b81 + 672e7f5 commit 40bf1fc

8 files changed

Lines changed: 278 additions & 25 deletions

File tree

backend/src/main/java/travelplanner/dto/trip/TripCreateRequest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44
import jakarta.validation.constraints.PositiveOrZero;
55
import jakarta.validation.constraints.Size;
66
import java.math.BigDecimal;
7+
import java.time.LocalDate;
78

89
public record TripCreateRequest(
910
@NotBlank(message = "Title cannot be blank")
1011
@Size(max = 255, message = "Title must not exceed 255 characters")
1112
String title,
1213

14+
@Size(max = 255, message = "Destination must not exceed 255 characters")
15+
String destination,
16+
17+
LocalDate startDate,
18+
19+
LocalDate endDate,
20+
1321
String description,
1422

1523
@PositiveOrZero(message = "Budget must be zero or positive")

backend/src/main/java/travelplanner/dto/trip/TripResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package travelplanner.dto.trip;
22

33
import java.math.BigDecimal;
4+
import java.time.LocalDate;
45
import java.time.LocalDateTime;
56
import java.util.UUID;
67

78
public record TripResponse(
89
UUID tripId,
910
String title,
11+
String destination,
12+
LocalDate startDate,
13+
LocalDate endDate,
1014
String description,
1115
BigDecimal budget,
1216
String currency,

backend/src/main/java/travelplanner/entity/Trip.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import jakarta.persistence.OneToMany;
1515
import jakarta.persistence.Table;
1616
import java.math.BigDecimal;
17+
import java.time.LocalDate;
1718
import java.time.LocalDateTime;
1819
import java.util.ArrayList;
1920
import java.util.HashSet;
@@ -42,6 +43,15 @@ public class Trip {
4243
@Column(name = "title", nullable = false)
4344
private String title;
4445

46+
@Column(name = "destination")
47+
private String destination;
48+
49+
@Column(name = "start_date")
50+
private LocalDate startDate;
51+
52+
@Column(name = "end_date")
53+
private LocalDate endDate;
54+
4555
@Column(name = "description", columnDefinition = "TEXT")
4656
private String description;
4757

backend/src/main/java/travelplanner/service/TripService.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package travelplanner.service;
22

3+
import java.time.temporal.ChronoUnit;
34
import java.util.List;
45
import java.util.UUID;
56
import lombok.RequiredArgsConstructor;
@@ -40,6 +41,18 @@ public TripResponse createTrip(TripCreateRequest request, User currentUser) {
4041
trip.setIsPublic(false);
4142
}
4243

44+
if (trip.getStartDate() != null && trip.getEndDate() != null
45+
&& !trip.getStartDate().isAfter(trip.getEndDate())) {
46+
long days = ChronoUnit.DAYS.between(trip.getStartDate(), trip.getEndDate());
47+
for (int i = 0; i <= days; i++) {
48+
TripDay tripDay = new TripDay();
49+
tripDay.setTrip(trip);
50+
tripDay.setDayNumber(i + 1);
51+
tripDay.setDate(trip.getStartDate().plusDays(i));
52+
trip.getTripDays().add(tripDay);
53+
}
54+
}
55+
4356
Trip savedTrip = tripRepository.save(trip);
4457
return tripMapper.toResponse(savedTrip);
4558
}
@@ -135,6 +148,9 @@ public TripResponse cloneTrip(UUID originalTripId, User currentUser) {
135148

136149
Trip clonedTrip = new Trip();
137150
clonedTrip.setTitle(originalTrip.getTitle() + " (Copy)");
151+
clonedTrip.setDestination(originalTrip.getDestination());
152+
clonedTrip.setStartDate(originalTrip.getStartDate());
153+
clonedTrip.setEndDate(originalTrip.getEndDate());
138154
clonedTrip.setDescription(originalTrip.getDescription());
139155
clonedTrip.setBudget(originalTrip.getBudget());
140156
clonedTrip.setCurrency(originalTrip.getCurrency());
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
--liquibase formatted sql
2+
--changeset ihor:add-trip-fields
3+
ALTER TABLE trips ADD COLUMN destination VARCHAR(255);
4+
ALTER TABLE trips ADD COLUMN start_date DATE;
5+
ALTER TABLE trips ADD COLUMN end_date DATE;
Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
1-
databaseChangeLog:
2-
- include:
3-
file: db/changelog/changes/01-create-users.sql
4-
- include:
5-
file: db/changelog/changes/02-create-trips.sql
6-
- include:
7-
file: db/changelog/changes/03-create-places.sql
8-
- include:
9-
file: db/changelog/changes/04-create-trip-places.sql
10-
- include:
11-
file: db/changelog/changes/05-insert-dummy-user.sql
12-
- include:
13-
file: db/changelog/changes/06-update-places-table.sql
14-
- include:
15-
file: db/changelog/changes/07-fix-places-relation.sql
16-
- include:
17-
file: db/changelog/changes/08-create-reviews.sql
18-
- include:
19-
file: db/changelog/changes/09-create-countries.sql
20-
- include:
21-
file: db/changelog/changes/10-create-trip-management-schema.sql
22-
- include:
23-
file: db/changelog/changes/11-add-tags-and-participants.sql
24-
- include:
25-
file: db/changelog/changes/12-add-photos-table.sql
1+
databaseChangeLog:
2+
- include:
3+
file: db/changelog/changes/01-create-users.sql
4+
- include:
5+
file: db/changelog/changes/02-create-trips.sql
6+
- include:
7+
file: db/changelog/changes/03-create-places.sql
8+
- include:
9+
file: db/changelog/changes/04-create-trip-places.sql
10+
- include:
11+
file: db/changelog/changes/05-insert-dummy-user.sql
12+
- include:
13+
file: db/changelog/changes/06-update-places-table.sql
14+
- include:
15+
file: db/changelog/changes/07-fix-places-relation.sql
16+
- include:
17+
file: db/changelog/changes/08-create-reviews.sql
18+
- include:
19+
file: db/changelog/changes/09-create-countries.sql
20+
- include:
21+
file: db/changelog/changes/10-create-trip-management-schema.sql
22+
- include:
23+
file: db/changelog/changes/11-add-tags-and-participants.sql
24+
- include:
25+
file: db/changelog/changes/12-add-photos-table.sql
26+
- include:
27+
file: db/changelog/changes/13-add-trip-fields.sql
28+

backend/src/test/java/travelplanner/controller/TripControllerIntegrationTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
1313

1414
import java.math.BigDecimal;
15+
import java.time.LocalDate;
1516
import java.time.LocalDateTime;
1617
import java.util.List;
1718
import java.util.UUID;
@@ -55,6 +56,9 @@ void uploadCover_Success() throws Exception {
5556
TripResponse response = new TripResponse(
5657
tripId,
5758
"My Trip",
59+
"Paris",
60+
LocalDate.now(),
61+
LocalDate.now().plusDays(5),
5862
"Description",
5963
BigDecimal.valueOf(1000),
6064
"USD",
@@ -138,6 +142,9 @@ void cloneTrip_Success() throws Exception {
138142
TripResponse response = new TripResponse(
139143
UUID.randomUUID(),
140144
"My Trip (Copy)",
145+
"Paris",
146+
LocalDate.now(),
147+
LocalDate.now().plusDays(5),
141148
"Description",
142149
BigDecimal.valueOf(1000),
143150
"USD",
@@ -153,6 +160,52 @@ void cloneTrip_Success() throws Exception {
153160
.with(csrf()))
154161
.andExpect(status().isCreated())
155162
.andExpect(jsonPath("$.title").value("My Trip (Copy)"))
163+
.andExpect(jsonPath("$.destination").value("Paris"))
156164
.andExpect(jsonPath("$.isPublic").value(false));
157165
}
166+
167+
@Test
168+
void createTrip_Success() throws Exception {
169+
User currentUser = new User();
170+
currentUser.setUserId(UUID.randomUUID());
171+
currentUser.setEmail("test@example.com");
172+
173+
TripResponse response = new TripResponse(
174+
UUID.randomUUID(),
175+
"Rome Adventure",
176+
"Rome",
177+
LocalDate.of(2026, 10, 1),
178+
LocalDate.of(2026, 10, 5),
179+
"Trip to Rome",
180+
BigDecimal.valueOf(1200),
181+
"EUR",
182+
null,
183+
false,
184+
LocalDateTime.now()
185+
);
186+
187+
when(tripService.createTrip(any(), any())).thenReturn(response);
188+
189+
mockMvc.perform(post("/api/v1/trips")
190+
.contentType(MediaType.APPLICATION_JSON)
191+
.content("""
192+
{
193+
"title": "Rome Adventure",
194+
"destination": "Rome",
195+
"startDate": "2026-10-01",
196+
"endDate": "2026-10-05",
197+
"description": "Trip to Rome",
198+
"budget": 1200,
199+
"currency": "EUR",
200+
"isPublic": false
201+
}
202+
""")
203+
.with(user(currentUser))
204+
.with(csrf()))
205+
.andExpect(status().isCreated())
206+
.andExpect(jsonPath("$.title").value("Rome Adventure"))
207+
.andExpect(jsonPath("$.destination").value("Rome"))
208+
.andExpect(jsonPath("$.startDate").value("2026-10-01"))
209+
.andExpect(jsonPath("$.endDate").value("2026-10-05"));
210+
}
158211
}

0 commit comments

Comments
 (0)