Skip to content

Commit

Permalink
account identifier worker and loan worker implementation (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
truthfool authored Feb 16, 2023
1 parent 135fc2e commit a3641fd
Show file tree
Hide file tree
Showing 12 changed files with 319 additions and 36 deletions.
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ plugins {
}

repositories {
// mavenLocal()
mavenLocal()

maven {
url = uri('https://repo.maven.apache.org/maven2')
}
Expand All @@ -21,7 +22,7 @@ repositories {
}

dependencies {
implementation 'org.mifos:ph-ee-connector-common:1.2.1-SNAPSHOT'
implementation 'org.mifos:ph-ee-connector-common:1.2.2-SNAPSHOT'
implementation 'com.sun.xml.ws:jaxws-ri:2.3.2'
implementation 'org.apache.camel.springboot:camel-spring-boot-starter:3.4.0'
implementation 'org.apache.camel:camel-endpointdsl:3.4.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static org.apache.camel.Exchange.HTTP_PATH;
import static org.mifos.connector.ams.camel.config.CamelProperties.TRANSFER_ACTION;
import static org.mifos.connector.ams.camel.cxfrs.HeaderBasedInterceptor.CXF_TRACE_HEADER;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.ACCOUNT_NUMBER;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.PARTY_ID;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.PARTY_ID_TYPE;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.TENANT_ID;
Expand All @@ -37,6 +38,9 @@ public class AmsCommonService {
@Value("${ams.local.interop.transfers-path}")
private String amsInteropTransfersPath;

@Value("${ams.local.loan.repayment-path}")
private String amsLoanRepaymentPath;

@Autowired
private TenantService tenantService;

Expand All @@ -45,6 +49,7 @@ public class AmsCommonService {

private Logger logger = LoggerFactory.getLogger(this.getClass());

private static final String APPLICATION_TYPE = "application/json";
public void getLocalQuote(Exchange e) {
Map<String, Object> headers = new HashMap<>();
headers.put(CXF_TRACE_HEADER, true);
Expand Down Expand Up @@ -78,6 +83,17 @@ public void sendTransfer(Exchange e) {
headers.putAll(tenantService.getHeaders(e.getProperty(TENANT_ID, String.class)));
cxfrsUtil.sendInOut("cxfrs:bean:ams.local.interop", e, headers, e.getIn().getBody());
}
public void repayLoan(Exchange e) {
Map<String, Object> headers = new HashMap<>();
headers.put(CXF_TRACE_HEADER, true);
headers.put(HTTP_METHOD, "POST");
headers.put(HTTP_PATH, amsLoanRepaymentPath.replace("{accountNumber}", e.getProperty(ACCOUNT_NUMBER, String.class)));
logger.debug("Loan Repayment Body: {}", e.getIn().getBody());
headers.put("Content-Type", APPLICATION_TYPE);
headers.putAll(tenantService.getHeaders(e.getProperty(TENANT_ID, String.class)));
cxfrsUtil.sendInOut("cxfrs:bean:ams.local.loan", e, headers, e.getIn().getBody());
}


public void registerInteropIdentifier(Exchange e) {
Map<String, Object> headers = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public interface AmsService {

void sendTransfer(Exchange e);

void repayLoan(Exchange e);

void login(Exchange e);

void getSavingsAccount(Exchange e);
Expand All @@ -29,7 +31,6 @@ public interface AmsService {
void getClientByMobileNo(Exchange e);

void getSavingsAccountsTransactions(Exchange e) ;

default void getClientImage(Exchange e){}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
import org.mifos.connector.ams.errorhandler.ErrorTranslator;
import org.mifos.connector.ams.tenant.TenantNotExistException;
import org.mifos.connector.ams.utils.Utils;
import org.mifos.connector.ams.zeebe.ZeebeUtil;
import org.mifos.connector.common.ams.dto.ClientData;
import org.mifos.connector.common.ams.dto.Customer;
import org.mifos.connector.common.ams.dto.InteropAccountDTO;
import org.mifos.connector.common.ams.dto.LoanRepaymentDTO;
import org.mifos.connector.common.ams.dto.LoginFineractCnResponseDTO;
import org.mifos.connector.common.ams.dto.PartyFspResponseDTO;
import org.mifos.connector.common.ams.dto.ProductDefinition;
Expand Down Expand Up @@ -187,6 +189,21 @@ public void configure() {
.process(transfersResponseProcessor)
.end();

from("direct:send-transfers-loan")
.id("send-transfers-loan")
.log(LoggingLevel.DEBUG, "Sending transfer with action: ${exchangeProperty." + TRANSFER_ACTION + "} " +
" for transaction: ${exchangeProperty." + TRANSACTION_ID + "}")
.log("Process type: ${exchangeProperty." + PROCESS_TYPE + "}")
.process(exchange -> {
LoanRepaymentDTO loanRepaymentDTO=ZeebeUtil.setLoanRepaymentBody(exchange);
String requestBody = objectMapper.writeValueAsString(loanRepaymentDTO);
logger.debug("Request Body : {}", requestBody);
exchange.getIn().setBody(requestBody);
exchange.setProperty("accountNumber",exchange.getProperty(ACCOUNT_NUMBER));
})
.process(amsService::repayLoan);


from("direct:fincn-oauth")
.id("fincn-oauth")
.log(LoggingLevel.INFO, "Fineract CN oauth request for tenant: ${exchangeProperty." + TENANT_ID + "}")
Expand Down Expand Up @@ -342,6 +359,5 @@ public void configure() {
exchange.setProperty(PARTY_ID, transactionRequest.getPayee().getPartyIdInfo().getPartyIdentifier());
})
.to("direct:send-transfers");

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.mifos.connector.ams.zeebe.ZeebeUtil;
import org.mifos.connector.common.ams.dto.TransferFspRequestDTO;
import org.mifos.connector.common.mojaloop.dto.Extension;
import org.mifos.connector.common.mojaloop.dto.ExtensionList;
import org.mifos.connector.common.mojaloop.dto.FspMoneyData;
import org.mifos.connector.common.mojaloop.dto.TransactionType;
import org.mifos.connector.common.mojaloop.type.InitiatorType;
Expand All @@ -17,9 +14,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.UUID;

import static org.mifos.connector.ams.camel.config.CamelProperties.TRANSACTION_ROLE;
Expand Down Expand Up @@ -75,22 +70,22 @@ public void process(Exchange exchange) throws Exception {

if (fspFee != null || fspCommission != null) {
transferRequestDTO = new TransferFspRequestDTO(
transactionCode,
transferCode,
exchange.getProperty(EXTERNAL_ACCOUNT_ID, String.class),
amount,
fspFee,
fspCommission,
TransactionRole.valueOf(exchange.getProperty(TRANSACTION_ROLE, String.class)),
transactionType,
note);
transactionCode,
transferCode,
exchange.getProperty(EXTERNAL_ACCOUNT_ID, String.class),
amount,
fspFee,
fspCommission,
TransactionRole.valueOf(exchange.getProperty(TRANSACTION_ROLE, String.class)),
transactionType,
note);
} else {
transferRequestDTO = new TransferFspRequestDTO(
transactionCode,
transferCode,
exchange.getProperty(EXTERNAL_ACCOUNT_ID, String.class),
amount,
TransactionRole.valueOf(exchange.getProperty(TRANSACTION_ROLE, String.class)));
transactionCode,
transferCode,
exchange.getProperty(EXTERNAL_ACCOUNT_ID, String.class),
amount,
TransactionRole.valueOf(exchange.getProperty(TRANSACTION_ROLE, String.class)));
}

logger.debug("prepared transferRequestDTO: {}", objectMapper.writeValueAsString(transferRequestDTO));
Expand Down
138 changes: 135 additions & 3 deletions src/main/java/org/mifos/connector/ams/zeebe/ZeebeUtil.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
package org.mifos.connector.ams.zeebe;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.camel.Exchange;
import org.json.JSONObject;
import org.mifos.connector.common.ams.dto.LoanRepaymentDTO;
import org.mifos.connector.common.channel.dto.TransactionChannelRequestDTO;
import org.mifos.connector.common.gsma.dto.CustomData;
import org.mifos.connector.common.gsma.dto.GsmaTransfer;
import org.mifos.connector.common.mojaloop.dto.*;
import org.mifos.connector.common.mojaloop.type.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static org.mifos.connector.ams.camel.config.CamelProperties.TRANSACTION_ROLE;
import static org.mifos.connector.ams.camel.config.CamelProperties.TRANSFER_ACTION;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.ACCOUNT_IDENTIFIER;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.ACCOUNT_NUMBER;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.CHANNEL_REQUEST;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.EXTERNAL_ACCOUNT_ID;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.PARTY_ID;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.PARTY_ID_TYPE;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.REQUESTED_DATE;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.TENANT_ID;
import static org.mifos.connector.ams.zeebe.ZeebeVariables.TRANSACTION_ID;
import static org.mifos.connector.common.ams.dto.TransferActionType.CREATE;

@Component
public class ZeebeUtil {


private static Logger logger = LoggerFactory.getLogger(ZeebeUtil.class);
private static ObjectMapper objectMapper = new ObjectMapper();
@Value("#{'${accountPrefixes}'.split(',')}")
public List<String> accountPrefixes;

public static void zeebeVariablesToCamelProperties(Map<String, Object> variables, Exchange exchange, String... names) {
exchange.setProperty("zeebeVariables", variables);
Expand All @@ -34,9 +61,114 @@ public static Map<String, Object> zeebeVariablesFrom(Exchange exchange) {

public static <T> T zeebeVariable(Exchange exchange, String name, Class<T> clazz) throws Exception {
Object content = zeebeVariablesFrom(exchange).get(name);
if (content instanceof Map){
if (content instanceof Map) {
return objectMapper.readValue(objectMapper.writeValueAsString(content), clazz);
}
return (T) content;
}

public static String getCurrentDate(String requestedDate,String dateFormat) {
LocalDateTime datetime = LocalDateTime.parse(requestedDate, DateTimeFormatter.ofPattern(dateFormat));
return datetime.format(DateTimeFormatter.ofPattern(dateFormat));
}

public static LoanRepaymentDTO setLoanRepaymentBody(Exchange exchange) {
String dateFormat = "dd MMMM yyyy";
LoanRepaymentDTO loanRepaymentDTO = new LoanRepaymentDTO();
loanRepaymentDTO.setDateFormat(dateFormat);
loanRepaymentDTO.setLocale("en");
loanRepaymentDTO.setTransactionAmount(exchange.getProperty("amount").toString());
String currDate = getCurrentDate(exchange.getProperty("requestedDate").toString(),dateFormat);
loanRepaymentDTO.setTransactionDate(currDate);
return loanRepaymentDTO;
}

public static void setZeebeVariables(Exchange e, Map<String, Object> variables, String requestDate, String accountHoldingInstitutionId, String transactionChannelRequestDTO) {
variables.put(ACCOUNT_IDENTIFIER,e.getProperty(ACCOUNT_IDENTIFIER));
variables.put(ACCOUNT_NUMBER,e.getProperty(ACCOUNT_NUMBER));
variables.put(TRANSACTION_ID, UUID.randomUUID().toString());
variables.put(TENANT_ID,accountHoldingInstitutionId);
variables.put(TRANSFER_ACTION,CREATE.name());
variables.put(CHANNEL_REQUEST,transactionChannelRequestDTO);
variables.put(REQUESTED_DATE,requestDate);
variables.put(EXTERNAL_ACCOUNT_ID,e.getProperty(ACCOUNT_NUMBER));
variables.put("payeeTenantId", accountHoldingInstitutionId);
}

public static void setZeebeVariablesLoanWorker(Map<String, Object> variables, TransactionChannelRequestDTO transactionRequest) {
TransactionType transactionType = new TransactionType();
transactionType.setInitiator(TransactionRole.PAYEE);
transactionType.setInitiatorType(InitiatorType.CONSUMER);
transactionType.setScenario(Scenario.PAYMENT);
transactionRequest.setTransactionType(transactionType);
variables.put("initiator", transactionType.getInitiator().name());
variables.put("initiatorType", transactionType.getInitiatorType().name());
variables.put("scenario", transactionType.getScenario().name());
variables.put("amount", new FspMoneyData(transactionRequest.getAmount().getAmountDecimal(),
transactionRequest.getAmount().getCurrency()));
variables.put("processType", "api");
}

public static void setExchangePropertyLoan(Exchange ex, String partyId, String partyIdType, TransactionChannelRequestDTO transactionRequest, Map<String, Object> existingVariables) throws JsonProcessingException {
ex.setProperty(PARTY_ID_TYPE, partyIdType);
ex.setProperty(PARTY_ID, partyId);

ex.setProperty(CHANNEL_REQUEST, objectMapper.writeValueAsString(transactionRequest));
ex.setProperty(TRANSACTION_ROLE, TransactionRole.PAYEE.name());
ex.setProperty("amount",transactionRequest.getAmount().getAmountDecimal());
ex.setProperty(ACCOUNT_NUMBER,existingVariables.get(ACCOUNT_NUMBER));
ex.setProperty(EXTERNAL_ACCOUNT_ID,"L");
ex.setProperty(REQUESTED_DATE,existingVariables.get("requestedDate"));
}

public Exchange setAccountTypeAndNumber(Exchange e, String accountNo) {
String accountTypeIdentifier = "";
String accountNumber = "";
int accountNoLength = accountNo.length();
// Separating account id and prefix
for (String accountPrefix : accountPrefixes) {
if (accountNo.startsWith(accountPrefix)) {
accountNumber = accountNo.substring(accountPrefix.length(), accountNoLength);
accountTypeIdentifier = accountNo.substring(0, accountPrefix.length());
break;
}
}
logger.debug("Accout number:{}, Identifier:{}", accountNumber, accountTypeIdentifier);
e.setProperty(ACCOUNT_NUMBER, accountNumber);
e.setProperty(ACCOUNT_IDENTIFIER, accountTypeIdentifier);
return e;
}

public static String getValueofKey(List<CustomData> customData, String key) {
for (CustomData obj : customData) {
String keyString = obj.getKey();
if (keyString.equalsIgnoreCase(key)) {
return obj.getValue().toString();
}
}
return null;
}

public static String convertGsmaTransfertoTransactionChannel(GsmaTransfer gsmaTransfer, Object property) throws JsonProcessingException {
TransactionChannelRequestDTO transactionChannelRequestDTO = new TransactionChannelRequestDTO();
String msisdn = gsmaTransfer.getPayer().get(0).getPartyIdIdentifier();
String accountId = property.toString();

String amount = gsmaTransfer.getAmount().trim();
List<CustomData> customData = gsmaTransfer.getCustomData();
String currency = gsmaTransfer.getCurrency();

PartyIdInfo partyIdInfopayee = new PartyIdInfo(IdentifierType.ACCOUNT_ID, accountId);
PartyIdInfo partyIdInfopayer = new PartyIdInfo(IdentifierType.MSISDN, msisdn);
Party partyPayee = new Party(partyIdInfopayee);
Party partyPayer = new Party(partyIdInfopayer);

MoneyData moneyData = new MoneyData(amount, currency);

transactionChannelRequestDTO.setAmount(moneyData);
transactionChannelRequestDTO.setPayee(partyPayee);
transactionChannelRequestDTO.setPayer(partyPayer);

return objectMapper.writeValueAsString(transactionChannelRequestDTO);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ public class ZeebeVariables {
public static final String TRANSFER_PREPARE_FAILED = "transferPrepareFailed";
public static final String TRANSFER_RELEASE_FAILED = "transferReleaseFailed";
public static final String TRANSFER_RESPONSE_PREFIX = "transferResponse";
public static final String ACCOUNT_IDENTIFIER="accountIdentifier";
public static final String ACCOUNT_NUMBER="accountNumber";

public static final String ERROR_CODE = "errorCode";
public static final String ERROR_PAYLOAD = "errorPayload";
public static final String IS_ERROR_HANDLED = "isErrorHandled";
public static final String NOTE = "note";
public static final String REQUESTED_DATE = "requestedDate";

static {
ACTION_FAILURE_MAP.put(TransferActionType.PREPARE.name(), TRANSFER_PREPARE_FAILED);
Expand Down
Loading

0 comments on commit a3641fd

Please sign in to comment.