-
Notifications
You must be signed in to change notification settings - Fork 1
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
[PIDM-42] fix(payment-status): payment position/option status not coherent #289
base: main
Are you sure you want to change the base?
Conversation
…position status not changing to PAID when paying the full amount in presence of already paid installments;
src/main/java/it/gov/pagopa/debtposition/util/DebtPositionValidation.java
Fixed
Show fixed
Hide fixed
…fix-payment-status # Conflicts: # src/main/java/it/gov/pagopa/debtposition/util/DebtPositionValidation.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[google-java-format] reported by reviewdog 🐶
pagopa-debt-position/src/main/java/it/gov/pagopa/debtposition/service/payments/PaymentsService.java
Lines 3 to 20 in c2e1437
import java.time.LocalDate; | |
import java.time.LocalDateTime; | |
import java.time.ZoneOffset; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.List; | |
import java.util.Objects; | |
import java.util.Optional; | |
import javax.validation.Valid; | |
import javax.validation.constraints.NotBlank; | |
import javax.validation.constraints.NotNull; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.stereotype.Service; | |
import org.springframework.transaction.annotation.Transactional; | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great,
How about preventing these cases by blocking the activation phase with a 409 if the activation is not related to an installment (payment option with isPartialPayment true
)?
… PIDM-42-fix-payment-status # Conflicts: # src/main/java/it/gov/pagopa/debtposition/util/DebtPositionValidation.java
…on to get/activate phase; adapt existing unit test;
@@ -69,6 +70,7 @@ public PaymentOption getPaymentOptionByNAV(@NotBlank String organizationFiscalCo | |||
// PaymentPosition used when converting PaymentOption to POWithDebtor | |||
DebtPositionStatus.validityCheckAndUpdate(paymentOption); | |||
DebtPositionStatus.expirationCheckAndUpdate(paymentOption); | |||
DebtPositionStatus.checkAlreadyPaidInstallments(paymentOption, nav); | |||
|
|||
return paymentOption; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[google-java-format] reported by reviewdog 🐶
return paymentOption; | |
if (po.isEmpty()) { | |
throw new AppException(AppError.PAYMENT_OPTION_NOT_FOUND, organizationFiscalCode, nav); |
@@ -233,7 +235,10 @@ | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[google-java-format] reported by reviewdog 🐶
} | |
pp.setLastUpdatedDate(currentDate); | |
// salvo l'aggiornamento del pagamento | |
paymentPositionRepository.saveAndFlush(pp); | |
return poToPay; | |
} | |
private Transfer updateTransferStatus(PaymentPosition pp, String iuv, String transferId) { | |
LocalDateTime currentDate = LocalDateTime.now(ZoneOffset.UTC); | |
long numberPOTransfers = 0; | |
long countReportedTransfer = 0; | |
Transfer reportedTransfer = null; | |
for (PaymentOption po : pp.getPaymentOption()) { | |
if (po.getIuv().equals(iuv)) { | |
// numero totale dei transfer per la PO | |
numberPOTransfers = po.getTransfer().stream().count(); | |
// numero dei transfer della PO in stato T_REPORTED | |
countReportedTransfer = | |
po.getTransfer().stream() | |
.filter(t -> t.getStatus().equals(TransferStatus.T_REPORTED)) | |
.count(); | |
// recupero il transfer oggetto di rendicontazione | |
Optional<Transfer> transferToReport = | |
po.getTransfer().stream().filter(t -> t.getIdTransfer().equals(transferId)).findFirst(); | |
if (transferToReport.isEmpty()) { | |
log.error( | |
"Obtained unexpected empty transfer - " | |
+ "[organizationFiscalCode= " | |
+ pp.getOrganizationFiscalCode() | |
+ "; " | |
+ "iupd= " | |
+ pp.getIupd() | |
+ "; " | |
+ "iuv= " | |
+ iuv | |
+ "; " | |
+ "idTransfer= " | |
+ transferId | |
+ "]"); | |
throw new AppException( | |
AppError.TRANSFER_REPORTING_FAILED, pp.getOrganizationFiscalCode(), iuv, transferId); | |
} |
// aggiorno lo stato della payment position | ||
if (countPaidPartialPayment > 0 && countPaidPartialPayment < numberOfPartialPayment) { | ||
// PIDM-42 if paying the full amount when there is already a paid partial payment | ||
// then update the payment position status to PAID | ||
if (countPaidPartialPayment > 0 && countPaidPartialPayment < numberOfPartialPayment | ||
&& Boolean.TRUE.equals(Objects.requireNonNull(poToPay).getIsPartialPayment())) { | ||
pp.setStatus(DebtPositionStatus.PARTIALLY_PAID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[google-java-format] reported by reviewdog 🐶
// aggiorno lo stato della payment position | |
if (countPaidPartialPayment > 0 && countPaidPartialPayment < numberOfPartialPayment) { | |
// PIDM-42 if paying the full amount when there is already a paid partial payment | |
// then update the payment position status to PAID | |
if (countPaidPartialPayment > 0 && countPaidPartialPayment < numberOfPartialPayment | |
&& Boolean.TRUE.equals(Objects.requireNonNull(poToPay).getIsPartialPayment())) { | |
pp.setStatus(DebtPositionStatus.PARTIALLY_PAID); | |
transferToReport.get().setStatus(TransferStatus.T_REPORTED); | |
transferToReport.get().setLastUpdatedDate(currentDate); | |
countReportedTransfer++; | |
// aggiorno lo stato della PO | |
if (countReportedTransfer < numberPOTransfers) { | |
po.setStatus(PaymentOptionStatus.PO_PARTIALLY_REPORTED); |
+ auxDigit | ||
+ "123456IUVMULTIPLEMOCK3") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[google-java-format] reported by reviewdog 🐶
+ auxDigit | |
+ "123456IUVMULTIPLEMOCK3") | |
+ auxDigit | |
+ "123456IUVMULTIPLEMOCK3") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[google-java-format] reported by reviewdog 🐶
pagopa-debt-position/src/main/java/it/gov/pagopa/debtposition/service/payments/PaymentsService.java
Lines 68 to 73 in 7aac4b2
PaymentOption paymentOption = po.get(); | |
// Update PaymentPosition instance only in memory | |
// PaymentPosition used when converting PaymentOption to POWithDebtor | |
DebtPositionStatus.validityCheckAndUpdate(paymentOption); | |
DebtPositionStatus.expirationCheckAndUpdate(paymentOption); | |
DebtPositionStatus.checkAlreadyPaidInstallments(paymentOption, nav); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[google-java-format] reported by reviewdog 🐶
pagopa-debt-position/src/main/java/it/gov/pagopa/debtposition/service/payments/PaymentsService.java
Lines 244 to 245 in 7aac4b2
pp.setStatus(DebtPositionStatus.PAID); | |
pp.setPaymentDate(paymentOptionModel.getPaymentDate()); |
I assume you meant isPartialPayment |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
log.warn( | ||
"Potential payment state inconsistency detected || " | ||
+ "Organization: {} || " | ||
+ "IUPD: {} || " | ||
+ "NAV: {} || " | ||
+ "Position Status: {} || " | ||
+ "Payment Option Status: {} || " | ||
+ "Is Partial Payment: {} || " | ||
+ "Timestamp: {}", | ||
ppToPay.getOrganizationFiscalCode(), | ||
ppToPay.getIupd(), | ||
nav, | ||
ppToPay.getStatus(), | ||
poToPay.getStatus(), | ||
poToPay.getIsPartialPayment(), | ||
LocalDateTime.now()); |
Check failure
Code scanning / CodeQL
Log Injection High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 21 hours ago
To fix the log injection issue, we need to sanitize the nav
parameter before logging it. The best way to do this is to remove any potentially harmful characters from the nav
parameter, such as new-line characters, which can be used to forge log entries. We can use a utility method to sanitize the input by replacing or removing such characters.
- Create a utility method to sanitize the
nav
parameter by removing new-line characters and other potentially harmful characters. - Use this utility method to sanitize the
nav
parameter before logging it in theDebtPositionValidation
class.
-
Copy modified line R26 -
Copy modified lines R31-R37 -
Copy modified line R290 -
Copy modified line R302
@@ -25,2 +25,3 @@ | ||
import org.apache.logging.log4j.util.Strings; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
@@ -29,2 +30,9 @@ | ||
|
||
private static String sanitize(String input) { | ||
if (input == null) { | ||
return null; | ||
} | ||
return StringUtils.replaceChars(input, "\n\r", ""); | ||
} | ||
|
||
private static final String LOG_BASE_PARAMS_DETAIL = | ||
@@ -281,2 +289,3 @@ | ||
// log detailed information about this edge case | ||
String sanitizedNav = sanitize(nav); | ||
log.warn( | ||
@@ -292,3 +301,3 @@ | ||
ppToPay.getIupd(), | ||
nav, | ||
sanitizedNav, | ||
ppToPay.getStatus(), |
Quality Gate passedIssues Measures |
List of Changes
These changes are relevant in case the user pays the full amount for a payment position in presence of already paid installments/payment options:
Motivation and Context
This is a hotfix that was necessary to make the db coherent with what the user experiences during checkout. Before the fix, if the user paid using a NAV corresponding to the full amount due for the payment position but one or more installment/payment options were already paid for the same payment position, then the payment option corresponding to the full amount did not change status from PO_UNPAID to PAID, causing a discrepancy in the process. This happened because the checkout ended correctly up to the receipt generation for the user payment, but in the backend a HttpStatus.CONFLICT, "Existing related payment found" was being thrown.
How Has This Been Tested?
Tested locally with Postman making the following use case:
Screenshots (if appropriate):
Types of changes
Checklist: