commit create and verify tranpin
parent
a3d69d66eb
commit
6f95055761
@ -0,0 +1,18 @@
|
||||
package com.mfsys.uco.config;
|
||||
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@Configuration
|
||||
public class WebClientconfiguration {
|
||||
|
||||
@LoadBalanced
|
||||
@Bean
|
||||
public WebClient.Builder loadBalancedWebClientBuilder() {
|
||||
return WebClient.builder();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.mfsys.uco.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class CreateTransactionPinRequest {
|
||||
private String newTransPincode;
|
||||
private String channelCode;
|
||||
private String pctCstycode;
|
||||
private String porOrgacode;
|
||||
private String cmpCustcode;
|
||||
private boolean isOtpRequired;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.mfsys.uco.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OTPRequest {
|
||||
private boolean isOtpRequired;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String channelCode;
|
||||
private String porOrgacode;
|
||||
private String username;
|
||||
private String pinType;
|
||||
private String subject;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.mfsys.uco.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class VerifyPinRequest {
|
||||
String channelCode;
|
||||
String pctCstycode;
|
||||
String porOrgacode;
|
||||
String cmpCustcode;
|
||||
String email;
|
||||
String obpPincode;
|
||||
String pinType;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
package com.mfsys.uco.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class CustomerProfileId implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String porOrgacode;
|
||||
private String cmpCustcode;
|
||||
|
||||
public String getPorOrgacode() {
|
||||
return porOrgacode;
|
||||
}
|
||||
|
||||
public void setPorOrgacode(String porOrgacode) {
|
||||
this.porOrgacode = porOrgacode;
|
||||
}
|
||||
|
||||
public String getCmpCustcode() {
|
||||
return cmpCustcode;
|
||||
}
|
||||
|
||||
public void setCmpCustcode(String cmpCustcode) {
|
||||
this.cmpCustcode = cmpCustcode;
|
||||
}
|
||||
|
||||
public CustomerProfileId() {
|
||||
}
|
||||
|
||||
public CustomerProfileId(String porOrgacode, String cmpCustcode) {
|
||||
this.porOrgacode = porOrgacode;
|
||||
this.cmpCustcode = cmpCustcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cmpCustcode == null) ? 0 : cmpCustcode.hashCode());
|
||||
result = prime * result + ((porOrgacode == null) ? 0 : porOrgacode.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CustomerProfileId other = (CustomerProfileId) obj;
|
||||
if (cmpCustcode == null) {
|
||||
if (other.cmpCustcode != null)
|
||||
return false;
|
||||
} else if (!cmpCustcode.equals(other.cmpCustcode))
|
||||
return false;
|
||||
if (porOrgacode == null) {
|
||||
if (other.porOrgacode != null)
|
||||
return false;
|
||||
} else if (!porOrgacode.equals(other.porOrgacode))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package com.mfsys.uco.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.mfsys.comm.util.FieldNameLength;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity(name = "DG_PN_PIN")
|
||||
@Table(name = "DG_PN_PIN")
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class Pin {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "PINSERIAL", nullable = false, updatable = false, columnDefinition = FieldNameLength.BIGINT)
|
||||
private Long pinserial;
|
||||
|
||||
@Column(name = "POR_ORGACODE", nullable = false, updatable = false, columnDefinition = FieldNameLength.POR_ORGACODE)
|
||||
private String porOrgacode;
|
||||
|
||||
@Column(name = "username", nullable = false, updatable = false, columnDefinition = FieldNameLength.USER_NAME)
|
||||
private String userName;
|
||||
|
||||
@Column(name = "CHANNEL_CODE", nullable = false, updatable = false, columnDefinition = FieldNameLength.CHANNEL_CODE)
|
||||
private String channelCode;
|
||||
|
||||
@Column(name = "PINTYPE", nullable = false, updatable = false, columnDefinition = FieldNameLength.CODE_10)
|
||||
private String pintype;
|
||||
|
||||
@Column(name = "PINLENGTH", nullable = false, updatable = false, columnDefinition = FieldNameLength.PIN_LENGTH)
|
||||
private int pinlength;
|
||||
|
||||
@Column(name = "PINCODE", nullable = false, updatable = true, columnDefinition = FieldNameLength.PIN_VALUE)
|
||||
private String pincode;
|
||||
|
||||
@Column(name = "PIN_CREATEDATE", nullable = false, updatable = true, columnDefinition = FieldNameLength.DATETIME)
|
||||
private LocalDateTime pinCreatedate;
|
||||
|
||||
@Column(name = "PIN_EXPIRYDATE", nullable = false, updatable = true, columnDefinition = FieldNameLength.DATETIME)
|
||||
private LocalDateTime pinExpirydate;
|
||||
|
||||
@Column(name = "PINSTATUS", nullable = false, updatable = true, columnDefinition = FieldNameLength.CODE_20)
|
||||
private String pinstatus;
|
||||
|
||||
@Column(name = "PIN_VALIDATIONDATE", nullable = true, updatable = true, columnDefinition = FieldNameLength.DATETIME)
|
||||
private LocalDateTime pinValidationdate;
|
||||
|
||||
@JsonIgnore
|
||||
@Column(name = "Version", nullable = false, updatable = true, columnDefinition = FieldNameLength.INT)
|
||||
@Version
|
||||
private int version;
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package com.mfsys.uco.repository;
|
||||
|
||||
import com.mfsys.uco.model.CustomerProfile;
|
||||
import com.mfsys.uco.model.CustomerProfileId;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CustomerProfileRepository extends JpaRepository<CustomerProfile, CustomerProfileId> {
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.mfsys.uco.repository;
|
||||
|
||||
import com.mfsys.uco.model.Pin;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface PinRepository extends JpaRepository<Pin, Long> {
|
||||
@Query("SELECT p FROM DG_PN_PIN p WHERE p.userName = :username AND p.pinstatus = 'Unverified' AND p.pinExpirydate > CURRENT_TIMESTAMP ORDER BY p.pinserial DESC LIMIT 1")
|
||||
Optional<Pin> findLatestActiveOtpByUserName(String username);
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.mfsys.uco.service;
|
||||
|
||||
import com.mfsys.comm.commonservices.OtpService;
|
||||
import com.mfsys.comm.constant.EurekaRegisteredMicroServicesURI;
|
||||
import com.mfsys.comm.exception.InvalidOTPException;
|
||||
import com.mfsys.uco.dto.OTPRequest;
|
||||
import com.mfsys.uco.model.Pin;
|
||||
import com.mfsys.uco.repository.PinRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class NotificationService {
|
||||
@LoadBalanced
|
||||
private final WebClient webClient;
|
||||
private final OtpService otpService;
|
||||
private final PinRepository pinRepository;
|
||||
|
||||
public NotificationService(WebClient.Builder webClientBuilder, OtpService otpService, PinRepository pinRepository) {
|
||||
this.webClient = webClientBuilder.baseUrl(EurekaRegisteredMicroServicesURI.NOTIFICATION_SERVICE_LB).build();
|
||||
this.otpService = otpService;
|
||||
this.pinRepository = pinRepository;
|
||||
}
|
||||
|
||||
public Mono<String> sendOtp(OTPRequest otpRequest) {
|
||||
String otp = otpRequest.isOtpRequired() ? otpService.generateOtp() : "123456";
|
||||
Pin pin = new Pin();
|
||||
final LocalDateTime createDate = LocalDateTime.now();
|
||||
final LocalDateTime expiryDate = LocalDateTime.now().plusMinutes(5);
|
||||
pin.setPinCreatedate(createDate);
|
||||
pin.setPinExpirydate(expiryDate);
|
||||
pin.setChannelCode(otpRequest.getChannelCode());
|
||||
pin.setPintype(otpRequest.getPinType());
|
||||
pin.setPincode(otp);
|
||||
pin.setPorOrgacode(otpRequest.getPorOrgacode());
|
||||
pin.setVersion(1);
|
||||
pin.setPinlength(6);
|
||||
pin.setPinstatus("Unverified");
|
||||
pin.setUserName(otpRequest.getEmail());
|
||||
pinRepository.save(pin);
|
||||
webClient.post().uri("/notification/otp/email").bodyValue(Map.of("email", otpRequest.getEmail(), "subject", otpRequest.getSubject(), "otp", otp, "userName", otpRequest.getUsername())).retrieve()
|
||||
.onStatus(status -> status.is4xxClientError() || status.is5xxServerError(), clientResponse
|
||||
-> Mono.error(new RuntimeException("Response has error status."))).bodyToMono(String.class).block();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void verifyOtp(String porOrgacode, String email, String obpPincode) {
|
||||
Optional<Pin> pin = pinRepository.findLatestActiveOtpByUserName(email);
|
||||
if (pin.isPresent() && pin.get().getPincode().equals(obpPincode) && pin.get().getPorOrgacode().equals(porOrgacode)) {
|
||||
pin.get().setPinstatus("VERIFIED");
|
||||
pinRepository.save(pin.get());
|
||||
return;
|
||||
}
|
||||
throw new InvalidOTPException(porOrgacode);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package com.mfsys.uco.service;
|
||||
|
||||
import com.mfsys.uco.dto.CreateTransactionPinRequest;
|
||||
import com.mfsys.uco.dto.OTPRequest;
|
||||
import com.mfsys.uco.dto.VerifyPinRequest;
|
||||
import com.mfsys.uco.model.CustomerProfile;
|
||||
import com.mfsys.uco.model.CustomerProfileId;
|
||||
import com.mfsys.uco.repository.CustomerProfileRepository;
|
||||
import com.mfsys.uco.repository.PinRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TransactionPinService {
|
||||
|
||||
private final CustomerProfileRepository customerProfileRepository;
|
||||
private final NotificationService notificationService;
|
||||
|
||||
public void createTransactionPin(CreateTransactionPinRequest request) {
|
||||
CustomerProfile profile = fetchCustomer(request.getPorOrgacode(), request.getCmpCustcode());
|
||||
OTPRequest otpRequest = OTPRequest.builder()
|
||||
.porOrgacode(request.getPorOrgacode())
|
||||
.channelCode(request.getChannelCode())
|
||||
.pinType("C_PIN")
|
||||
.email(profile.getCmpEmail())
|
||||
.phone(profile.getPadAdrsmobphone())
|
||||
.isOtpRequired(request.isOtpRequired())
|
||||
.username(profile.getCmpUserName())
|
||||
.subject("Create Transaction Pin Verification OTP")
|
||||
.build();
|
||||
|
||||
notificationService.sendOtp(otpRequest);
|
||||
customerProfileRepository.save(profile);
|
||||
}
|
||||
|
||||
|
||||
public boolean verifyOTPAndSavePin(VerifyPinRequest request) {
|
||||
notificationService.verifyOtp(request.getPorOrgacode(), request.getEmail(), request.getObpPincode());
|
||||
CustomerProfile profile = fetchCustomer(request.getPorOrgacode(), request.getCmpCustcode());
|
||||
profile.setCmpTranpinVerfied(true);
|
||||
customerProfileRepository.save(profile);
|
||||
return true;
|
||||
}
|
||||
|
||||
public CustomerProfile fetchCustomer(String porOrgacode, String cmpCustcode){
|
||||
CustomerProfileId profileId = new CustomerProfileId(porOrgacode,cmpCustcode);
|
||||
return customerProfileRepository.findById(profileId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Customer profile not found for ID: " + profileId));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue