Skip to content

Commit 8f0a304

Browse files
authored
Merge pull request #2813 from objectcomputing/bugfix-2807/partial-volunteer-hours
Support floating point hours for volunteering.
2 parents 08d313e + 0ea87c8 commit 8f0a304

File tree

5 files changed

+38
-34
lines changed

5 files changed

+38
-34
lines changed

server/src/main/java/com/objectcomputing/checkins/services/volunteering/VolunteeringEvent.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,16 @@ public class VolunteeringEvent {
5454

5555
@Column(name = "hours")
5656
@Schema(description = "number of hours spent volunteering")
57-
@TypeDef(type = DataType.INTEGER)
58-
private int hours;
57+
@TypeDef(type = DataType.DOUBLE)
58+
private double hours;
5959

6060
@Nullable
6161
@Column(name = "notes")
6262
@TypeDef(type = DataType.STRING)
6363
@Schema(description = "notes about the volunteering event")
6464
private String notes;
6565

66-
public VolunteeringEvent(UUID relationshipId, LocalDate eventDate, int hours, String notes) {
66+
public VolunteeringEvent(UUID relationshipId, LocalDate eventDate, double hours, String notes) {
6767
this(null, relationshipId, eventDate, hours, notes);
6868
}
6969

@@ -79,4 +79,4 @@ public boolean equals(Object o) {
7979
public int hashCode() {
8080
return Objects.hash(id, relationshipId, eventDate, hours, notes);
8181
}
82-
}
82+
}

server/src/main/java/com/objectcomputing/checkins/services/volunteering/VolunteeringEventDTO.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ public class VolunteeringEventDTO {
2929

3030
@NotNull
3131
@Schema(description = "number of hours spent volunteering")
32-
private Integer hours;
32+
private Double hours;
3333

3434
@Nullable
3535
@Schema(description = "notes about the volunteering event")
3636
private String notes;
37-
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE volunteering_event
2+
ALTER COLUMN hours TYPE float;

server/src/test/java/com/objectcomputing/checkins/services/fixture/VolunteeringFixture.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ default VolunteeringRelationship createVolunteeringRelationship(UUID memberId, U
4141
return getVolunteeringRelationshipRepository().save(new VolunteeringRelationship(memberId, organizationId, startDate, endDate, active));
4242
}
4343

44-
default VolunteeringEvent createVolunteeringEvent(UUID relationshipId, LocalDate now, int i, String notes) {
44+
default VolunteeringEvent createVolunteeringEvent(UUID relationshipId, LocalDate now, double i, String notes) {
4545
return getVolunteeringEventRepository().save(new VolunteeringEvent(relationshipId, now, i, notes));
4646
}
4747
}

server/src/test/java/com/objectcomputing/checkins/services/volunteering/VolunteeringEventControllerTest.java

+29-27
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
@Property(name = VolunteeringClients.Event.ENABLED, value = "true")
3232
class VolunteeringEventControllerTest extends TestContainersSuite implements MemberProfileFixture, RoleFixture, VolunteeringFixture {
33+
static final double fiveHours = 5.0;
34+
static final double tenHours = 10.0;
3335

3436
@Inject
3537
VolunteeringClients.Event eventClient;
@@ -63,7 +65,7 @@ void memberCanCreateEventForTheirRelationships() {
6365
LocalDate now = LocalDate.now();
6466
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
6567

66-
var event = new VolunteeringEventDTO(relationship.getId(), now, 10, "Notes");
68+
var event = new VolunteeringEventDTO(relationship.getId(), now, tenHours, "Notes");
6769
var createdEvent = eventClient.create(timAuth, event);
6870

6971
assertEquals(HttpStatus.CREATED, createdEvent.getStatus());
@@ -83,7 +85,7 @@ void memberCannotCreateEventForSomeoneElseRelationships() {
8385
LocalDate now = LocalDate.now();
8486
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
8587

86-
var event = new VolunteeringEventDTO(relationship.getId(), now, 10, "Notes");
88+
var event = new VolunteeringEventDTO(relationship.getId(), now, tenHours, "Notes");
8789

8890
MemberProfile bob = memberWithoutBoss("bob");
8991
String bobAuth = auth(bob.getWorkEmail(), MEMBER_ROLE);
@@ -104,7 +106,7 @@ void memberWithPermissionCanCreateEventForSomeoneElseRelationships() {
104106
MemberProfile bob = memberWithoutBoss("bob");
105107
String bobAuth = auth(bob.getWorkEmail(), ADMIN_ROLE);
106108

107-
var event = new VolunteeringEventDTO(relationship.getId(), now, 10, "Notes");
109+
var event = new VolunteeringEventDTO(relationship.getId(), now, tenHours, "Notes");
108110
var createdEvent = eventClient.create(bobAuth, event);
109111

110112
assertEquals(HttpStatus.CREATED, createdEvent.getStatus());
@@ -124,9 +126,9 @@ void memberCanUpdateTheirOwnEvents() {
124126

125127
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
126128
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
127-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
129+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
128130

129-
var updated = eventClient.update(timAuth, event.getId(), new VolunteeringEventDTO(relationship.getId(), now, 5, "New notes"));
131+
var updated = eventClient.update(timAuth, event.getId(), new VolunteeringEventDTO(relationship.getId(), now, fiveHours, "New notes"));
130132
assertEquals(event.getId(), updated.getId());
131133
assertEquals("New notes", updated.getNotes());
132134
}
@@ -138,12 +140,12 @@ void memberCannotUpdateOthersEvents() {
138140

139141
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
140142
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
141-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
143+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
142144

143145
MemberProfile bob = memberWithoutBoss("bob");
144146
String bobAuth = auth(bob.getWorkEmail(), MEMBER_ROLE);
145147

146-
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(relationship.getId(), now, 5, "New notes")));
148+
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(relationship.getId(), now, fiveHours, "New notes")));
147149
assertEquals(HttpStatus.BAD_REQUEST, e.getStatus());
148150
assertEquals("Member %s does not have permission to update Volunteering event for relationship %s".formatted(bob.getId(), relationship.getId()), e.getMessage());
149151
}
@@ -157,12 +159,12 @@ void memberCannotUpdateTheirEventToSomeoneElse() {
157159

158160
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
159161
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
160-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
162+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
161163

162164
MemberProfile bob = memberWithoutBoss("bob");
163165
VolunteeringRelationship bobRelationship = createVolunteeringRelationship(bob.getId(), organization.getId(), now);
164166

165-
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(timAuth, event.getId(), new VolunteeringEventDTO(bobRelationship.getId(), now, 5, "New notes")));
167+
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(timAuth, event.getId(), new VolunteeringEventDTO(bobRelationship.getId(), now, fiveHours, "New notes")));
166168
assertEquals(HttpStatus.BAD_REQUEST, e.getStatus());
167169
assertEquals("Member %s does not have permission to update Volunteering event for relationship %s".formatted(tim.getId(), bobRelationship.getId()), e.getMessage());
168170
}
@@ -175,13 +177,13 @@ void memberCannotUpdateSomeoneElseEventToTheirs() {
175177

176178
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
177179
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
178-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
180+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
179181

180182
MemberProfile bob = memberWithoutBoss("bob");
181183
String bobAuth = auth(bob.getWorkEmail(), MEMBER_ROLE);
182184
VolunteeringRelationship bobRelationship = createVolunteeringRelationship(bob.getId(), organization.getId(), now);
183185

184-
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(bobRelationship.getId(), now, 5, "New notes")));
186+
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(bobRelationship.getId(), now, fiveHours, "New notes")));
185187
assertEquals(HttpStatus.BAD_REQUEST, e.getStatus());
186188
assertEquals("Member %s does not have permission to update Volunteering event for relationship %s".formatted(bob.getId(), relationship.getId()), e.getMessage());
187189
}
@@ -192,13 +194,13 @@ void memberCannotHackUpdateOthersEventsWithTheirOwnRelationship() {
192194
MemberProfile tim = createADefaultMemberProfile();
193195
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
194196
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
195-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
197+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
196198

197199
MemberProfile bob = memberWithoutBoss("bob");
198200
String bobAuth = auth(bob.getWorkEmail(), MEMBER_ROLE);
199201
VolunteeringRelationship bobsRelationship = createVolunteeringRelationship(bob.getId(), organization.getId(), now);
200202

201-
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(bobsRelationship.getId(), now, 5, "New notes")));
203+
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(bobsRelationship.getId(), now, fiveHours, "New notes")));
202204
assertEquals(HttpStatus.BAD_REQUEST, e.getStatus());
203205
assertEquals("Member %s does not have permission to update Volunteering event for relationship %s".formatted(bob.getId(), relationship.getId()), e.getMessage());
204206
}
@@ -209,12 +211,12 @@ void memberCanUpdateOthersEventsWithProperPermission() {
209211
MemberProfile tim = createADefaultMemberProfile();
210212
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
211213
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
212-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
214+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
213215

214216
MemberProfile bob = memberWithoutBoss("bob");
215217
String bobAuth = auth(bob.getWorkEmail(), ADMIN_ROLE);
216218

217-
var updated = eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(relationship.getId(), now, 5, "New notes"));
219+
var updated = eventClient.update(bobAuth, event.getId(), new VolunteeringEventDTO(relationship.getId(), now, fiveHours, "New notes"));
218220
assertEquals(event.getId(), updated.getId());
219221
assertEquals("New notes", updated.getNotes());
220222
}
@@ -226,7 +228,7 @@ void memberCanDeleteTheirOwnEvents() {
226228
String timAuth = auth(tim.getWorkEmail(), MEMBER_ROLE);
227229
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
228230
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
229-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
231+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
230232

231233
var deletedEvent = eventClient.delete(timAuth, event.getId());
232234
assertEquals(HttpStatus.OK, deletedEvent.getStatus());
@@ -238,7 +240,7 @@ void memberCannotDeleteOthersEvents() {
238240
MemberProfile tim = createADefaultMemberProfile();
239241
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
240242
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
241-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
243+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
242244

243245
MemberProfile bob = memberWithoutBoss("bob");
244246
String bobAuth = auth(bob.getWorkEmail(), MEMBER_ROLE);
@@ -254,7 +256,7 @@ void memberWithPermissionCanDeleteOthersEvents() {
254256
MemberProfile tim = createADefaultMemberProfile();
255257
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
256258
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
257-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
259+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
258260

259261
MemberProfile bob = memberWithoutBoss("bob");
260262
String bobAuth = auth(bob.getWorkEmail(), ADMIN_ROLE);
@@ -304,13 +306,13 @@ void eventListCanBeFiltered() {
304306
var bobClosed = createVolunteeringRelationship(bob.getId(), closedOrg.getId(), now.minusDays(100), now.minusDays(50), false);
305307
var clairClosed = createVolunteeringRelationship(claire.getId(), closedOrg.getId(), now.minusDays(1), now);
306308

307-
var aliceLiftEvent1 = createVolunteeringEvent(aliceLiftForLife.getId(), now.minusDays(2), 10, "aliceLiftEvent1"); // 2 days ago
309+
var aliceLiftEvent1 = createVolunteeringEvent(aliceLiftForLife.getId(), now.minusDays(2), tenHours, "aliceLiftEvent1"); // 2 days ago
308310
var aliceLiftEvent2 = createVolunteeringEvent(aliceLiftForLife.getId(), now, 8, "aliceLiftEvent2"); // today
309311
var bobLiftEvent1 = createVolunteeringEvent(bobLiftForLife.getId(), now, 6, "bobLiftEvent1"); // today
310312
var clairLiftEvent1 = createVolunteeringEvent(claireLiftForLife.getId(), now.minusDays(3), 4, "clairLiftEvent1"); // 3 days ago
311313
var aliceFoodEvent1 = createVolunteeringEvent(aliceFood.getId(), now.minusDays(20), 2, "aliceFoodEvent1"); // 20 days ago
312314
var clairFoodEvent1 = createVolunteeringEvent(claireFood.getId(), now, 1, "clairFoodEvent1"); // today
313-
var bobClosedEvent1 = createVolunteeringEvent(bobClosed.getId(), now.minusDays(76), 10, "bobClosedEvent1"); // 76 days ago
315+
var bobClosedEvent1 = createVolunteeringEvent(bobClosed.getId(), now.minusDays(76), tenHours, "bobClosedEvent1"); // 76 days ago
314316
var clairClosedEvent1 = createVolunteeringEvent(clairClosed.getId(), now.minusDays(1), 0, "clairClosedEvent1"); // yesterday
315317

316318
// List all events, sorted by event date and then by organization name
@@ -353,10 +355,10 @@ void relationshipMustExist() {
353355
String timAuth = auth(tim.getWorkEmail(), MEMBER_ROLE);
354356
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
355357
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
356-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
358+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
357359
UUID randomId = UUID.randomUUID();
358360

359-
VolunteeringEventDTO newEvent = new VolunteeringEventDTO(randomId, now, 10, "Notes");
361+
VolunteeringEventDTO newEvent = new VolunteeringEventDTO(randomId, now, tenHours, "Notes");
360362

361363
// Creating an event with a non-existent relationship should fail
362364
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.create(timAuth, newEvent));
@@ -376,9 +378,9 @@ void eventDateMustBeSet() {
376378
String timAuth = auth(tim.getWorkEmail(), MEMBER_ROLE);
377379
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
378380
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
379-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
381+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
380382

381-
VolunteeringEventDTO newEvent = new VolunteeringEventDTO(relationship.getId(), null, 10, "Notes");
383+
VolunteeringEventDTO newEvent = new VolunteeringEventDTO(relationship.getId(), null, tenHours, "Notes");
382384

383385
// Creating an event with a null date should fail
384386
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.create(timAuth, newEvent));
@@ -400,9 +402,9 @@ void hoursMustBeNonNegative() {
400402
String timAuth = auth(tim.getWorkEmail(), MEMBER_ROLE);
401403
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
402404
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
403-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
405+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
404406

405-
VolunteeringEventDTO newEvent = new VolunteeringEventDTO(relationship.getId(), now, -1, "Notes");
407+
VolunteeringEventDTO newEvent = new VolunteeringEventDTO(relationship.getId(), now, -1.0, "Notes");
406408

407409
// Creating an event with negative hours should fail
408410
var e = assertThrows(HttpClientResponseException.class, () -> eventClient.create(timAuth, newEvent));
@@ -422,7 +424,7 @@ void hoursAreRequired() {
422424

423425
VolunteeringOrganization organization = createDefaultVolunteeringOrganization();
424426
VolunteeringRelationship relationship = createVolunteeringRelationship(tim.getId(), organization.getId(), now);
425-
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, 10, "Notes");
427+
VolunteeringEvent event = createVolunteeringEvent(relationship.getId(), now, tenHours, "Notes");
426428
String postBody = """
427429
{
428430
"relationshipId": "%s",

0 commit comments

Comments
 (0)