Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VAS-1113] feat: Improvement get available CI for station api #56

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: pagopa-api-config-selfcare-integration
description: Microservice that manages requests from selfcare
type: application
version: 1.95.0
appVersion: 1.11.4
version: 1.96.0
appVersion: 1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api
dependencies:
- name: microservice-chart
version: 2.8.0
Expand Down
2 changes: 1 addition & 1 deletion helm/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ microservice-chart: &microservice-chart
envSecret: {}
image:
repository: ghcr.io/pagopa/pagopa-api-config-selfcare-integration
tag: "1.11.4"
tag: "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion helm/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ microservice-chart: &microservice-chart
envSecret: {}
image:
repository: ghcr.io/pagopa/pagopa-api-config-selfcare-integration
tag: "1.11.4"
tag: "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
2 changes: 1 addition & 1 deletion helm/values-uat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ microservice-chart: &microservice-chart
envSecret: {}
image:
repository: ghcr.io/pagopa/pagopa-api-config-selfcare-integration
tag: "1.11.4"
tag: "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
pullPolicy: Always
livenessProbe:
httpGet:
Expand Down
24 changes: 19 additions & 5 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"title": "API-Config - SelfCare Integration",
"description": "Spring application exposes APIs for SelfCare",
"termsOfService": "https://www.pagopa.gov.it/",
"version": "1.11.4"
"version": "1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api"
},
"servers": [
{
Expand Down Expand Up @@ -667,7 +667,7 @@
"tags": [
"Creditor Institutions"
],
"summary": "Get the list of creditor institutions associated to a station",
"summary": "Get the list of creditor institutions that can be associated to a station",
"operationId": "getStationCreditorInstitutions",
"parameters": [
{
Expand All @@ -678,6 +678,20 @@
"schema": {
"type": "string"
}
},
{
"name": "ciTaxCodeList",
"in": "query",
"description": "List of Creditor Institution's tax code, restrict the research to this tax code list only",
"required": true,
"schema": {
"maxItems": 10,
"minItems": 0,
"type": "array",
"items": {
"type": "string"
}
}
}
],
"responses": {
Expand All @@ -696,7 +710,7 @@
"schema": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/components/schemas/CreditorInstitutionInfo"
}
}
}
Expand Down Expand Up @@ -2263,7 +2277,7 @@
"CreditorInstitutionInfo": {
"required": [
"business_name",
"creditor_institution_code"
"ci_tax_code"
],
"type": "object",
"properties": {
Expand All @@ -2272,7 +2286,7 @@
"description": "The business name of the creditor institution",
"example": "Comune di Roma"
},
"creditor_institution_code": {
"ci_tax_code": {
"type": "string",
"description": "The tax code of the creditor institution",
"example": "02438750586"
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<groupId>it.gov.pagopa.api-config</groupId>
<artifactId>selfcareintegration</artifactId>
<version>1.11.4</version>
<version>1.11.4-1-VAS-1113-improvement-get-available-ci-for-station-api</version>
<name>API-Config - SelfCare Integration</name>
<description>Spring application exposes APIs for SelfCare</description>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ public ResponseEntity<StationDetailsList> getStationsDetailsFromCreditorInstitut
* code 500)
*/
@Operation(
summary = "Get the list of creditor institutions associated to a station",
summary = "Get the list of creditor institutions that can be associated to a station",
security = {@SecurityRequirement(name = "ApiKey"), @SecurityRequirement(name = "Authorization")})
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "OK",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
array = @ArraySchema(schema = @Schema(implementation = String.class)))),
array = @ArraySchema(schema = @Schema(implementation = CreditorInstitutionInfo.class)))),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "403", description = "Forbidden", content = @Content(schema = @Schema())),
Expand All @@ -102,10 +102,11 @@ public ResponseEntity<StationDetailsList> getStationsDetailsFromCreditorInstitut
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))
})
@GetMapping(value = "/stations/{station-code}", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<String>> getStationCreditorInstitutions(
@Parameter(description = "Station's code") @PathVariable("station-code") String stationCode
public ResponseEntity<List<CreditorInstitutionInfo>> getStationCreditorInstitutions(
@Parameter(description = "Station's code") @PathVariable("station-code") String stationCode,
@Parameter(description = "List of Creditor Institution's tax code, restrict the research to this tax code list only") @RequestParam @Size(max = 10) List<String> ciTaxCodeList
) {
return ResponseEntity.ok(this.creditorInstitutionsService.getStationCreditorInstitutions(stationCode));
return ResponseEntity.ok(this.creditorInstitutionsService.getStationCreditorInstitutions(stationCode, ciTaxCodeList));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum AppError {
"Creditor Institutions not found",
"No Creditor Institutions found with codes: %s"),
STATION_NOT_FOUND(HttpStatus.NOT_FOUND, "Station not found", "No Station found with code: %s"),
PA_NOT_FOUND(HttpStatus.NOT_FOUND, "PA not found", "No PA found with code: %s"),


BROKER_NOT_FOUND(HttpStatus.NOT_FOUND, "Broker not found", "No Broker found with code: %s"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ConvertPaToCreditorInstitutionInfo implements Converter<Pa, Credito
public CreditorInstitutionInfo convert(MappingContext<Pa, CreditorInstitutionInfo> context) {
@Valid Pa pa = context.getSource();
return CreditorInstitutionInfo.builder()
.creditorInstitutionCode(pa.getIdDominio())
.ciTaxCode(pa.getIdDominio())
.businessName(pa.getRagioneSociale() != null ? pa.getRagioneSociale() : "")
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public class CreditorInstitutionInfo {
@NotNull
private String businessName;

@JsonProperty("creditor_institution_code")
@JsonProperty("ci_tax_code")
@Schema(example = "02438750586", description = "The tax code of the creditor institution", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
private String creditorInstitutionCode;
private String ciTaxCode;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package it.gov.pagopa.apiconfig.selfcareintegration.repository;

import it.gov.pagopa.apiconfig.starter.entity.Pa;
import it.gov.pagopa.apiconfig.starter.entity.PaStazionePa;
import it.gov.pagopa.apiconfig.starter.entity.Stazioni;
import it.gov.pagopa.apiconfig.starter.repository.PaStazionePaRepository;
Expand All @@ -18,5 +19,5 @@ public interface ExtendedCreditorInstitutionStationRepository extends PaStazione

Page<PaStazionePa> findByFkPa(@Param("fkPa") Long creditorInstitutionId, Pageable pageable);

List<PaStazionePa> findByFkStazione(@Param("fkStazione") Stazioni station);
List<PaStazionePa> findByFkStazioneAndPaIn(@Param("fkStazione") Stazioni station, @Param("pa") List<Pa> paList);
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,21 @@ public List<CreditorInstitutionInfo> getCreditorInstitutionInfoList(List<String>
* @param stationCode station's code
* @return the list of creditor institution's tax codes
*/
public List<String> getStationCreditorInstitutions(String stationCode) {
public List<CreditorInstitutionInfo> getStationCreditorInstitutions(String stationCode, List<String> ciTaxCodeList) {
Stazioni station = this.stationRepository.findByIdStazione(stationCode)
.orElseThrow(() -> new AppException(AppError.STATION_NOT_FOUND, stationCode));

List<PaStazionePa> stazionePaList = this.ciStationRepository.findByFkStazione(station);
return stazionePaList.stream()
List<Pa> paList = this.paRepository.findByIdDominioIn(ciTaxCodeList)
.orElseThrow(() -> new AppException(AppError.PA_NOT_FOUND, ciTaxCodeList));

List<String> stazionePaList = this.ciStationRepository.findByFkStazioneAndPaIn(station, paList).stream()
.map(paStazionePa -> paStazionePa.getPa().getIdDominio())
.toList();

return paList.parallelStream()
.filter(pa -> !stazionePaList.contains(pa.getIdDominio()))
.map(pa -> this.modelMapper.map(pa, CreditorInstitutionInfo.class))
.toList();
}

private CIAssociatedCodeList extractUsedAndUnusedCodes(
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/h2/schema-h2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ create table NODO4_CFG.STAZIONI
TARGET_HOST_POF varchar(100),
TARGET_PORT_POF numeric,
TARGET_PATH_POF varchar(100),
FLAG_STANDIN char not null default 'N',
VERSIONE_PRIMITIVE numeric(2) default 1,
constraint PK_STAZIONI
primary key (OBJ_ID),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,13 @@ void getCreditorInstitutionsTest() throws Exception {

@Test
void getStationCreditorInstitutionsTest() throws Exception {
List<String> ciTaxCodes = Collections.singletonList("ciTaxCode");

when(creditorInstitutionsService.getStationCreditorInstitutions("stationCode"))
.thenReturn(Collections.singletonList("ciTaxCode"));
when(creditorInstitutionsService.getStationCreditorInstitutions("stationCode", ciTaxCodes))
.thenReturn(Collections.singletonList(CreditorInstitutionInfo.builder().build()));

mvc.perform(get("/creditorinstitutions/stations/{station-code}", "stationCode"))
mvc.perform(get("/creditorinstitutions/stations/{station-code}", "stationCode")
.param("ciTaxCodeList", String.valueOf(ciTaxCodes)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand All @@ -58,6 +58,7 @@ class CreditorInstitutionsServiceTest {
private static final String CI_TAX_CODE = "1234";
private static final String TARGET_CI_TAX_CODE = "targetCITaxCode";
private static final String STATION_CODE = "stationCode";
private static final String RAGIONE_SOCIALE = "pa";

@MockBean
private PaRepository paRepository;
Expand Down Expand Up @@ -218,7 +219,7 @@ void getCreditorInstitutionInfoListSuccess() throws IOException {
assertNotNull(result);
assertEquals(1, result.size());
CreditorInstitutionInfo ci = result.get(0);
assertEquals(pa.getIdDominio(), ci.getCreditorInstitutionCode());
assertEquals(pa.getIdDominio(), ci.getCiTaxCode());
assertEquals(pa.getRagioneSociale(), ci.getBusinessName());
}

Expand Down Expand Up @@ -253,24 +254,51 @@ void getCreditorInstitutionInfoListFailInternalServerError() throws IOException
void getStationCreditorInstitutionsSuccess() throws IOException {
Stazioni stazioni = getMockStazioni();
PaStazionePa paStazionePa = getMockPaStazionePa();
Pa pa = getMockPa();
List<String> ciTaxCodes = List.of(CI_TAX_CODE, pa.getIdDominio());
List<Pa> paList = List.of(pa, Pa.builder().idDominio(CI_TAX_CODE).ragioneSociale(RAGIONE_SOCIALE).build());

when(stationRepository.findByIdStazione(STATION_CODE)).thenReturn(Optional.of(stazioni));
when(ciStationRepository.findByFkStazione(stazioni)).thenReturn(Collections.singletonList(paStazionePa));
when(paRepository.findByIdDominioIn(ciTaxCodes)).thenReturn(Optional.of(paList));
when(ciStationRepository.findByFkStazioneAndPaIn(stazioni, paList)).thenReturn(Collections.singletonList(paStazionePa));

List<String> result = assertDoesNotThrow(() -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE));
List<CreditorInstitutionInfo> result = assertDoesNotThrow(() ->
creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE, ciTaxCodes));

assertNotNull(result);
assertEquals(1, result.size());
assertEquals(RAGIONE_SOCIALE, result.get(0).getBusinessName());
assertEquals(CI_TAX_CODE, result.get(0).getCiTaxCode());
}

@Test
void getStationCreditorInstitutionsFailNotFound() {
void getStationCreditorInstitutionsFailStationNotFound() {
List<String> ciTaxCodes = Collections.singletonList(CI_TAX_CODE);

when(stationRepository.findByIdStazione(STATION_CODE)).thenReturn(Optional.empty());

AppException e = assertThrows(AppException.class, () -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE));
AppException e = assertThrows(AppException.class, () -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE, ciTaxCodes));

assertNotNull(e);
assertEquals(HttpStatus.NOT_FOUND, e.getHttpStatus());

verify(paRepository, never()).findByIdDominioIn(anyList());
verify(ciStationRepository, never()).findByFkStazioneAndPaIn(any(), anyList());
}

@Test
void getStationCreditorInstitutionsFailPaNotFound() throws IOException {
List<String> ciTaxCodes = Collections.singletonList(CI_TAX_CODE);
Stazioni stazioni = getMockStazioni();

when(stationRepository.findByIdStazione(STATION_CODE)).thenReturn(Optional.of(stazioni));
when(paRepository.findByIdDominioIn(ciTaxCodes)).thenReturn(Optional.empty());

AppException e = assertThrows(AppException.class, () -> creditorInstitutionsService.getStationCreditorInstitutions(STATION_CODE, ciTaxCodes));

assertNotNull(e);
assertEquals(HttpStatus.NOT_FOUND, e.getHttpStatus());

verify(ciStationRepository, never()).findByFkStazione(any());
verify(ciStationRepository, never()).findByFkStazioneAndPaIn(any(), anyList());
}
}
Loading