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

feat: [PagoPa-1997] - paid notice details #88

Merged
merged 13 commits into from
Sep 5, 2024
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
3,561 changes: 1,698 additions & 1,863 deletions openapi/openapi.json

Large diffs are not rendered by default.

1,073 changes: 505 additions & 568 deletions openapi/openapi_ec.json

Large diffs are not rendered by default.

1,446 changes: 703 additions & 743 deletions openapi/openapi_helpdesk.json

Large diffs are not rendered by default.

1,530 changes: 639 additions & 891 deletions openapi/openapi_io.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
public class Application {

public static void main(String[] args) {
// to avoid java.lang.ClassCastException for objects fetched from the REDIS cache
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(Application.class, args);
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package it.gov.pagopa.bizeventsservice.controller;

import javax.validation.constraints.NotBlank;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
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.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -9,19 +20,33 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import it.gov.pagopa.bizeventsservice.model.ProblemJson;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import it.gov.pagopa.bizeventsservice.model.response.paidnotice.NoticeDetailResponse;


@Tag(name = "Paid Notice REST APIs")
@RequestMapping("/paids")
@Validated
public interface IPaidNoticeController {
String X_FISCAL_CODE = "x-fiscal-code";

/**
* @param fiscalCode
* @param eventId
* @return the paid notice detail
*/
@Operation(summary = "Retrieve the paid notice details given its id.", security = {
@SecurityRequirement(name = "ApiKey")}, operationId = "getPaidNoticeDetail")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Obtained paid notice detail.",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(name = "NoticeDetailResponse", implementation = NoticeDetailResponse.class))),
@ApiResponse(responseCode = "401", description = "Wrong or missing function key.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "404", description = "Not found the transaction.", content = @Content(schema = @Schema(implementation = ProblemJson.class))),
@ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "500", description = "Service unavailable.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))})
@GetMapping(value = "/{event-id}", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<NoticeDetailResponse> getPaidNoticeDetail(
@RequestHeader("x-fiscal-code") @NotBlank String fiscalCode,
@Parameter(description = "The id of the paid event.", required = true) @NotBlank @PathVariable("event-id") String eventId);

@Operation(summary = "Disable the paid notice details given its id.", security = {
@SecurityRequirement(name = "ApiKey")}, operationId = "disablePaidNotice")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,37 +73,12 @@ ResponseEntity<TransactionListWrapResponse> getTransactionList(


/**
* recovers biz-event data for the transaction list
*
* @param fiscalCode tokenized user fiscal code
* @param isPayer optional flag defining the filter to select only the notices where the user is the payer
* @param isDebtor optional flag defining the filter to select only the notices where the user is the debtor
* @param page optional parameter defining page number, default to 0 (first page)
* @param size optional parameter defining page size, defaults to 10
* @param orderBy optional parameter defining the sort field for the returned list, defaults to TRANSACTION_DATE
* @param ordering optional parameter defining the sorting direction of the returned list, defaults to DESC
* @return the transaction list
* @param fiscalCode
* @param transactionId
* @return the transaction details
* @deprecated
*/
@GetMapping(value = "/cached", produces = MediaType.APPLICATION_JSON_VALUE)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Obtained transaction list.",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(name = "TransactionListWrapResponse", implementation = TransactionListWrapResponse.class))),
@ApiResponse(responseCode = "401", description = "Wrong or missing function key.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "404", description = "Not found the transaction.", content = @Content(schema = @Schema(implementation = ProblemJson.class))),
@ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "500", description = "Service unavailable.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))})
@Operation(summary = "Retrieve the paged transaction list from biz events.", security = {
@SecurityRequirement(name = "ApiKey")}, operationId = "getTransactionList")
ResponseEntity<TransactionListWrapResponse> getCachedTransactionList(
@RequestHeader(name = X_FISCAL_CODE) String fiscalCode,
@Valid @Parameter(description = "Filter by payer") @RequestParam(value = "is_payer", required = false) Boolean isPayer,
@Valid @Parameter(description = "Filter by debtor") @RequestParam(value = "is_debtor", required = false) Boolean isDebtor,
@RequestParam(name = PAGE_NUMBER, required = false, defaultValue = "0") Integer page,
@RequestParam(name = PAGE_SIZE, required = false, defaultValue = "10") Integer size,
@RequestParam(required = false, name = "orderby", defaultValue = "TRANSACTION_DATE") @Parameter(description = "Order by TRANSACTION_DATE") Order.TransactionListOrder orderBy,
@RequestParam(required = false, name = "ordering", defaultValue = "DESC") @Parameter(description = "Direction of ordering") Sort.Direction ordering);

@Operation(summary = "Retrieve the transaction details given its id.", security = {
@Operation(summary = "Retrieve the transaction details given its id.", description = "This operation is deprecated. Use Paid Notice APIs instead", deprecated = true, security = {
@SecurityRequirement(name = "ApiKey")}, operationId = "getTransactionDetails")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Obtained transaction details.",
Expand All @@ -113,6 +88,7 @@ ResponseEntity<TransactionListWrapResponse> getCachedTransactionList(
@ApiResponse(responseCode = "429", description = "Too many requests.", content = @Content(schema = @Schema())),
@ApiResponse(responseCode = "500", description = "Service unavailable.", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = ProblemJson.class)))})
@GetMapping(value = "/{transaction-id}", produces = MediaType.APPLICATION_JSON_VALUE)
@Deprecated(forRemoval = false)
ResponseEntity<TransactionDetailResponse> getTransactionDetails(
@RequestHeader("x-fiscal-code") @NotBlank String fiscalCode,
@Parameter(description = "The id of the transaction.", required = true) @NotBlank @PathVariable("transaction-id") String transactionId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package it.gov.pagopa.bizeventsservice.controller.impl;

import it.gov.pagopa.bizeventsservice.controller.IPaidNoticeController;
import it.gov.pagopa.bizeventsservice.model.response.paidnotice.NoticeDetailResponse;
import it.gov.pagopa.bizeventsservice.service.ITransactionService;

import javax.validation.constraints.NotBlank;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -21,12 +25,17 @@ public PaidNoticeController(ITransactionService transactionService) {
this.transactionService = transactionService;
}

@Override
public ResponseEntity<NoticeDetailResponse> getPaidNoticeDetail(@NotBlank String fiscalCode,
@NotBlank String eventId) {
return new ResponseEntity<>(
transactionService.getPaidNoticeDetail(fiscalCode, eventId),
HttpStatus.OK);
}

@Override
public ResponseEntity<Void> disablePaidNotice(String fiscalCode, String transactionId) {
transactionService.disableTransaction(fiscalCode, transactionId);
return new ResponseEntity<>(HttpStatus.OK);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,6 @@ public ResponseEntity<TransactionListWrapResponse> getTransactionList(String fis
.body(TransactionListWrapResponse.builder().transactions(transactionListResponse.getTransactionList()).build());
}

@Override
public ResponseEntity<TransactionListWrapResponse> getCachedTransactionList(String fiscalCode, Boolean isPayer, Boolean isDebtor,
Integer page, Integer size, TransactionListOrder orderBy, Direction ordering) {
TransactionListResponse transactionListResponse = transactionService.getCachedTransactionList(fiscalCode, isPayer, isDebtor,
page, size, orderBy, ordering);
return ResponseEntity.ok()
.body(TransactionListWrapResponse.builder()
.transactions(transactionListResponse.getTransactionList())
.pageInfo(transactionListResponse.getPageInfo())
.build());
}

@Override
public ResponseEntity<TransactionDetailResponse> getTransactionDetails(String fiscalCode, String eventReference) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@

import java.io.Serializable;

import javax.validation.constraints.NotNull;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

import io.swagger.v3.oas.annotations.media.Schema;

@Builder
@Data
@NoArgsConstructor
Expand All @@ -23,5 +27,7 @@ public class UserDetail implements Serializable {
private static final long serialVersionUID = -5682201542579999764L;

private String name;
@Schema(required = true)
@NotNull
private String taxCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import it.gov.pagopa.bizeventsservice.model.response.transaction.CartItem;
import it.gov.pagopa.bizeventsservice.model.response.transaction.InfoTransactionView;
import it.gov.pagopa.bizeventsservice.util.DateValidator;
import it.gov.pagopa.bizeventsservice.model.response.paidnotice.InfoNotice;
import it.gov.pagopa.bizeventsservice.model.response.paidnotice.NoticeDetailResponse;
import it.gov.pagopa.bizeventsservice.model.response.transaction.*;

import org.apache.commons.lang3.BooleanUtils;
Expand Down Expand Up @@ -78,6 +80,48 @@ public static TransactionDetailResponse convertTransactionDetails(String taxCode
.carts(listOfCartItems)
.build();
}

public static NoticeDetailResponse convertPaidNoticeDetails(String taxCode, BizEventsViewGeneral bizEventsViewGeneral, List<BizEventsViewCart> listOfCartViews) {
List<it.gov.pagopa.bizeventsservice.model.response.paidnotice.CartItem> listOfCartItems = new ArrayList<>();
AtomicReference<BigDecimal> totalAmount = new AtomicReference<>(BigDecimal.ZERO);

for (BizEventsViewCart bizEventsViewCart : listOfCartViews) {

listOfCartItems.add(
it.gov.pagopa.bizeventsservice.model.response.paidnotice.CartItem.builder()
.subject(bizEventsViewCart.getSubject())
.amount(new BigDecimal(bizEventsViewCart.getAmount()).setScale(2, RoundingMode.UNNECESSARY).toString())
.debtor(bizEventsViewCart.getDebtor())
.payee(bizEventsViewCart.getPayee())
.refNumberType(bizEventsViewCart.getRefNumberType())
.refNumberValue(bizEventsViewCart.getRefNumberValue())
.build()
);
BigDecimal amountExtracted = new BigDecimal(bizEventsViewCart.getAmount());
totalAmount.updateAndGet(v -> v.add(amountExtracted));
}

// PAGOPA-1763: if the tax code refers to a debtor, do not show the sections relating to the payer
boolean isDebtor = bizEventsViewGeneral.getPayer() == null || !bizEventsViewGeneral.getPayer().getTaxCode().equals(taxCode);
return NoticeDetailResponse.builder()
.infoNotice(
InfoNotice.builder()
.eventId(bizEventsViewGeneral.getTransactionId())
.authCode(bizEventsViewGeneral.getAuthCode())
.rrn(bizEventsViewGeneral.getRrn())
.noticeDate(dateFormatZoned(bizEventsViewGeneral.getTransactionDate()))
.pspName(bizEventsViewGeneral.getPspName())
.walletInfo(isDebtor ? null:bizEventsViewGeneral.getWalletInfo())
.payer(isDebtor ? null:bizEventsViewGeneral.getPayer())
.amount(totalAmount.get().setScale(2, RoundingMode.UNNECESSARY).toString())
.fee(StringUtils.isNotEmpty(bizEventsViewGeneral.getFee()) ? bizEventsViewGeneral.getFee().replace(',', '.') : bizEventsViewGeneral.getFee())
.paymentMethod(isDebtor ? null:bizEventsViewGeneral.getPaymentMethod())
.origin(bizEventsViewGeneral.getOrigin())
.build()
)
.carts(listOfCartItems)
.build();
}

public static TransactionListItem convertTransactionListItem(BizEventsViewUser viewUser, List<BizEventsViewCart> listOfCartViews){
AtomicReference<BigDecimal> totalAmount = new AtomicReference<>(BigDecimal.ZERO);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package it.gov.pagopa.bizeventsservice.model.response.paidnotice;

import it.gov.pagopa.bizeventsservice.entity.view.UserDetail;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

import javax.validation.constraints.NotNull;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

import io.swagger.v3.oas.annotations.media.Schema;

/**
* Response model for transaction detail API
*/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(Include.NON_NULL)
public class CartItem implements Serializable {

private static final long serialVersionUID = -6391592801925923358L;
@Schema(required = true)
@NotNull
private String subject;
@Schema(required = true)
@NotNull
private String amount;
private UserDetail payee;
private UserDetail debtor;
@Schema(required = true)
@NotNull
private String refNumberValue;
@Schema(required = true)
@NotNull
private String refNumberType;
}
Loading
Loading