Skip to content

Commit

Permalink
feat: Implemented billable in TimeEntryTrackingService
Browse files Browse the repository at this point in the history
Key changes:
- Created `TimeBillingDTO` class.
- Modified `TimeEntry` domain.
- Modified unit tests.
  • Loading branch information
seyedali-dev committed May 14, 2024
1 parent 90854be commit e114226
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.seyed.ali.timeentryservice.controller;

import com.seyed.ali.timeentryservice.model.dto.TimeBillingDTO;
import com.seyed.ali.timeentryservice.model.dto.response.Result;
import com.seyed.ali.timeentryservice.service.interfaces.TimeEntryTrackingService;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;

import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.OK;

Expand All @@ -19,12 +22,14 @@ public class TimeEntryTrackingController {

@PostMapping("/start")
@ResponseStatus(CREATED)
public Result startTrackingTimeEntry() {
public Result startTrackingTimeEntry(@RequestBody TimeBillingDTO timeBillingDTO) {
boolean billable = timeBillingDTO.isBillable();
BigDecimal hourlyRate = timeBillingDTO.getHourlyRate();
return new Result(
true,
CREATED,
"Time tracking started...",
this.timeEntryService.startTrackingTimeEntry()
this.timeEntryService.startTrackingTimeEntry(billable, hourlyRate)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import jakarta.persistence.OneToMany;
import lombok.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -20,6 +21,8 @@ public class TimeEntry {

@Id
private String timeEntryId;
private boolean billable = false;
private BigDecimal hourlyRate = BigDecimal.TEN;

@OneToMany(mappedBy = "timeEntry", cascade = CascadeType.ALL)
@ToString.Exclude
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.seyed.ali.timeentryservice.model.domain;

import jakarta.persistence.*;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.*;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.seyed.ali.timeentryservice.model.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TimeBillingDTO {

private boolean billable;
private BigDecimal hourlyRate;

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.UUID;
Expand All @@ -36,7 +37,7 @@ public TimeEntryTrackingServiceImpl(TimeSegmentRepository timeSegmentRepository,

// TODO: Implement REDIS for caching the `start_time`
@Override
public String startTrackingTimeEntry() {
public String startTrackingTimeEntry(boolean billable, BigDecimal hourlyRate) {
TimeEntry timeEntry = new TimeEntry();
timeEntry.setTimeEntryId(UUID.randomUUID().toString());
TimeSegment timeSegment = TimeSegment.builder()
Expand All @@ -47,6 +48,12 @@ public String startTrackingTimeEntry() {
.timeEntry(timeEntry)
.build();

if (billable) {
timeEntry.setBillable(true);
if (hourlyRate != null)
timeEntry.setHourlyRate(hourlyRate);
}

timeEntry.getTimeSegmentList().add(timeSegment);
timeEntry.setUserId(this.authenticationServiceClient.getCurrentLoggedInUsersId());
this.timeEntryRepository.save(timeEntry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import com.seyed.ali.timeentryservice.model.dto.TimeEntryDTO;

import java.math.BigDecimal;

public interface TimeEntryTrackingService {

// TODO: Implement REDIS for caching the `start_time`
String startTrackingTimeEntry();
String startTrackingTimeEntry(boolean billable, BigDecimal hourlyRate);

// TODO: Implement REDIS for getting the cached `start_time`
TimeEntryDTO stopTrackingTimeEntry(String timeEntryId);

TimeEntryDTO continueTrackingTimeEntry(String timeEntryId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.seyed.ali.timeentryservice.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.seyed.ali.timeentryservice.config.EurekaClientTestConfiguration;
import com.seyed.ali.timeentryservice.keycloak.util.KeycloakSecurityUtil;
import com.seyed.ali.timeentryservice.model.dto.TimeBillingDTO;
import com.seyed.ali.timeentryservice.model.dto.TimeEntryDTO;
import com.seyed.ali.timeentryservice.service.TimeEntryTrackingServiceImpl;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -17,10 +19,12 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.when;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt;
Expand All @@ -42,6 +46,7 @@ class TimeEntryTrackingControllerTest {
private @MockBean KeycloakSecurityUtil keycloakSecurityUtil;

private @Autowired MockMvc mockMvc;
private @Autowired ObjectMapper objectMapper;

private final String baseUrl = "/api/v1/time";
private final List<TimeEntryDTO> timeEntries = new ArrayList<>();
Expand All @@ -57,14 +62,16 @@ void setUp() {
public void startTrackingTimeEntryTest() throws Exception {
// given
String timeEntryId = "some_time_entry_id";
when(this.timeEntryTrackingService.startTrackingTimeEntry())
when(this.timeEntryTrackingService.startTrackingTimeEntry(isA(Boolean.class), isA(BigDecimal.class)))
.thenReturn(timeEntryId);
String json = this.objectMapper.writeValueAsString(new TimeBillingDTO(true, BigDecimal.ONE));

// when
ResultActions response = this.mockMvc.perform(
post(this.baseUrl + "/track/start")
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(json)
.with(jwt().authorities(new SimpleGrantedAuthority("some_authority")))
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
Expand Down Expand Up @@ -83,7 +84,7 @@ public void startTrackingTimeEntryTest() {
when(this.timeEntryRepository.save(isA(TimeEntry.class))).thenReturn(timeEntry);

// Act
String timeEntryId = this.timeEntryTrackingService.startTrackingTimeEntry();
String timeEntryId = this.timeEntryTrackingService.startTrackingTimeEntry(false, BigDecimal.ONE);
System.out.println(timeEntryId);

// Assert
Expand Down

0 comments on commit e114226

Please sign in to comment.