Skip to content

Commit

Permalink
#146 | Implement the process of Assignment for Save Operation (#147)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rapter1990 authored Aug 22, 2023
1 parent 3c15af3 commit 02035a6
Show file tree
Hide file tree
Showing 22 changed files with 704 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.ays.assignment.controller;

import com.ays.assignment.model.dto.request.AssignmentSaveRequest;
import com.ays.assignment.service.AssignmentSaveService;
import com.ays.common.model.dto.response.AysResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* REST controller class for managing assignment-related operations via HTTP requests.
* This controller handles the CRUD operations for assignments in the system.
* The mapping path for this controller is "/api/v1/assignment".
*/
@RestController
@RequestMapping("/api/v1")
@RequiredArgsConstructor
@Validated
class AssignmentController {

private final AssignmentSaveService assignmentSaveService;


/**
* Saves a new assignment to the system.
* Requires ADMIN authority.
*
* @param saveRequest The request object containing the assignment data to be saved.
* @return A response object containing the saved assignment data.
*/
@PostMapping("/assignment")
@PreAuthorize("hasAnyAuthority('ADMIN')")
public AysResponse<Void> saveAssignment(@RequestBody @Valid AssignmentSaveRequest saveRequest) {
assignmentSaveService.saveAssignment(saveRequest);
return AysResponse.SUCCESS;
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/ays/assignment/model/Assignment.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.SuperBuilder;
import org.locationtech.jts.geom.Point;

/**
* Assignment Domain Model to perform data transfer from service layer to controller
Expand All @@ -22,8 +23,7 @@ public class Assignment extends BaseDomainModel {
private String firstName;
private String lastName;
private AysPhoneNumber phoneNumber;
private Double latitude;
private Double longitude;
private Point point;
private AssignmentStatus status;

private User user;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.ays.assignment.model.dto.request;

import com.ays.common.model.AysPhoneNumber;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

/**
* A DTO class representing the request data for saving an assignment.
* <p>
* This class provides getters and setters for the description, first name, last name, latitude, longitude and phone number fields.
* It also includes a builder pattern implementation for constructing instances of this class with optional parameters.
* <p>
* The purpose of this class is to encapsulate the request data related to saving an assignment, allowing for easy
* transfer of the data between different layers of the application.
*/
@Getter
@Setter
@Builder
public class AssignmentSaveRequest {

@NotBlank
private String description;

@NotBlank
private String firstName;

@NotBlank
private String lastName;

@Valid
@NotNull
private AysPhoneNumber phoneNumber;

@NotNull
private Double latitude;

@NotNull
private Double longitude;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.ays.assignment.model.enums.AssignmentStatus;
import com.ays.common.model.entity.BaseEntity;
import com.ays.common.util.AysLocationUtil;
import com.ays.institution.model.entity.InstitutionEntity;
import com.ays.user.model.entity.UserEntity;
import jakarta.persistence.*;
Expand All @@ -10,8 +11,6 @@
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;

/**
Expand Down Expand Up @@ -55,7 +54,7 @@ public class AssignmentEntity extends BaseEntity {
private Point point;

@Enumerated(EnumType.STRING)
@Column(name = "ASSIGNMENT_STATUS")
@Column(name = "STATUS")
private AssignmentStatus status;

@OneToOne
Expand All @@ -67,9 +66,7 @@ public class AssignmentEntity extends BaseEntity {
private UserEntity user;

public void setPoint(double latitude, double longitude) {
Coordinate coordinate = new Coordinate(latitude, longitude);
GeometryFactory geometryFactory = new GeometryFactory();
this.point = geometryFactory.createPoint(coordinate);
this.point = AysLocationUtil.generatePoint(latitude, longitude);
}

public boolean isAvailable() {
Expand All @@ -92,8 +89,15 @@ public boolean isDone() {
return AssignmentStatus.DONE.equals(this.status);
}


public void updateAssignmentStatus(AssignmentStatus assignmentStatus) {
this.status = assignmentStatus;
}

public abstract static class AssignmentEntityBuilder<C extends AssignmentEntity, B extends AssignmentEntityBuilder<C, B>> extends BaseEntity.BaseEntityBuilder<C, B> {
public B point(final Double latitude, final Double longitude) {
this.point = AysLocationUtil.generatePoint(latitude, longitude);
return this.self();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
import com.ays.assignment.model.Assignment;
import com.ays.assignment.model.entity.AssignmentEntity;
import com.ays.common.model.mapper.BaseMapper;
import org.locationtech.jts.geom.Point;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.util.Optional;

/**
* AssignmentEntityToAssignmentMapper is an interface that defines the mapping between an {@link AssignmentEntity} and an {@link Assignment}.
* This interface uses the MapStruct annotation @Mapper to generate an implementation of this interface at compile-time.
Expand All @@ -23,8 +20,6 @@ public interface AssignmentEntityToAssignmentMapper extends BaseMapper<Assignmen
@Override
@Mapping(target = "phoneNumber.countryCode", source = "source.countryCode")
@Mapping(target = "phoneNumber.lineNumber", source = "source.lineNumber")
@Mapping(target = "latitude", expression = "java(mapToLatitude(source.getPoint()))")
@Mapping(target = "longitude", expression = "java(mapToLongitude(source.getPoint()))")
Assignment map(AssignmentEntity source);

/**
Expand All @@ -36,28 +31,4 @@ static AssignmentEntityToAssignmentMapper initialize() {
return Mappers.getMapper(AssignmentEntityToAssignmentMapper.class);
}

/**
* Maps a Point object to latitude.
*
* @param point The Point object.
* @return The latitude coordinate.
*/
default Double mapToLatitude(Point point) {
return Optional.ofNullable(point)
.map(Point::getY)
.orElse(null);
}

/**
* Maps a Point object to longitude.
*
* @param point The Point object.
* @return The longitude coordinate.
*/
default Double mapToLongitude(Point point) {
return Optional.ofNullable(point)
.map(Point::getX)
.orElse(null);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.ays.assignment.model.mapper;

import com.ays.assignment.model.Assignment;
import com.ays.assignment.model.dto.request.AssignmentSaveRequest;
import com.ays.assignment.model.entity.AssignmentEntity;
import com.ays.assignment.model.enums.AssignmentStatus;
import com.ays.common.model.mapper.BaseMapper;
import com.ays.common.util.AysRandomUtil;
import com.ays.user.model.entity.UserEntity;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

/**
* UserToUserResponseMapper is an interface that defines the mapping between an {@link AssignmentSaveRequest} and an {@link Assignment}.
* This interface uses the MapStruct annotation @Mapper to generate an implementation of this interface at compile-time.
* <p>The class provides a static method {@code initialize()} that returns an instance of the generated mapper implementation.
* <p>The interface extends the MapStruct interface {@link BaseMapper}, which defines basic mapping methods.
* The interface adds no additional mapping methods, but simply defines the types to be used in the mapping process.
*/
@Mapper
public interface AssignmentSaveRequestToAssignmentMapper extends BaseMapper<AssignmentSaveRequest, Assignment> {

/**
* Maps an {@link AssignmentSaveRequest} object to an {@link AssignmentEntity} object for saving in the database.
*
* @param saveRequest the {@link AssignmentSaveRequest} object to be mapped.
* @param institutionId the {@link String} object.
* @return the mapped {@link UserEntity} object.
*/
default AssignmentEntity mapForSaving(AssignmentSaveRequest saveRequest, String institutionId) {

return AssignmentEntity.builder()
.id(AysRandomUtil.generateUUID())
.institutionId(institutionId)
.description(saveRequest.getDescription())
.firstName(saveRequest.getFirstName())
.lastName(saveRequest.getLastName())
.lineNumber(saveRequest.getPhoneNumber().getLineNumber())
.countryCode(saveRequest.getPhoneNumber().getCountryCode())
.point(saveRequest.getLatitude(), saveRequest.getLongitude())
.status(AssignmentStatus.AVAILABLE)
.build();
}

/**
* Initializes the mapper.
*
* @return the initialized mapper object.
*/
static AssignmentSaveRequestToAssignmentMapper initialize() {
return Mappers.getMapper(AssignmentSaveRequestToAssignmentMapper.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
import com.ays.assignment.model.Assignment;
import com.ays.assignment.model.entity.AssignmentEntity;
import com.ays.common.model.mapper.BaseMapper;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

/**
Expand All @@ -20,15 +16,6 @@
@Mapper
public interface AssignmentToAssignmentEntityMapper extends BaseMapper<Assignment, AssignmentEntity> {

/**
* Maps UserAssignment to UserAssignmentEntity.
*
* @param assignment the UserAssignment object
* @return the mapped UserAssignmentEntity object
*/
@Mapping(target = "point", expression = "java(mapToPoint(assignment.getLatitude(), assignment.getLongitude()))")
AssignmentEntity map(Assignment assignment);


/**
* Initializes the mapper.
Expand All @@ -39,19 +26,4 @@ static AssignmentToAssignmentEntityMapper initialize() {
return Mappers.getMapper(AssignmentToAssignmentEntityMapper.class);
}

/**
* Maps latitude and longitude to the point field.
*
* @param latitude the latitude value
* @param longitude the longitude value
* @return the mapped Point object
*/
default Point mapToPoint(Double latitude, Double longitude) {
if (latitude != null && longitude != null) {
Coordinate coordinate = new Coordinate(latitude, longitude);
GeometryFactory geometryFactory = new GeometryFactory();
return geometryFactory.createPoint(coordinate);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import com.ays.assignment.model.entity.AssignmentEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/**
* Repository interface for performing CRUD operations on UserAssignmentEntity objects.
*/
public interface AssignmentEntityRepository extends JpaRepository<AssignmentEntity, String> {
public interface AssignmentRepository extends JpaRepository<AssignmentEntity, String>, JpaSpecificationExecutor<AssignmentEntity> {


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.ays.assignment.service;

import com.ays.assignment.model.dto.request.AssignmentSaveRequest;

/**
* Assignment Save Service to perform assignment related save business operations.
*/
public interface AssignmentSaveService {

/**
* Saves a saveRequest to the database.
*
* @param saveRequest the AssignmentSaveRequest entity
* @return Assignment
*/
void saveAssignment(AssignmentSaveRequest saveRequest);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.ays.assignment.service.impl;

import com.ays.assignment.model.dto.request.AssignmentSaveRequest;
import com.ays.assignment.model.entity.AssignmentEntity;
import com.ays.assignment.model.mapper.AssignmentSaveRequestToAssignmentMapper;
import com.ays.assignment.repository.AssignmentRepository;
import com.ays.assignment.service.AssignmentSaveService;
import com.ays.auth.model.AysIdentity;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
* UserSaveServiceImpl is an implementation of the {@link AssignmentSaveService} interface.
* It provides methods for saving assignment data and performing related operations by admin.
*/
@Service
@RequiredArgsConstructor
class AssignmentSaveServiceImpl implements AssignmentSaveService {

private final AssignmentRepository assignmentRepository;

private final AysIdentity identity;

private static final AssignmentSaveRequestToAssignmentMapper assignmentSaveRequestToAssignmentMapper = AssignmentSaveRequestToAssignmentMapper.initialize();

/**
* Saves a new assignment based on the provided save request.
*
* @param saveRequest the request object containing assignment data to be saved
* @return the saved assignment
*/
@Override
public void saveAssignment(AssignmentSaveRequest saveRequest) {

final AssignmentEntity assignmentEntity = assignmentSaveRequestToAssignmentMapper.mapForSaving(saveRequest, identity.getInstitutionId());

assignmentRepository.save(assignmentEntity);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.io.Serial;

/**
* Exception thrown when a user assignment is available and attempting to perform an action that requires an assignment which is already available.
* Exception thrown when an assignment is available and attempting to perform an action that requires an assignment which is already available.
*/
public class AysAssignmentAlreadyAvailableException extends AysAlreadyException {

Expand Down
Loading

0 comments on commit 02035a6

Please sign in to comment.