package com.abnamro.nl.bck.facade;
import com.abnamro.nl.bck.constants.BacikConstants;
import com.abnamro.nl.bck.dtos.BCKResponseDTO;
import com.abnamro.nl.bck.dtos.BCKResponseDTO.Level;
import com.abnamro.nl.bck.dtos.PaymentDetailsDTO;
import com.abnamro.nl.bck.entity.BacikPaymAdmin;
import com.abnamro.nl.bck.entity.BacikPaymAgtDet;
import com.abnamro.nl.bck.entity.BacikPaymAgtPstlAdr;
import com.abnamro.nl.bck.exceptions.BacikApplicationException;
import com.abnamro.nl.bck.repository.BacikPaymAdminRepo;
import com.abnamro.nl.bck.repository.BacikPaymAgtDetRepo;
import com.abnamro.nl.bck.repository.BacikPaymAgtPstlAdrRepo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
/**
* This class is used to create success response.
* for any api,We can create appropriate method
* for each api based on required message.
*/
@Component
public class SuccessResponseCreatorNL {
/**
* bacikPaymAdminRepo
*/
@Autowired
private BacikPaymAdminRepo bacikPaymAdminRepo;
/**
* bacikPaymAgtPstlAdrRepo
*/
@Autowired
public BacikPaymAgtPstlAdrRepo bacikPaymAgtPstlAdrRepo;
/**
* bacikPaymAgtDetRepo
*/
@Autowired
public BacikPaymAgtDetRepo bacikPaymAgtDetRepo;
private final static String DEFAULTSTRING = "DEFAULT";
private final static String COUNTER = "C";
private final static String SUCCESS = "200";
private final static String MESSAGE = " is ingevoerd and verzonden voor verwerking. \n\n U kunt een printout verstrekken aan de klant.";
private final static String MESSAGE_SENT_FOR_UPDATE_LAST_PART = " is niet geautoriseerd en bataling is verzonden voor bewerking.";
private final static String MESSAGE_REJECTED_LAST_PART = " is afgewezen en betaling zal niet worden uitgevoerd.";
private final static String MESSAGE_FIRST_AUTH = " en wordt aangeboden voor tweede autorisatie";
private final static String MESSAGE_SECOND_AUTH = " en wordt aangeboden voor speciale autorisatie.";
private final static String MESSAGE_FINAL_AUTH = " en wordt aangeboden voor verdere verwerking.";
private final static String MESSAGE_APPROVED_LAST_PART = " is geautoriseerd.";
private final static String MESSAGE_CROSS_BORDER_TRANSFER_FIRST_PART = " De buitenland overboeking van ";
/**
* This method is used to create response for create api
* based on transfer via option selected.
*
* @param paymentDetailsDTO complex object used to get values from dto.
* @return BCKResponseDTO as a response object.
* @throws BacikApplicationException complex object application exception thrown by application.
*/
public BCKResponseDTO createApiResponse(PaymentDetailsDTO paymentDetailsDTO) throws BacikApplicationException {
BCKResponseDTO bckResponseDTO = new BCKResponseDTO();
if (Objects.nonNull(paymentDetailsDTO)) {
switch (paymentDetailsDTO.getSourceId()) {
case COUNTER:
if(!paymentDetailsDTO.getDebtorAccountDetailsDTO().isBranchAccountSelected())
bckResponseDTO = this.generateMessage(paymentDetailsDTO, COUNTER);
else
bckResponseDTO = this.generateMessage(paymentDetailsDTO, DEFAULTSTRING);
break;
default:
bckResponseDTO = this.generateMessage(paymentDetailsDTO, DEFAULTSTRING);
}
}
return bckResponseDTO;
}
/**
* This method will create success response for
* validate api
*
* @return BCKResponseDTO complex object
*/
public BCKResponseDTO successApiResponse() {
BCKResponseDTO bckResponseDTO = new BCKResponseDTO();
bckResponseDTO.setStatus(SUCCESS);
bckResponseDTO.setStatusMessage("SUCCESS");
bckResponseDTO.setLevel(Level.SUCCESS);
return bckResponseDTO;
}
/**
* This method will create success response for
* validate api response
*
* @param boNum integer bonumber passed to validate
* @return BCKResponseDTO complex object
*/
public BCKResponseDTO validateApiResponse(int boNum) {
BCKResponseDTO bckResponseDTO = new BCKResponseDTO();
bckResponseDTO.setStatus(SUCCESS);
bckResponseDTO.setStatusMessage(Integer.toString(boNum));
bckResponseDTO.setLevel(Level.SUCCESS);
return bckResponseDTO;
}
/**
* This method is used to generate success message for Create api.
*
* @param paymentDetailsDTO PaymentDetailsDTO paymentDetailsDTO
* @return BCKResponseDTO a complex object to be returned to UI.
* @throws BacikApplicationException application exception thrown by application.
*/
private BCKResponseDTO generateMessage(PaymentDetailsDTO paymentDetailsDTO, String transferVia) throws BacikApplicationException {
BCKResponseDTO bckResponseDTO = new BCKResponseDTO();
StringBuffer message = new StringBuffer();
if (!StringUtils.equals(transferVia, COUNTER)) {
message.append("De referentie van deze overboeking is ")
.append(paymentDetailsDTO.getUtri())
.append(". U moet dit nummer kopiëren op het brondocument.");
} else {
message.append(MESSAGE_CROSS_BORDER_TRANSFER_FIRST_PART)
.append(paymentDetailsDTO.getTxCrncy())
.append(" ")
.append(formattedAmount(paymentDetailsDTO.getTxAmt()));
if(!StringUtils.isEmpty(paymentDetailsDTO.getCdtrNm())) {
message.append(" aan ")
.append(paymentDetailsDTO.getCdtrNm());
}
message = generateCounterMessage(paymentDetailsDTO, message);
}
bckResponseDTO.setStatusMessage(message.toString());
bckResponseDTO.setStatus(SUCCESS);
bckResponseDTO.setLevel(Level.SUCCESS);
bckResponseDTO.setRefId(paymentDetailsDTO.getPaymId().toString());
return bckResponseDTO;
}
/**
* This method is used to generate success message for Update and Reject auth request api.
*
* @param bacikPaymAdmin BacikPaymAdmin
* @param transactionReference String
* @return BCKResponseDTO a complex object to be returned to UI.
*/
public BCKResponseDTO generateUpdateResponseMessage(BacikPaymAdmin bacikPaymAdmin, String transactionReference) {
BCKResponseDTO bckResponseDTO = new BCKResponseDTO();
StringBuffer message = new StringBuffer();
message.append(MESSAGE_CROSS_BORDER_TRANSFER_FIRST_PART)
.append(bacikPaymAdmin.getTxCrncy())
.append(" ")
.append(formattedAmount(bacikPaymAdmin.getTxAmt()));
if(!StringUtils.isEmpty(bacikPaymAdmin.getCdtrNm())) {
message.append(" to ")
.append(bacikPaymAdmin.getCdtrNm());
}
message = generatePostalAddress(transactionReference, message);
if (2 == bacikPaymAdmin.getGapStatus()) {
message.append(MESSAGE_SENT_FOR_UPDATE_LAST_PART);
} else if (3 == bacikPaymAdmin.getGapStatus()) {
message.append(MESSAGE_REJECTED_LAST_PART);
}
bckResponseDTO.setStatusMessage(message.toString());
bckResponseDTO.setStatus(SUCCESS);
bckResponseDTO.setLevel(Level.SUCCESS);
return bckResponseDTO;
}
/**
* This method is to generate postal address for response message
*
* @param transactionReference String
* @param message StringBuffer
* @return StringBuffer message
*/
public StringBuffer generatePostalAddress(String transactionReference, StringBuffer message) {
StringBuffer postalCode = new StringBuffer();
ArrayList addressList = new ArrayList<String>();
BacikPaymAgtPstlAdr creditorPostalAddress = bacikPaymAgtPstlAdrRepo.findByPaymIdAndPrtyRole(Timestamp.valueOf(transactionReference), BacikConstants.CDTR);
BacikPaymAgtDet creditorDetails = bacikPaymAgtDetRepo.findByPaymIdAndPrtyRole(Timestamp.valueOf(transactionReference), BacikConstants.CDTR);
if (null != creditorPostalAddress) {
addressList.add(creditorPostalAddress.getStrtName());
addressList.add(creditorPostalAddress.getBldgNb());
addressList.add(creditorPostalAddress.getFlrNb());
addressList.add(creditorPostalAddress.getTwnNm());
addressList.add(creditorPostalAddress.getPstCd());
addressList.add(creditorPostalAddress.getCtrySubDvsn());
}
if (null != creditorDetails) {
addressList.add(" in " + creditorDetails.getCtryResidence());
}
addressList.forEach(potalCodeElement -> {
if (potalCodeElement != null && !potalCodeElement.toString().isEmpty()) {
postalCode.append(potalCodeElement)
.append(",");
}
});
if (postalCode.length() != 0) {
message.append(",")
.append(removeLastCharOptional(postalCode.toString()));
}
return message;
}
/**
* This method generates resposne for BO Number screen.
*
* @param bacikPaymAdmin updated admin object
* @return Strig message that will be sent to UI
* @throws BacikApplicationException application exception
*/
public BCKResponseDTO generateBoNumberResponse(BacikPaymAdmin bacikPaymAdmin) throws BacikApplicationException {
StringBuffer msgString = new StringBuffer();
BCKResponseDTO bckResponseDTO = new BCKResponseDTO();
msgString.append(MESSAGE_CROSS_BORDER_TRANSFER_FIRST_PART)
.append(bacikPaymAdmin.getTxCrncy())
.append(" ")
.append(formattedAmount(bacikPaymAdmin.getTxAmt()));
if(!StringUtils.isEmpty(bacikPaymAdmin.getCdtrNm())) {
msgString.append(" to ")
.append(bacikPaymAdmin.getCdtrNm());
}
msgString = generatePostalAddress(bacikPaymAdmin.getPaymId().toString(), msgString);
msgString.append(" is authorized ");
//This block will change message part based on auth step counter level.
switch (bacikPaymAdmin.getAuthStepCnt()) {
case 2:
msgString.append(MESSAGE_FIRST_AUTH);
break;
case 3:
msgString.append(StringUtils.isEmpty(bacikPaymAdmin.getSplAuthUser()) ?
MESSAGE_SECOND_AUTH :
MESSAGE_FINAL_AUTH);
break;
default:
break;
}
bckResponseDTO.setStatusMessage(msgString.toString());
bckResponseDTO.setStatus(SUCCESS);
bckResponseDTO.setLevel(Level.SUCCESS);
return bckResponseDTO;
}
/**
* This method will generate counter message
*
* @param paymentDetailsDTO details object that contain data
* @param message string buffer object that will contain message
* @return StringBuffer having message
*/
private StringBuffer generateCounterMessage(PaymentDetailsDTO paymentDetailsDTO, StringBuffer message) {
StringBuffer postalCode = new StringBuffer();
ArrayList addressList = new ArrayList<String>();
addressList.add(paymentDetailsDTO.getCreditorDetailsDTO().getPostalAddressDTO().getStrtName());
addressList.add(paymentDetailsDTO.getCreditorDetailsDTO().getPostalAddressDTO().getBldgNb());
addressList.add(paymentDetailsDTO.getCreditorDetailsDTO().getPostalAddressDTO().getFlrNb());
addressList.add(paymentDetailsDTO.getCreditorDetailsDTO().getPostalAddressDTO().getTwnNm());
addressList.add(paymentDetailsDTO.getCreditorDetailsDTO().getPostalAddressDTO().getPstCd());
addressList.add(paymentDetailsDTO.getCreditorDetailsDTO().getPostalAddressDTO().getCtrySubDvsn());
addressList.add("in " + paymentDetailsDTO.getCreditorDetailsDTO().getPostalAddressDTO().getCtryResidence());
addressList.forEach(potalCodeElement -> {
if (potalCodeElement != null && !potalCodeElement.toString().isEmpty()) {
postalCode.append(potalCodeElement)
.append(",");
}
});
if (postalCode.length() != 0) {
message.append(",")
.append(removeLastCharOptional(postalCode.toString()))
.append(MESSAGE);
} else {
message.append(MESSAGE);
}
return message;
}
/**
* Remove last character from message
* since it contains comma
*
* @param s String toe xclude last char
* @return excluded last characater
*/
public static String removeLastCharOptional(String s) {
return Optional.ofNullable(s)
.filter(str -> str.length() != 0)
.map(str -> str.substring(0, str.length() - 1))
.orElse(s);
}
/**
* This method generates resposne for Auth screen.
*
* @param bacikPaymAdmin BacikPaymAdmin
* @param transactionReference String
* @return BCKResponseDTO response dto that will contain response message
*/
public BCKResponseDTO approveApiResponse(BacikPaymAdmin bacikPaymAdmin, String transactionReference) {
BCKResponseDTO bckResponseDTO = new BCKResponseDTO();
Integer gapStatus = bacikPaymAdmin.getGapStatus();
if(gapStatus != 4) {
bckResponseDTO.setStatusMessage("False");
} else {
StringBuffer message = new StringBuffer();
message.append(MESSAGE_CROSS_BORDER_TRANSFER_FIRST_PART)
.append(bacikPaymAdmin.getTxCrncy())
.append(" ")
.append(formattedAmount(bacikPaymAdmin.getTxAmt()));
if(!StringUtils.isEmpty(bacikPaymAdmin.getCdtrNm())) {
message.append(" aan ")
.append(bacikPaymAdmin.getCdtrNm());
}
message = generatePostalAddress(transactionReference, message);
message.append(MESSAGE_APPROVED_LAST_PART);
bckResponseDTO.setStatusMessage(message.toString());
}
bckResponseDTO.setStatus(SUCCESS);
bckResponseDTO.setLevel(Level.SUCCESS);
return bckResponseDTO;
}
/**
* Method to format amount
*
* @param amount String
* @return String
*/
public String formattedAmount(String amount) {
NumberFormat currecnyFormat = NumberFormat.getCurrencyInstance(new Locale("nl", "NL"));
String currecny = currecnyFormat.format(Double.valueOf(amount));
String formattedAmount = currecny.replace(currecnyFormat.getCurrency()
.getSymbol(new Locale("nl", "NL")), "");
return formattedAmount;
}
}