Skip to content

Commit

Permalink
PO-495: Infra code for Cheques
Browse files Browse the repository at this point in the history
  • Loading branch information
RustyHMCTS committed Jul 12, 2024
1 parent a712f85 commit 9085cf5
Show file tree
Hide file tree
Showing 13 changed files with 609 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package uk.gov.hmcts.opal.controllers.develop;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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;
import uk.gov.hmcts.opal.dto.search.ChequeSearchDto;
import uk.gov.hmcts.opal.entity.ChequeEntity;
import uk.gov.hmcts.opal.service.ChequeServiceInterface;

import java.util.List;

import static uk.gov.hmcts.opal.util.HttpUtil.buildResponse;


@RestController
@RequestMapping("/dev/cheque")
@Slf4j(topic = "ChequeController")
@Tag(name = "Cheque Controller")
public class ChequeController {

private final ChequeServiceInterface chequeService;

public ChequeController(@Qualifier("chequeService") ChequeServiceInterface chequeService) {
this.chequeService = chequeService;
}

@GetMapping(value = "/{chequeId}")
@Operation(summary = "Returns the Cheque for the given chequeId.")
public ResponseEntity<ChequeEntity> getChequeById(@PathVariable Long chequeId) {

log.info(":GET:getChequeById: chequeId: {}", chequeId);

ChequeEntity response = chequeService.getCheque(chequeId);

return buildResponse(response);
}

@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Searches Cheques based upon criteria in request body")
public ResponseEntity<List<ChequeEntity>> postChequesSearch(@RequestBody ChequeSearchDto criteria) {
log.info(":POST:postChequesSearch: query: \n{}", criteria);

List<ChequeEntity> response = chequeService.searchCheques(criteria);

return buildResponse(response);
}


}
14 changes: 14 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/dto/search/ChequeSearchDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package uk.gov.hmcts.opal.dto.search;

import lombok.Builder;
import lombok.Data;
import uk.gov.hmcts.opal.dto.ToJsonString;

@Data
@Builder
public class ChequeSearchDto implements ToJsonString {

private String chequeId;
private String businessUnitId;

}
71 changes: 71 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/entity/ChequeEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package uk.gov.hmcts.opal.entity;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDate;

@Entity
@Table(name = "cheques")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "chequeId")
public class ChequeEntity {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cheque_id_seq_generator")
@SequenceGenerator(name = "cheque_id_seq_generator", sequenceName = "cheque_id_seq", allocationSize = 1)
@Column(name = "cheque_id", nullable = false)
private Long chequeId;

@ManyToOne
@JoinColumn(name = "business_unit_id", nullable = false)
private BusinessUnitEntity businessUnit;

@Column(name = "cheque_number", nullable = false)
private Long chequeNumber;

@Column(name = "issue_date", nullable = false)
@Temporal(TemporalType.DATE)
private LocalDate issueDate;

@Column(name = "creditor_transaction_id")
private Long creditorTransactionId;

@Column(name = "defendant_transaction_id")
private Long defendantTransactionId;

@Column(name = "amount", precision = 18, scale = 2, nullable = false)
private BigDecimal amount;

@Column(name = "allocation_type", length = 10)
private String allocationType;

@Column(name = "reminder_date")
@Temporal(TemporalType.DATE)
private LocalDate reminderDate;

@Column(name = "status", length = 1, nullable = false)
private String status;

}
11 changes: 11 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/repository/ChequeRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package uk.gov.hmcts.opal.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import uk.gov.hmcts.opal.entity.ChequeEntity;

@Repository
public interface ChequeRepository extends JpaRepository<ChequeEntity, Long>,
JpaSpecificationExecutor<ChequeEntity> {
}
38 changes: 38 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/repository/jpa/ChequeSpecs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package uk.gov.hmcts.opal.repository.jpa;

import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.Join;
import org.springframework.data.jpa.domain.Specification;
import uk.gov.hmcts.opal.dto.search.ChequeSearchDto;
import uk.gov.hmcts.opal.entity.BusinessUnitEntity;
import uk.gov.hmcts.opal.entity.ChequeEntity;
import uk.gov.hmcts.opal.entity.ChequeEntity_;

import static uk.gov.hmcts.opal.repository.jpa.BusinessUnitSpecs.equalsBusinessUnitIdPredicate;

public class ChequeSpecs extends EntitySpecs<ChequeEntity> {

public Specification<ChequeEntity> findBySearchCriteria(ChequeSearchDto criteria) {
return Specification.allOf(specificationList(
notBlank(criteria.getChequeId()).map(ChequeSpecs::equalsChequeId),
numericShort(criteria.getBusinessUnitId()).map(ChequeSpecs::equalsBusinessUnitId)
));
}

public static Specification<ChequeEntity> equalsChequeId(String chequeId) {
return (root, query, builder) -> builder.equal(root.get(ChequeEntity_.chequeId), chequeId);
}

public static Specification<ChequeEntity> equalsBusinessUnitId(Short businessUnitId) {
return (root, query, builder) ->
equalsBusinessUnitIdPredicate(joinBusinessUnit(root), builder, businessUnitId);
}

public static Specification<ChequeEntity> equalsChequeNumber(String chequeNumber) {
return (root, query, builder) -> builder.equal(root.get(ChequeEntity_.chequeNumber), chequeNumber);
}

public static Join<ChequeEntity, BusinessUnitEntity> joinBusinessUnit(From<?, ChequeEntity> from) {
return from.join(ChequeEntity_.businessUnit);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package uk.gov.hmcts.opal.service;

import uk.gov.hmcts.opal.dto.search.ChequeSearchDto;
import uk.gov.hmcts.opal.entity.ChequeEntity;

import java.util.List;

public interface ChequeServiceInterface {

ChequeEntity getCheque(long chequeId);

List<ChequeEntity> searchCheques(ChequeSearchDto criteria);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package uk.gov.hmcts.opal.service.legacy;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import uk.gov.hmcts.opal.config.properties.LegacyGatewayProperties;
import uk.gov.hmcts.opal.dto.search.ChequeSearchDto;
import uk.gov.hmcts.opal.entity.ChequeEntity;
import uk.gov.hmcts.opal.service.ChequeServiceInterface;

import java.util.List;

@Service
@Slf4j(topic = "LegacyChequeService")
public class LegacyChequeService extends LegacyService implements ChequeServiceInterface {

public LegacyChequeService(LegacyGatewayProperties legacyGatewayProperties, RestClient restClient) {
super(legacyGatewayProperties, restClient);
}

@Override
public Logger getLog() {
return log;
}

@Override
public ChequeEntity getCheque(long chequeId) {
throw new LegacyGatewayResponseException("Not Yet Implemented");
}

@Override
public List<ChequeEntity> searchCheques(ChequeSearchDto criteria) {
throw new LegacyGatewayResponseException("Not Yet Implemented");
}

}
40 changes: 40 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/service/opal/ChequeService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package uk.gov.hmcts.opal.service.opal;


import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import uk.gov.hmcts.opal.dto.search.ChequeSearchDto;
import uk.gov.hmcts.opal.entity.ChequeEntity;
import uk.gov.hmcts.opal.repository.ChequeRepository;
import uk.gov.hmcts.opal.repository.jpa.ChequeSpecs;
import uk.gov.hmcts.opal.service.ChequeServiceInterface;

import java.util.List;

@Service
@RequiredArgsConstructor
@Qualifier("chequeService")
public class ChequeService implements ChequeServiceInterface {

private final ChequeRepository chequeRepository;

private final ChequeSpecs specs = new ChequeSpecs();

@Override
public ChequeEntity getCheque(long chequeId) {
return chequeRepository.getReferenceById(chequeId);
}

@Override
public List<ChequeEntity> searchCheques(ChequeSearchDto criteria) {
Page<ChequeEntity> page = chequeRepository
.findBy(specs.findBySearchCriteria(criteria),
ffq -> ffq.page(Pageable.unpaged()));

return page.getContent();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package uk.gov.hmcts.opal.service.proxy;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import uk.gov.hmcts.opal.dto.search.ChequeSearchDto;
import uk.gov.hmcts.opal.entity.ChequeEntity;
import uk.gov.hmcts.opal.service.DynamicConfigService;
import uk.gov.hmcts.opal.service.ChequeServiceInterface;
import uk.gov.hmcts.opal.service.legacy.LegacyChequeService;
import uk.gov.hmcts.opal.service.opal.ChequeService;

import java.util.List;

@Service
@RequiredArgsConstructor
@Qualifier("chequeServiceProxy")
public class ChequeServiceProxy implements ChequeServiceInterface, ProxyInterface {

private final ChequeService opalChequeService;
private final LegacyChequeService legacyChequeService;
private final DynamicConfigService dynamicConfigService;

private ChequeServiceInterface getCurrentModeService() {
return isLegacyMode(dynamicConfigService) ? legacyChequeService : opalChequeService;
}

@Override
public ChequeEntity getCheque(long chequeId) {
return getCurrentModeService().getCheque(chequeId);
}

@Override
public List<ChequeEntity> searchCheques(ChequeSearchDto criteria) {
return getCurrentModeService().searchCheques(criteria);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package uk.gov.hmcts.opal.controllers.develop;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import uk.gov.hmcts.opal.dto.search.ChequeSearchDto;
import uk.gov.hmcts.opal.entity.ChequeEntity;
import uk.gov.hmcts.opal.service.opal.ChequeService;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class ChequeControllerTest {

@Mock
private ChequeService chequeService;

@InjectMocks
private ChequeController chequeController;

@Test
void testGetCheque_Success() {
// Arrange
ChequeEntity entity = ChequeEntity.builder().build();

when(chequeService.getCheque(any(Long.class))).thenReturn(entity);

// Act
ResponseEntity<ChequeEntity> response = chequeController.getChequeById(1L);

// Assert
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(entity, response.getBody());
verify(chequeService, times(1)).getCheque(any(Long.class));
}

@Test
void testSearchCheques_Success() {
// Arrange
ChequeEntity entity = ChequeEntity.builder().build();
List<ChequeEntity> chequeList = List.of(entity);

when(chequeService.searchCheques(any())).thenReturn(chequeList);

// Act
ChequeSearchDto searchDto = ChequeSearchDto.builder().build();
ResponseEntity<List<ChequeEntity>> response = chequeController.postChequesSearch(searchDto);

// Assert
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(chequeList, response.getBody());
verify(chequeService, times(1)).searchCheques(any());
}

}
Loading

0 comments on commit 9085cf5

Please sign in to comment.