Skip to content

Commit

Permalink
refactor: implement create new employee endpoint (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
mohsenk authored Aug 18, 2024
1 parent d945d9e commit abb392e
Show file tree
Hide file tree
Showing 16 changed files with 191 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,44 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

@Data
@NoArgsConstructor
public class RegistrationRequest {
@Nonnull
@NotBlank(message = "organization.first_name.blank")
@Size(min = 1, max = 255, message = "organization.first_name.size")
private String firstName;

@Nonnull
@NotBlank(message = "organization.last_name.blank")
@Size(min = 1, max = 255, message = "organization.last_name.size")
private String lastName;

@Nonnull
@NotBlank(message = "organization.name.blank")
@Size(min = 3, max = 100, message = "organization.name.size")
private String organizationName;

@Nonnull
@PhoneNumber
private String phone;

@Nonnull
@NotBlank(message = "organization.country.blank")
@Size(min = 2, max = 2, message = "organization.country.size")
private String countryCode;

@Nullable
@TimeZone(message = "site.timezone.invalid")
private String timezone;

@Nonnull
@NotBlank(message = "organization.email.blank")
@Email(message = "organization.email.email_format")
@Size(min = 5, max = 255, message = "organization.email.size")
private String email;

@Nonnull
@NotBlank(message = "organization.password.blank")
@Size(min = 6, max = 32, message = "organization.password.size")
private String password;
}

public record RegistrationRequest(
@Nonnull
@NotBlank(message = "organization.first_name.blank")
@Size(min = 1, max = 255, message = "organization.first_name.size")
String firstName,

@Nonnull
@NotBlank(message = "organization.last_name.blank")
@Size(min = 1, max = 255, message = "organization.last_name.size")
String lastName,

@Nonnull
@NotBlank(message = "organization.name.blank")
@Size(min = 3, max = 100, message = "organization.name.size")
String organizationName,

@Nonnull
@PhoneNumber
String phone,

@Nonnull
@NotBlank(message = "organization.country.blank")
@Size(min = 2, max = 2, message = "organization.country.size")
String countryCode,

@Nullable
@TimeZone(message = "site.timezone.invalid")
String timezone,

@Nonnull
@NotBlank(message = "organization.email.blank")
@Email(message = "organization.email.email_format")
@Size(min = 5, max = 255, message = "organization.email.size")
String email,

@Nonnull
@NotBlank(message = "organization.password.blank")
@Size(min = 6, max = 32, message = "organization.password.size")
String password
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,18 @@ public class AuthenticationService implements UserDetailsService {

@Transactional(rollbackFor = BaseException.class)
public AuthenticationResponse register(RegistrationRequest request) throws UserAlreadyExistsException, OrganizationNotFoundException, TeamNotFoundException {
var organization = organizationService.registerOrganization(new OrganizationCreateRequest(request.getOrganizationName(),request.getCountryCode(), request.getTimezone()));
var organization = organizationService.registerOrganization(new OrganizationCreateRequest(request.organizationName(),request.countryCode(), request.timezone()));
var team = teamService.createTeam(organization.getId(), new TeamCreateRequest("Default", null));
var registerRequest = new AdminUserCreateRequest(request.getEmail(), request.getPassword(),
request.getFirstName(), request.getLastName(), request.getPhone());
var registerRequest = new AdminUserCreateRequest(
request.email(),
request.password(),
request.firstName(),
request.lastName(),
request.phone(),
request.timezone()
);
var user = userService.createOrganizationAdmin(organization.getId(), team.getId(),registerRequest);
eventPublisher.publishEvent(new OrganizationCreatedEvent(organization, user));
eventPublisher.publishEvent(new OrganizationCreatedEvent(organization, userMapper.toUserResponse(user)));

var accessToken = tokenService.generateAccessToken(
user.getId().toString(),
Expand All @@ -58,7 +64,7 @@ public AuthenticationResponse register(RegistrationRequest request) throws UserA
LocalDateTime.now().plusDays(1)
);
var refreshToken = tokenService.generateRefreshToken(user.getId().toString(), LocalDateTime.now().plusDays(7));
return new AuthenticationResponse(accessToken, refreshToken, user);
return new AuthenticationResponse(accessToken, refreshToken, userMapper.toUserResponse(user));
}

public AuthenticationResponse login(LoginRequest request) throws InvalidCredentialException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public List<FetchedPublicHoliday> fetchPublicHolidays(Long organizationId, Integ
}
var organization = organizationService.getOrganization(organizationId);
try {
return publicHolidayProvider.getPublicHolidays(organization.getCountry(), year);
return publicHolidayProvider.getPublicHolidays(organization.getCountryCode(), year);
} catch (Exception ex) {
throw new PublicHolidayProviderConnectionBrokenException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class Organization extends BaseAuditEntity {
private Long id;
private String name;

private String country;
private String countryCode;

private String timezone;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public Organization updateOrganization(long organizationId, OrganizationUpdateRe
.setWeekFirstDay(request.weekFirstDay())
.setWorkingDays(request.workingDays().toArray(DayOfWeek[]::new))
.setMetadata(request.metadata())
.setCountry(request.country());
.setCountryCode(request.country());
return organizationRepository.update(organization);
}

Expand All @@ -50,7 +50,7 @@ private Organization getById(Long organizationId) throws OrganizationNotFoundExc
private Organization buildOrganization(OrganizationCreateRequest request) {
return new Organization()
.setName(request.name())
.setCountry(request.country())
.setCountryCode(request.country())
.setTimezone(request.timezone())
.setWeekFirstDay(DayOfWeek.MONDAY)
.setWorkingDays(new DayOfWeek[]{DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, DayOfWeek.FRIDAY});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import app.teamwize.api.base.exception.BaseException;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@RequiredArgsConstructor
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Team Not Found")
public class TeamNotFoundException extends BaseException {
private final long organizationId;
private final long teamId;
Expand Down
19 changes: 11 additions & 8 deletions src/main/java/app/teamwize/api/user/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@
import app.teamwize.api.auth.service.SecurityService;
import app.teamwize.api.base.domain.model.request.PaginationRequest;
import app.teamwize.api.base.domain.model.response.PagedResponse;
import app.teamwize.api.user.domain.request.ChangePasswordRequest;
import app.teamwize.api.user.domain.request.UserChangeStatusRequest;
import app.teamwize.api.user.domain.request.UserUpdateRequest;
import app.teamwize.api.user.exception.IncorrectPasswordException;
import app.teamwize.api.user.exception.UnableToDisableCurrentUserException;
import app.teamwize.api.user.exception.UserAlreadyExistsException;
import app.teamwize.api.user.exception.UserNotFoundException;
import app.teamwize.api.organization.exception.OrganizationNotFoundException;
import app.teamwize.api.team.domain.exception.TeamNotFoundException;
import app.teamwize.api.user.domain.request.*;
import app.teamwize.api.user.exception.*;
import app.teamwize.api.user.mapper.UserMapper;
import app.teamwize.api.user.service.UserService;
import app.teamwize.api.base.mapper.PagedResponseMapper;
import app.teamwize.api.user.domain.request.UserFilterRequest;
import app.teamwize.api.user.domain.response.UserResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;


Expand All @@ -46,6 +43,12 @@ public PagedResponse<UserResponse> getUsers(@ParameterObject @Valid UserFilterRe
);
}

@PostMapping
public UserResponse createUser(@RequestBody UserCreateRequest request) throws UserAlreadyExistsException, OrganizationNotFoundException, TeamNotFoundException, UserNotFoundException, PermissionDeniedException {
var user = userService.createUser(securityService.getUserOrganizationId(), securityService.getUserId(), request);
return userMapper.toUserResponse(user);
}

@GetMapping("mine")
public UserResponse getMyProfile() throws UserNotFoundException {
return userMapper.toUserResponse(userService.getUser(securityService.getUserOrganizationId(), securityService.getUserId()));
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/app/teamwize/api/user/domain/UserRole.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
@Getter
@RequiredArgsConstructor
public enum UserRole {
ADMIN("admin"),
ORGANIZATION_ADMIN("organization_admin"),
EMPLOYEE("employee"),
TEAM_ADMIN("team_admin"),
API("api");

private final String name;
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/app/teamwize/api/user/domain/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,19 @@ public class User extends BaseAuditEntity {
@GeneratedValue(generator = "user_id_seq_generator")
@SequenceGenerator(name = "user_id_seq_generator", sequenceName = "user_id_seq", allocationSize = 1)
private Long id;

@Enumerated(EnumType.STRING)
private UserRole role;
private String email;
private String password;
private String phone;
private String firstName;
private String lastName;

private String countryCode;
private String timezone;
@ManyToOne(fetch = FetchType.LAZY)
private Organization organization;

@ManyToOne(fetch = FetchType.LAZY)
private Team team;


@Enumerated(EnumType.STRING)
private UserStatus status;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminUserCreateRequest {
private String email;
private String password;
private String firstName;
private String lastName;
private String phone;
}
public record AdminUserCreateRequest(
String email,
String password,
String firstName,
String lastName,
String phone,
String timezone
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserCreateRequest {
private String email;
private String firstName;
private String lastName;
private String password;
private String phone;
private UserRole role;
}
public record UserCreateRequest(
String email,
String firstName,
String lastName,
String password,
String phone,
UserRole role,
String timezone,
String countryCode,
Long teamId
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,18 @@
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;

@Data
@NoArgsConstructor
public class UserResponse {
@Nonnull
private Long id;
@Nonnull
private UserStatus status;
@Nonnull
private UserRole role;
@Nonnull
private String email;
@Nonnull
private String firstName;
@Nullable
private String lastName;
@Nullable
private String phone;
@Nonnull
private OrganizationCompactResponse organization;
@Nonnull
private TeamCompactResponse team;
}

public record UserResponse(
@Nonnull Long id,
@Nonnull UserStatus status,
@Nonnull UserRole role,
@Nonnull String email,
@Nonnull String firstName,
@Nullable String lastName,
@Nullable String phone,
@Nullable String timezone,
@Nullable String countryCode,
@Nonnull OrganizationCompactResponse organization,
@Nonnull TeamCompactResponse team
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package app.teamwize.api.user.exception;

import app.teamwize.api.base.exception.BaseException;
import lombok.NoArgsConstructor;

public class PermissionDeniedException extends BaseException {
private final long organizationId;
public PermissionDeniedException(long organizationId) {
this.organizationId = organizationId;
}

}
Loading

0 comments on commit abb392e

Please sign in to comment.