Skip to content

Commit

Permalink
PO-495: Add infra code for BacsPayment
Browse files Browse the repository at this point in the history
  • Loading branch information
RustyHMCTS committed Jul 11, 2024
1 parent 1fc6691 commit a712f85
Show file tree
Hide file tree
Showing 13 changed files with 598 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.BacsPaymentSearchDto;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity;
import uk.gov.hmcts.opal.service.BacsPaymentServiceInterface;

import java.util.List;

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


@RestController
@RequestMapping("/dev/bacs-payment")
@Slf4j(topic = "BacsPaymentController")
@Tag(name = "BacsPayment Controller")
public class BacsPaymentController {

private final BacsPaymentServiceInterface bacsPaymentService;

public BacsPaymentController(@Qualifier("bacsPaymentService") BacsPaymentServiceInterface bacsPaymentService) {
this.bacsPaymentService = bacsPaymentService;
}

@GetMapping(value = "/{bacsPaymentId}")
@Operation(summary = "Returns the BacsPayment for the given bacsPaymentId.")
public ResponseEntity<BacsPaymentEntity> getBacsPaymentById(@PathVariable Long bacsPaymentId) {

log.info(":GET:getBacsPaymentById: bacsPaymentId: {}", bacsPaymentId);

BacsPaymentEntity response = bacsPaymentService.getBacsPayment(bacsPaymentId);

return buildResponse(response);
}

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

List<BacsPaymentEntity> response = bacsPaymentService.searchBacsPayments(criteria);

return buildResponse(response);
}


}
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 BacsPaymentSearchDto implements ToJsonString {

private String bacsPaymentId;
private String businessUnitId;

}
64 changes: 64 additions & 0 deletions src/main/java/uk/gov/hmcts/opal/entity/BacsPaymentEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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 = "bacs_payments")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "bacsPaymentId")
public class BacsPaymentEntity {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "bacs_payment_id_seq_generator")
@SequenceGenerator(name = "bacs_payment_id_seq_generator", sequenceName = "bacs_payment_id_seq", allocationSize = 1)
@Column(name = "bacs_payment_id", nullable = false)
private Long bacsPaymentId;

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

@Column(name = "bacs_number", nullable = false)
private Long bacsNumber;

@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 = "status", length = 10, nullable = false)
private String status;

}
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.BacsPaymentEntity;

@Repository
public interface BacsPaymentRepository extends JpaRepository<BacsPaymentEntity, Long>,
JpaSpecificationExecutor<BacsPaymentEntity> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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.BacsPaymentSearchDto;
import uk.gov.hmcts.opal.entity.BusinessUnitEntity;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity_;

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

public class BacsPaymentSpecs extends EntitySpecs<BacsPaymentEntity> {

public Specification<BacsPaymentEntity> findBySearchCriteria(BacsPaymentSearchDto criteria) {
return Specification.allOf(specificationList(
notBlank(criteria.getBacsPaymentId()).map(BacsPaymentSpecs::equalsBacsPaymentId),
numericShort(criteria.getBusinessUnitId()).map(BacsPaymentSpecs::equalsBusinessUnitId)
));
}

public static Specification<BacsPaymentEntity> equalsBacsPaymentId(String bacsPaymentId) {
return (root, query, builder) -> builder.equal(root.get(BacsPaymentEntity_.bacsPaymentId), bacsPaymentId);
}

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

public static Join<BacsPaymentEntity, BusinessUnitEntity> joinBusinessUnit(From<?, BacsPaymentEntity> from) {
return from.join(BacsPaymentEntity_.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.BacsPaymentSearchDto;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity;

import java.util.List;

public interface BacsPaymentServiceInterface {

BacsPaymentEntity getBacsPayment(long bacsPaymentId);

List<BacsPaymentEntity> searchBacsPayments(BacsPaymentSearchDto 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.BacsPaymentSearchDto;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity;
import uk.gov.hmcts.opal.service.BacsPaymentServiceInterface;

import java.util.List;

@Service
@Slf4j(topic = "LegacyBacsPaymentService")
public class LegacyBacsPaymentService extends LegacyService implements BacsPaymentServiceInterface {

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

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

@Override
public BacsPaymentEntity getBacsPayment(long bacsPaymentId) {
throw new LegacyGatewayResponseException("Not Yet Implemented");
}

@Override
public List<BacsPaymentEntity> searchBacsPayments(BacsPaymentSearchDto criteria) {
throw new LegacyGatewayResponseException("Not Yet Implemented");
}

}
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.BacsPaymentSearchDto;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity;
import uk.gov.hmcts.opal.repository.BacsPaymentRepository;
import uk.gov.hmcts.opal.repository.jpa.BacsPaymentSpecs;
import uk.gov.hmcts.opal.service.BacsPaymentServiceInterface;

import java.util.List;

@Service
@RequiredArgsConstructor
@Qualifier("bacsPaymentService")
public class BacsPaymentService implements BacsPaymentServiceInterface {

private final BacsPaymentRepository bacsPaymentRepository;

private final BacsPaymentSpecs specs = new BacsPaymentSpecs();

@Override
public BacsPaymentEntity getBacsPayment(long bacsPaymentId) {
return bacsPaymentRepository.getReferenceById(bacsPaymentId);
}

@Override
public List<BacsPaymentEntity> searchBacsPayments(BacsPaymentSearchDto criteria) {
Page<BacsPaymentEntity> page = bacsPaymentRepository
.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.BacsPaymentSearchDto;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity;
import uk.gov.hmcts.opal.service.DynamicConfigService;
import uk.gov.hmcts.opal.service.BacsPaymentServiceInterface;
import uk.gov.hmcts.opal.service.legacy.LegacyBacsPaymentService;
import uk.gov.hmcts.opal.service.opal.BacsPaymentService;

import java.util.List;

@Service
@RequiredArgsConstructor
@Qualifier("bacsPaymentServiceProxy")
public class BacsPaymentServiceProxy implements BacsPaymentServiceInterface, ProxyInterface {

private final BacsPaymentService opalBacsPaymentService;
private final LegacyBacsPaymentService legacyBacsPaymentService;
private final DynamicConfigService dynamicConfigService;

private BacsPaymentServiceInterface getCurrentModeService() {
return isLegacyMode(dynamicConfigService) ? legacyBacsPaymentService : opalBacsPaymentService;
}

@Override
public BacsPaymentEntity getBacsPayment(long bacsPaymentId) {
return getCurrentModeService().getBacsPayment(bacsPaymentId);
}

@Override
public List<BacsPaymentEntity> searchBacsPayments(BacsPaymentSearchDto criteria) {
return getCurrentModeService().searchBacsPayments(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.BacsPaymentSearchDto;
import uk.gov.hmcts.opal.entity.BacsPaymentEntity;
import uk.gov.hmcts.opal.service.opal.BacsPaymentService;

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 BacsPaymentControllerTest {

@Mock
private BacsPaymentService bacsPaymentService;

@InjectMocks
private BacsPaymentController bacsPaymentController;

@Test
void testGetBacsPayment_Success() {
// Arrange
BacsPaymentEntity entity = BacsPaymentEntity.builder().build();

when(bacsPaymentService.getBacsPayment(any(Long.class))).thenReturn(entity);

// Act
ResponseEntity<BacsPaymentEntity> response = bacsPaymentController.getBacsPaymentById(1L);

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

@Test
void testSearchBacsPayments_Success() {
// Arrange
BacsPaymentEntity entity = BacsPaymentEntity.builder().build();
List<BacsPaymentEntity> bacsPaymentList = List.of(entity);

when(bacsPaymentService.searchBacsPayments(any())).thenReturn(bacsPaymentList);

// Act
BacsPaymentSearchDto searchDto = BacsPaymentSearchDto.builder().build();
ResponseEntity<List<BacsPaymentEntity>> response = bacsPaymentController.postBacsPaymentsSearch(searchDto);

// Assert
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(bacsPaymentList, response.getBody());
verify(bacsPaymentService, times(1)).searchBacsPayments(any());
}

}
Loading

0 comments on commit a712f85

Please sign in to comment.