You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
UCO-BS/src/main/java/com/mfsys/uco/service/UcoAccountService.java

263 lines
14 KiB
Java

package com.mfsys.uco.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mfsys.comm.constant.EurekaRegisteredMicroServicesURI;
import com.mfsys.comm.constant.SecurityURI;
import com.mfsys.uco.constants.UCOConstants;
import com.mfsys.uco.constants.UCOURI;
import com.mfsys.uco.dto.AccountInquiryResponse;
import com.mfsys.uco.dto.AddAccountRequestModel;
import com.mfsys.uco.dto.SignupStep3RequestModel;
import com.mfsys.uco.dto.webclientdto.AccountDetail;
import com.mfsys.uco.exception.AccountDoesntExistsException;
import com.mfsys.uco.exception.CustomerAccountOpeningNotAllowedException;
import com.mfsys.uco.exception.DepositAccountNotReadyException;
import com.mfsys.uco.exception.UserAlreadyRegisteredException;
import com.mfsys.uco.model.AccountId;
import com.mfsys.uco.model.CustomerProfile;
import com.mfsys.uco.model.UcoAccount;
import com.mfsys.uco.repository.CustomerProfileRepository;
import com.mfsys.uco.repository.UCOAccountRepository;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.time.LocalDate;
import java.util.*;
@Service
public class UcoAccountService {
ObjectMapper objectMapper;
private final CustomerProfileRepository customerProfileRepository;
private final UCOAccountRepository ucoAccountRepository;
private final CustomerProfileService customerProfileService;
@LoadBalanced
private final WebClient webClient;
private final WebClientDepositService webClientDeposit;
private final WebClientCrmService webClientCrmService;
public UcoAccountService(WebClient.Builder webClientBuilder,CustomerProfileRepository customerProfileRepository, UCOAccountRepository ucoAccountRepository, CustomerProfileService customerProfileService, WebClientDepositService webClientDeposit, WebClientCrmService webClientCrmService
,ObjectMapper objectMapper) {
this.webClient = webClientBuilder.baseUrl(EurekaRegisteredMicroServicesURI.SECURITY_SERVICE_LB).build();
this.customerProfileRepository = customerProfileRepository;
this.ucoAccountRepository = ucoAccountRepository;
this.customerProfileService = customerProfileService;
this.webClientDeposit = webClientDeposit;
this.webClientCrmService = webClientCrmService;
this.objectMapper = objectMapper;
}
public List<AccountInquiryResponse> fetchAccountTitile(String porOrgacode, String acntTypeCode, String acntTypeValue) {
CustomerProfile customerProfile = new CustomerProfile();
if (acntTypeCode.equals(UCOConstants.CMP_PHONE)) {
customerProfile = customerProfileRepository.findProfilesByMobilePhone(porOrgacode, acntTypeValue);
} else if (acntTypeCode.equals(UCOConstants.CMP_EMAIL)) {
customerProfile = customerProfileRepository.findCustomerProfileByCmpEmailAndPorOrgacode(porOrgacode, acntTypeValue);
}
if (Objects.isNull(customerProfile)) {
throw new AccountDoesntExistsException();
}
List<UcoAccount> ucoAccountList= ucoAccountRepository.findUcoAccountByCmpCustcode(porOrgacode, customerProfile.getCmpCustcode());
List<AccountInquiryResponse> accountInquiryResponseList = new ArrayList<>();
ucoAccountList.stream().forEach(account ->{;
accountInquiryResponseList.add( AccountInquiryResponse.builder().mbmBkmsnumber(account.getId().getMbmBkmsnumber())
.mbmBkmstitle(account.getMbmBkmstitle())
.pcrCurrshort(account.getPcrCurrshort())
.pcrCurrcode(account.getPcrCurrcode())
.pcrCurrdesc(account.getPcrCurrdesc())
.build());
});
return accountInquiryResponseList;
}
public Double fetchAccountBalance(String porOrgacode, String mbmBkmsNumber) {
return (Double) getIndvAccountDetails(porOrgacode, mbmBkmsNumber);
}
public Object getIndvAccountDetails(String porOrgacode, String mbmBkmsnumber) {
String url = UCOURI.GET_UCOACC_BALANCE + "?porOrgacode=" + porOrgacode + "&mbmBkmsnumber=" + mbmBkmsnumber;
return webClientDeposit.getUcoAccountBalance(url, porOrgacode);
}
public void onBoardCustomer(SignupStep3RequestModel signupStep3RequestModel) {
if (Objects.nonNull(customerProfileService.fetchCustcodeBasedOnEmail(signupStep3RequestModel.getPorOrgacode(), signupStep3RequestModel.getEmail()))) {
throw new UserAlreadyRegisteredException(null);
}
String porOrgacode = signupStep3RequestModel.getPorOrgacode();
Map cmpCustcodeReturn = (Map) webClientCrmService.onboardCustomer(
Map.of(
"CMP_FULLNAME", signupStep3RequestModel.getName(),
"PIT_IDENCODE", signupStep3RequestModel.getIdentificationType(),
"CIT_IDENVALUE", signupStep3RequestModel.getIdentificationNumber(),
"PAD_ADRSMOBPHONE", signupStep3RequestModel.getPhone(),
"POR_ORGACODE", signupStep3RequestModel.getPorOrgacode(),
"SUS_USERCODE", signupStep3RequestModel.getChannelCode(),
"PLC_LOCACODE", signupStep3RequestModel.getPlcLocacode(),
"DMP_PRODCODE", signupStep3RequestModel.getDmpProdcode()
),
UCOURI.CUSTOMER_ONBOARDING,
signupStep3RequestModel.getPorOrgacode()
);
String cmpCustcode = String.valueOf(cmpCustcodeReturn.get("cmpCustcode"));
System.out.println(cmpCustcode);
List<AccountDetail> depositAccounts = fetchDepositAccountWithRetry(porOrgacode, cmpCustcode);
if (depositAccounts.isEmpty()) {
throw new DepositAccountNotReadyException();
}
AccountDetail accountDetail = depositAccounts.get(0);
CustomerProfile customerProfile = CustomerProfile.builder().cmpCustcode(accountDetail.getCmpCustcode()).cmpEmail(signupStep3RequestModel.getEmail())
.cmpName(signupStep3RequestModel.getName()).cmpIsKycVerified(signupStep3RequestModel.isKycAdded())
.pitIdencode(signupStep3RequestModel.getIdentificationType()).pitIdenvalue(signupStep3RequestModel.getIdentificationNumber())
.cmpUserName(signupStep3RequestModel.getName())
.padAdrsmobphone(signupStep3RequestModel.getPhone())
.cmpUserName(signupStep3RequestModel.getUsername()).porOrgacode(signupStep3RequestModel.getPorOrgacode())
.build();
customerProfileRepository.save(customerProfile);
UcoAccount ucoAccount = UcoAccount.builder()
.id(new AccountId(accountDetail.getPorOrgacode(), accountDetail.getMbmBkmsnumber())) // Set the AccountId, assuming a method exists to create or retrieve it
.dmpProdcode(accountDetail.getDmpProdcode())
.mbmBkmstitle(accountDetail.getMbmBkmstitle())
.pcrCurrdesc(accountDetail.getPcrCurrdesc())
.cmpCustcode(accountDetail.getCmpCustcode())
.pcrCurrcode(accountDetail.getPcrCurrcode())
.pcrCurrshort(accountDetail.getPcrCurrshort())
.mbmBkmsclosed(accountDetail.isMbmBkmsclosed())
.mbmBkmsopendate(LocalDate.now())
.sgtLasttrandate(LocalDate.now())
.build();
ucoAccountRepository.save(ucoAccount);
updateCustomerApplication(Map.of("email",customerProfile.getCmpEmail(),"porOrgacode",porOrgacode));
}
private void updateCustomerApplication(Map<String, String> payload) {
webClient.post()
.uri(SecurityURI.UPDATE_CUSTOMER_APPLICATION)
.bodyValue(payload)
.retrieve()
.onStatus(
status -> status.is4xxClientError() || status.is5xxServerError(),
clientResponse -> Mono.error(new RuntimeException("Response has error status."))
)
.bodyToMono(String.class)
.block();
}
public List<AccountDetail> fetchdepositAccountFromCiihive(String porOrgacode, String cmpCustcode) {
String url = UCOURI.GET_CMP_UCOACCOUNTS + "?porOrgacode=" + porOrgacode + "&cmpCustcode=" + cmpCustcode;
List<Object> map = (List<Object>) webClientDeposit.getCmpUcoAccounts(url, porOrgacode);
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.convertValue(map, objectMapper.getTypeFactory().constructCollectionType(List.class, AccountDetail.class));
}
private List<AccountDetail> fetchDepositAccountWithRetry(String porOrgacode, String cmpCustcode) {
int maxAttempts = 3;
int delayMs = 2000;
List<AccountDetail> accounts = fetchdepositAccountFromCiihive(porOrgacode, cmpCustcode);
for (int attempt = 1; attempt < maxAttempts && accounts.isEmpty(); attempt++) {
try {
Thread.sleep(delayMs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
accounts = fetchdepositAccountFromCiihive(porOrgacode, cmpCustcode);
}
return accounts;
}
public Object fetchExchangeRate(String porOrgacode) {
String url = UCOURI.FETCH_EXCHANGE_RATE + "?porOrgacode=" + porOrgacode;
return webClientDeposit.fetchExchangeRate(url, porOrgacode);
}
public void addUcoAccount(AddAccountRequestModel addAccountRequestModel){
String porOrgacode = addAccountRequestModel.getPorOrgacode();
CustomerProfile customerProfile = customerProfileRepository.findCustomerProfileByCmpEmailAndPorOrgacode(porOrgacode,addAccountRequestModel.getEmail());
if(Objects.nonNull(customerProfile)){
List<UcoAccount> ucoAccountList = ucoAccountRepository.findUcoAccountByCmpCustcode(customerProfile.getPorOrgacode(),customerProfile.getCmpCustcode());
ucoAccountList.stream().forEach(acc->{
if(acc.getDmpProdcode().equals(addAccountRequestModel.getDmpProdcode())){
throw new CustomerAccountOpeningNotAllowedException();
}
});
}
String accountNumber = webClientDeposit.createUcoAccount(JsonToString(Map.of("payload",preparePayloadForAccount(customerProfile,addAccountRequestModel.getTitle()),
"uniqueConstraints",List.of(List.of(String.valueOf(addAccountRequestModel.getDmpProdcode()))))),UCOURI.UCO_CUSTOMER_ACCOUNT,porOrgacode);
saveCustomerAccountDetails(porOrgacode,customerProfile.getCmpCustcode(),accountNumber);
}
public void saveCustomerAccountDetails(String porOrgacode, String cmpCustcode,String accountNumber){
fetchdepositAccountFromCiihive(porOrgacode, cmpCustcode).stream().forEach(k -> {
if(k.getMbmBkmsnumber().equals(accountNumber)){
UcoAccount ucoAccount = UcoAccount.builder()
.id(new AccountId(k.getPorOrgacode(), k.getMbmBkmsnumber()))
.dmpProdcode(k.getDmpProdcode())
.mbmBkmstitle(k.getMbmBkmstitle())
.pcrCurrdesc(k.getPcrCurrdesc())
.cmpCustcode(k.getCmpCustcode())
.pcrCurrcode(k.getPcrCurrcode())
.pcrCurrshort(k.getPcrCurrshort())
.mbmBkmsclosed(k.isMbmBkmsclosed())
.mbmBkmsopendate(LocalDate.now())
.sgtLasttrandate(LocalDate.now())
.build();
ucoAccountRepository.save(ucoAccount);
}
});
}
public String preparePayloadForAccount(CustomerProfile customerProfile,String title){
Map<String,Object> jsonMap = new HashMap<>();
jsonMap.put("SUS_USERCODE", "01");
jsonMap.put("CMP_CUSTCODE",customerProfile.getCmpCustcode());
jsonMap.put("CMP_FULLNAME", title);
jsonMap.put("PLC_LOCACODE", "2003");
jsonMap.put("workFlowStage", "BN_WF_CP_AUTHORIZATION");
jsonMap.put("PCT_CSTYCODE", "I");
jsonMap.put("POR_ORGACODE", customerProfile.getPorOrgacode());
List<Map<String, Object>> workFlowLog = new ArrayList<>();
Map<String, Object> logEntry = new HashMap<>();
logEntry.put("susUsercode", "01");
logEntry.put("formId", "BN_WF_CP_AUTHORIZATION");
workFlowLog.add(logEntry);
jsonMap.put("workFlowLog", workFlowLog);
List<Map<String, Object>> bnCsItIdentifier = new ArrayList<>();
Map<String, Object> identifierEntry = new HashMap<>();
identifierEntry.put("CIT_IDENVALUE", customerProfile.getPitIdenvalue());
identifierEntry.put("PIT_PRIMARYIDENCODE", true);
identifierEntry.put("PIT_IDENCODE", customerProfile.getPitIdencode());
bnCsItIdentifier.add(identifierEntry);
jsonMap.put("BN_CS_IT_IDENTIFIER", bnCsItIdentifier);
jsonMap.put("@_CREATEUSER", "01");
List<Map<String, Object>> bnCsAdAddress = new ArrayList<>();
Map<String, Object> addressEntry = new HashMap<>();
addressEntry.put("PAD_ADRSCORRESPONDENCE", true);
addressEntry.put("PAD_ADRSMOBPHONE", customerProfile.getPadAdrsmobphone());
bnCsAdAddress.add(addressEntry);
jsonMap.put("BN_CS_AD_ADDRESS", customerProfile.getCmpAddress());
Map<String, Object> createdDateMap = new HashMap<>();
createdDateMap.put("$date", new Date());
jsonMap.put("@_CREATEDATE", createdDateMap);
return JsonToString(jsonMap);
}
public String JsonToString(Object jsonMap){
try {
return this.objectMapper.writeValueAsString(jsonMap);
} catch (JsonProcessingException var3) {
throw new RuntimeException(var3);
}
}
}