Skip to content

Commit

Permalink
[PIDM-35] feat: Improve Transfer update iban method loop
Browse files Browse the repository at this point in the history
  • Loading branch information
svariant committed Jan 28, 2025
1 parent 38595f5 commit cc2e142
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ ResponseEntity<PaymentOptionModelResponse> updateNotificationFee(
schema = @Schema(implementation = ProblemJson.class)))
})
@PostMapping(
value = "/organizations/{organizationfiscalcode}/transfers/iban/update",
value = "/organizations/{organizationfiscalcode}/transfers/update/iban",
produces = {MediaType.TEXT_PLAIN_VALUE},
consumes = {MediaType.APPLICATION_JSON_VALUE})
ResponseEntity<String> updateTransferIbanMassive(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package it.gov.pagopa.debtposition.model.payments;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotNull;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UpdateTransferIbanMassiveModel {

@NotNull
@JsonProperty("old_iban")
private String oldIban;
@NotNull
@JsonProperty("new_iban")
private String newIban;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import it.gov.pagopa.debtposition.entity.PaymentOption;

import it.gov.pagopa.debtposition.entity.PaymentPosition;
import it.gov.pagopa.debtposition.model.enumeration.PaymentOptionStatus;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
Expand All @@ -25,6 +26,6 @@ public interface PaymentOptionRepository extends JpaRepository<PaymentOption, Lo
Optional<PaymentOption> findByOrganizationFiscalCodeAndIuvOrOrganizationFiscalCodeAndNav(String organizationFiscalCodeIuv, String iuv, String organizationFiscalCodeNav, String nav);

// Derived Query - using method naming convention - get all PaymentOption by payment_position_id and in the specified statuses
List<PaymentOption> findByPaymentPositionIdAndStatusIn(Long paymentPositionId, List<PaymentOptionStatus> statusList);
List<PaymentOption> findByPaymentPositionInAndStatusIn(List<PaymentPosition> paymentPositionList, List<PaymentOptionStatus> statusList);
}

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package it.gov.pagopa.debtposition.repository;

import it.gov.pagopa.debtposition.entity.PaymentOption;
import it.gov.pagopa.debtposition.entity.Transfer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

Expand All @@ -14,12 +14,9 @@

@Repository
public interface TransferRepository extends JpaRepository<Transfer, Long>,
JpaSpecificationExecutor<Transfer>, PagingAndSortingRepository<Transfer, Long> {

// Derived Query - using method naming convention - get all Transfer by paymentOptionId
List<Transfer> findByPaymentOptionId(Long paymentOptionId);
JpaSpecificationExecutor<Transfer> {

@Modifying
@Query("update Transfer tr set tr.newIban = :newIban, tr.lastUpdatedDate = :currentDate where tr.payment_option_id=:paymentOptionId and tr.iban=:oldIban")
int updateTransferIban(@Param(value="paymentOptionId") Long paymentOptionId, @Param(value = "oldIban") String oldIban, @Param(value = "newIban") String newIban, @Param(value = "currentDate") LocalDateTime currentDate);
@Query("update Transfer tr set tr.iban = :newIban, tr.lastUpdatedDate = :currentDate where tr.paymentOption in (:paymentOptionList) and tr.iban=:oldIban")
int updateTransferIban(@Param(value="paymentOptionList") List<PaymentOption> paymentOptionList, @Param(value = "oldIban") String oldIban, @Param(value = "newIban") String newIban, @Param(value = "currentDate") LocalDateTime currentDate);
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,5 @@
package it.gov.pagopa.debtposition.service.payments;

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.Optional;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

import it.gov.pagopa.debtposition.repository.TransferRepository;
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;

import feign.FeignException;
import it.gov.pagopa.debtposition.client.NodeClient;
import it.gov.pagopa.debtposition.entity.PaymentOption;
Expand All @@ -35,8 +17,24 @@
import it.gov.pagopa.debtposition.model.payments.PaymentOptionModel;
import it.gov.pagopa.debtposition.repository.PaymentOptionRepository;
import it.gov.pagopa.debtposition.repository.PaymentPositionRepository;
import it.gov.pagopa.debtposition.repository.TransferRepository;
import it.gov.pagopa.debtposition.util.DebtPositionValidation;
import lombok.extern.slf4j.Slf4j;
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;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
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.Optional;


@Service
Expand All @@ -57,7 +55,6 @@ public PaymentsService(PaymentPositionRepository paymentPositionRepository, Paym
}



@Value("${nav.aux.digit}")
private String auxDigit;

Expand Down Expand Up @@ -85,7 +82,7 @@ public PaymentOption getPaymentOptionByNAV(@NotBlank String organizationFiscalCo
public PaymentOption pay(@NotBlank String organizationFiscalCode,
@NotBlank String nav, @NotNull @Valid PaymentOptionModel paymentOptionModel) {
Optional<PaymentPosition> ppToPay = paymentPositionRepository.
findByPaymentOptionOrganizationFiscalCodeAndPaymentOptionIuvOrPaymentOptionOrganizationFiscalCodeAndPaymentOptionNav(organizationFiscalCode, nav, organizationFiscalCode, nav);
findByPaymentOptionOrganizationFiscalCodeAndPaymentOptionIuvOrPaymentOptionOrganizationFiscalCodeAndPaymentOptionNav(organizationFiscalCode, nav, organizationFiscalCode, nav);

if (ppToPay.isEmpty()) {
throw new AppException(AppError.PAYMENT_OPTION_NOT_FOUND, organizationFiscalCode, nav);
Expand Down Expand Up @@ -120,7 +117,7 @@ public Transfer report(@NotBlank String organizationFiscalCode,
public PaymentOption updateNotificationFee(@NotBlank String organizationFiscalCode, @NotBlank String nav, Long notificationFeeAmount) {

// Check if exists a payment option with the passed IUV related to the organization
// TODO #naviuv: temporary regression management: search by nav or iuv
// TODO #naviuv: temporary regression management: search by nav or iuv
Optional<PaymentOption> paymentOptionOpt = paymentOptionRepository.findByOrganizationFiscalCodeAndIuvOrOrganizationFiscalCodeAndNav(organizationFiscalCode, nav, organizationFiscalCode, nav);
if (paymentOptionOpt.isEmpty()) {
throw new AppException(AppError.PAYMENT_OPTION_NOT_FOUND, organizationFiscalCode, nav);
Expand All @@ -130,33 +127,32 @@ public PaymentOption updateNotificationFee(@NotBlank String organizationFiscalCo
if (!PaymentOptionStatus.PO_UNPAID.equals(paymentOption.getStatus())) {
throw new AppException(AppError.PAYMENT_OPTION_NOTIFICATION_FEE_UPDATE_NOT_UPDATABLE, organizationFiscalCode, nav);
}

// Executing the amount updating with the inserted notification fee
updateAmountsWithNotificationFee(paymentOption, organizationFiscalCode, notificationFeeAmount);

// Executes a call to the node's checkPosition API to see if there is a payment in progress
try {
// TODO #naviuv: temporary regression management: search by nav or iuv --> possible double call to the node
// TODO #naviuv: temporary regression management: search by nav or iuv --> possible double call to the node
// 1. first call attempt is with the nav variable valued as iuv (auxDigit added)
NodePosition position = NodePosition.builder().fiscalCode(organizationFiscalCode).noticeNumber(auxDigit+nav).build();
NodeCheckPositionResponse chkPositionRes =
nodeClient.getCheckPosition(NodeCheckPositionModel.builder().positionslist(Collections.singletonList(position)).build());
paymentOption.setPaymentInProgress("OK".equalsIgnoreCase(chkPositionRes.getOutcome())?Boolean.FALSE:Boolean.TRUE);
NodePosition position = NodePosition.builder().fiscalCode(organizationFiscalCode).noticeNumber(auxDigit + nav).build();
NodeCheckPositionResponse chkPositionRes =
nodeClient.getCheckPosition(NodeCheckPositionModel.builder().positionslist(Collections.singletonList(position)).build());
paymentOption.setPaymentInProgress("OK".equalsIgnoreCase(chkPositionRes.getOutcome()) ? Boolean.FALSE : Boolean.TRUE);
} catch (FeignException.BadRequest e) {
// 2. if the first call fails with a bad request error --> try with a nav call
NodePosition position = NodePosition.builder().fiscalCode(organizationFiscalCode).noticeNumber(nav).build();
try {
NodeCheckPositionResponse chkPositionRes =
nodeClient.getCheckPosition(NodeCheckPositionModel.builder().positionslist(Collections.singletonList(position)).build());
paymentOption.setPaymentInProgress("OK".equalsIgnoreCase(chkPositionRes.getOutcome())?Boolean.FALSE:Boolean.TRUE);
} catch (Exception ex) {
log.error("Error checking the position on the node for PO with fiscalCode " + organizationFiscalCode + " and noticeNumber " + "("+auxDigit+")"+nav, ex);
// 2. if the first call fails with a bad request error --> try with a nav call
NodePosition position = NodePosition.builder().fiscalCode(organizationFiscalCode).noticeNumber(nav).build();
try {
NodeCheckPositionResponse chkPositionRes =
nodeClient.getCheckPosition(NodeCheckPositionModel.builder().positionslist(Collections.singletonList(position)).build());
paymentOption.setPaymentInProgress("OK".equalsIgnoreCase(chkPositionRes.getOutcome()) ? Boolean.FALSE : Boolean.TRUE);
} catch (Exception ex) {
log.error("Error checking the position on the node for PO with fiscalCode " + organizationFiscalCode + " and noticeNumber " + "(" + auxDigit + ")" + nav, ex);
// By business rules it is expected to treat the error as if the node had responded KO
paymentOption.setPaymentInProgress(Boolean.TRUE);
}
}
catch (Exception e) {
log.error("Error checking the position on the node for PO with fiscalCode " + organizationFiscalCode + " and noticeNumber " + "("+auxDigit+")"+nav, e);
} catch (Exception e) {
log.error("Error checking the position on the node for PO with fiscalCode " + organizationFiscalCode + " and noticeNumber " + "(" + auxDigit + ")" + nav, e);
// By business rules it is expected to treat the error as if the node had responded KO
paymentOption.setPaymentInProgress(Boolean.TRUE);
}
Expand Down Expand Up @@ -321,23 +317,19 @@ private void setPaymentPositionStatus(PaymentPosition pp) {
}

// Update all Organization's IBANs on Transfer of payable PaymentPosition
@Transactional
public int updateTransferIbanMassive(String organizationFiscalCode, String oldIban, String newIban) {
int numberOfUpdates = 0;
// Retrieve all payment_position with organization_fiscal_code AND in status (DRAFT or PUBLISHED or VALID or PARTIALLY_PAID)
List<PaymentPosition> ppToUpdate = paymentPositionRepository.findByOrganizationFiscalCodeAndStatusIn(organizationFiscalCode, List.of(DebtPositionStatus.DRAFT, DebtPositionStatus.PUBLISHED, DebtPositionStatus.VALID, DebtPositionStatus.PARTIALLY_PAID));

if (ppToUpdate.isEmpty()) {
throw new AppException(AppError.DEBT_POSITION_IN_UPDATABLE_STATE_NOT_FOUND, organizationFiscalCode);
}
for (PaymentPosition pp : ppToUpdate) {
// Retrieve all payment_option with payment_position_id AND in status PO_UNPAID
List<PaymentOption> poToUpdate = paymentOptionRepository.findByPaymentPositionIdAndStatusIn(pp.getId(), List.of(PaymentOptionStatus.PO_UNPAID));
// Retrieve all payment_option with payment_position_id AND in status PO_UNPAID
List<PaymentOption> poToUpdate = paymentOptionRepository.findByPaymentPositionInAndStatusIn(ppToUpdate, List.of(PaymentOptionStatus.PO_UNPAID));

for (PaymentOption po : poToUpdate) {
// Update all Transfers that have the specified payment_option_id and oldIban as IBAN
numberOfUpdates += transferRepository.updateTransferIban(po.getId(), oldIban, newIban, LocalDateTime.now(ZoneOffset.UTC));
}
}
// Update all Transfers that have the specified payment_option_id and oldIban as IBAN
numberOfUpdates += transferRepository.updateTransferIban(poToUpdate, oldIban, newIban, LocalDateTime.now(ZoneOffset.UTC));

return numberOfUpdates;
}
Expand Down

0 comments on commit cc2e142

Please sign in to comment.