[UCOD][PRE-PROD][14]-getEvaluatedCurrency api to fetch currency conversion exchange rates #2

Merged
naeem.ullah merged 1 commits from UCOD-14 into UCO-PRE-PRODUCTION-2026 2 weeks ago

@ -24,6 +24,7 @@ import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Currency;
import java.util.*; import java.util.*;
@Service @Service
@ -183,12 +184,19 @@ public class TransactionService {
} }
public EvaluatedCurrencyReponse getEvaluatedCurrency(String porOrgacode, String baseCurrencyCode, String targetCurrencyCode, double sgtGntramtfc) { public EvaluatedCurrencyReponse getEvaluatedCurrency(String porOrgacode, String baseCurrencyCode, String targetCurrencyCode, double sgtGntramtfc) {
double pkrAmt = convertToPKR(baseCurrencyCode,sgtGntramtfc,porOrgacode);
double convertFromPkr = convertFromPKR(targetCurrencyCode,pkrAmt,porOrgacode);
List<ExchangeRateModel> exchangeRateModelList = fetchExchangeRate(porOrgacode); List<ExchangeRateModel> exchangeRateModelList = fetchExchangeRate(porOrgacode);
if (exchangeRateModelList == null || exchangeRateModelList.isEmpty()) {
throw new RuntimeException("No exchange rates configured for organization " + porOrgacode + ". Please configure exchange rates first.");
}
String normalizedBase = normalizeCurrencyCode(baseCurrencyCode, exchangeRateModelList);
String normalizedTarget = normalizeCurrencyCode(targetCurrencyCode, exchangeRateModelList);
double pkrAmt = convertToPKR(normalizedBase, sgtGntramtfc, porOrgacode, exchangeRateModelList);
double convertFromPkr = convertFromPKR(normalizedTarget, pkrAmt, porOrgacode, exchangeRateModelList);
Optional<Double> rate = exchangeRateModelList.stream() Optional<Double> rate = exchangeRateModelList.stream()
.filter(x -> x.isPcrCurrbase() && x.getPcrCurrcode().equals(targetCurrencyCode)) .filter(x -> x.isPcrCurrbase() && currencyCodeMatches(x.getPcrCurrcode(), normalizedTarget))
.map(x -> { .map(x -> {
BigDecimal bd = BigDecimal.valueOf(1 / x.getPerEratrateact()); BigDecimal bd = BigDecimal.valueOf(1 / x.getPerEratrateact());
bd = bd.setScale(2, RoundingMode.HALF_UP); bd = bd.setScale(2, RoundingMode.HALF_UP);
@ -198,7 +206,7 @@ public class TransactionService {
if (!rate.isPresent()) { if (!rate.isPresent()) {
rate = exchangeRateModelList.stream() rate = exchangeRateModelList.stream()
.filter(x -> !x.isPcrCurrbase() && x.getPcrCurrcode().equals(targetCurrencyCode)) .filter(x -> !x.isPcrCurrbase() && currencyCodeMatches(x.getPcrCurrcode(), normalizedTarget))
.map(x -> { .map(x -> {
BigDecimal bd = BigDecimal.valueOf(x.getPerEratrateact()); BigDecimal bd = BigDecimal.valueOf(x.getPerEratrateact());
bd = bd.setScale(2, RoundingMode.HALF_UP); bd = bd.setScale(2, RoundingMode.HALF_UP);
@ -220,22 +228,30 @@ public class TransactionService {
public double convertToPKR(String fromcrCurrcode, double amount, String porOrgacode) { public double convertToPKR(String fromcrCurrcode, double amount, String porOrgacode) {
List<ExchangeRateModel> exchangeRateModelList = fetchExchangeRate(porOrgacode); List<ExchangeRateModel> exchangeRateModelList = fetchExchangeRate(porOrgacode);
return convertToPKR(fromcrCurrcode, amount, porOrgacode, exchangeRateModelList);
}
private double convertToPKR(String fromcrCurrcode, double amount, String porOrgacode, List<ExchangeRateModel> exchangeRateModelList) {
if (exchangeRateModelList == null || exchangeRateModelList.isEmpty()) {
throw new RuntimeException("No exchange rates configured for organization " + porOrgacode + ". Please configure exchange rates first.");
}
String baseCurrencyCode = exchangeRateModelList.stream() String baseCurrencyCode = exchangeRateModelList.stream()
.filter(ExchangeRateModel::isPcrCurrbase) .filter(ExchangeRateModel::isPcrCurrbase)
.findFirst() .findFirst()
.map(ExchangeRateModel::getPcrCurrcode) .map(ExchangeRateModel::getPcrCurrcode)
.orElse(null); .orElse(null);
if (fromcrCurrcode.equals(baseCurrencyCode)) { if (currencyCodeMatches(baseCurrencyCode, fromcrCurrcode)) {
return amount; return amount;
} }
return exchangeRateModelList.stream() return exchangeRateModelList.stream()
.filter(k -> k.getPcrCurrcode().equals(fromcrCurrcode)) .filter(k -> currencyCodeMatches(k.getPcrCurrcode(), fromcrCurrcode))
.findFirst() .findFirst()
.map(k -> amount * k.getPerEratrateact()) .map(k -> amount * k.getPerEratrateact())
.orElse(0.0); .orElseThrow(() -> new RuntimeException(
"Exchange rate not found for currency " + fromcrCurrcode + " (organization: " + porOrgacode + "). Available: " + formatAvailableCurrencies(exchangeRateModelList)
));
} }
public List<ExchangeRateModel> fetchExchangeRate(String porOrgacode) { public List<ExchangeRateModel> fetchExchangeRate(String porOrgacode) {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
@ -245,21 +261,103 @@ public class TransactionService {
} }
public double convertFromPKR(String todrCurrcode, double amount, String porOrgacode) { public double convertFromPKR(String todrCurrcode, double amount, String porOrgacode) {
List<ExchangeRateModel> exchangeRateModelList = fetchExchangeRate(porOrgacode); List<ExchangeRateModel> exchangeRateModelList = fetchExchangeRate(porOrgacode);
return convertFromPKR(todrCurrcode, amount, porOrgacode, exchangeRateModelList);
}
private double convertFromPKR(String todrCurrcode, double amount, String porOrgacode, List<ExchangeRateModel> exchangeRateModelList) {
if (exchangeRateModelList == null || exchangeRateModelList.isEmpty()) {
throw new RuntimeException("No exchange rates configured for organization " + porOrgacode + ". Please configure exchange rates first.");
}
String baseCurrencyCode = exchangeRateModelList.stream() String baseCurrencyCode = exchangeRateModelList.stream()
.filter(ExchangeRateModel::isPcrCurrbase) .filter(ExchangeRateModel::isPcrCurrbase)
.findFirst() .findFirst()
.map(ExchangeRateModel::getPcrCurrcode) .map(ExchangeRateModel::getPcrCurrcode)
.orElse(null); .orElse(null);
if (todrCurrcode.equals(baseCurrencyCode)) { if (currencyCodeMatches(baseCurrencyCode, todrCurrcode)) {
return amount; return amount;
} }
return exchangeRateModelList.stream() return exchangeRateModelList.stream()
.filter(k -> k.getPcrCurrcode().equals(todrCurrcode)) .filter(k -> currencyCodeMatches(k.getPcrCurrcode(), todrCurrcode))
.findFirst() .findFirst()
.map(k -> amount / k.getPerEratrateact()) .map(k -> amount / k.getPerEratrateact())
.orElseThrow(() -> new RuntimeException("Product Not Found")); .orElseThrow(() -> new RuntimeException(
"Exchange rate not found for currency " + todrCurrcode + " (organization: " + porOrgacode + "). Available: " + formatAvailableCurrencies(exchangeRateModelList)
));
}
private boolean currencyCodeMatches(String storedCode, String requestedCode) {
if (requestedCode == null) return storedCode == null;
if (storedCode == null) return false;
return storedCode.trim().equals(requestedCode.trim());
}
private String normalizeCurrencyCode(String currencyCode, List<ExchangeRateModel> exchangeRates) {
if (currencyCode == null) return null;
String raw = currencyCode.trim();
if (raw.isEmpty()) return raw;
String upper = raw.toUpperCase(Locale.ROOT);
if (exchangeRates != null && exchangeRates.stream().anyMatch(r -> upper.equals(safeTrimUpper(r.getPcrCurrcode())))) {
return upper;
}
if (exchangeRates != null) {
Optional<String> byShort = exchangeRates.stream()
.filter(r -> upper.equals(safeTrimUpper(r.getPcrCurrshort())))
.map(ExchangeRateModel::getPcrCurrcode)
.filter(Objects::nonNull)
.findFirst();
if (byShort.isPresent()) {
return byShort.get();
}
}
if (upper.length() == 3 && upper.chars().allMatch(Character::isLetter)) {
try {
int numeric = Currency.getInstance(upper).getNumericCode();
String numericStr = String.valueOf(numeric);
if (exchangeRates != null && exchangeRates.stream().anyMatch(r -> numericStr.equals(safeTrimUpper(r.getPcrCurrcode())))) {
return numericStr;
}
} catch (Exception ignored) {
}
}
if (upper.chars().allMatch(Character::isDigit)) {
try {
int numeric = Integer.parseInt(upper);
for (Currency c : Currency.getAvailableCurrencies()) {
if (c.getNumericCode() == numeric) {
String alpha = c.getCurrencyCode();
if (exchangeRates != null && exchangeRates.stream().anyMatch(r -> alpha.equals(safeTrimUpper(r.getPcrCurrcode())))) {
return alpha;
}
break;
}
}
} catch (Exception ignored) {
}
}
return upper;
}
private String safeTrimUpper(String s) {
return s == null ? null : s.trim().toUpperCase(Locale.ROOT);
}
private String formatAvailableCurrencies(List<ExchangeRateModel> exchangeRates) {
if (exchangeRates == null || exchangeRates.isEmpty()) return "[]";
return exchangeRates.stream()
.map(r -> {
String shortCode = (r.getPcrCurrshort() == null || r.getPcrCurrshort().isBlank()) ? "?" : r.getPcrCurrshort().trim();
String code = (r.getPcrCurrcode() == null || r.getPcrCurrcode().isBlank()) ? "?" : r.getPcrCurrcode().trim();
return shortCode + "(" + code + ")";
})
.distinct()
.limit(20)
.toList()
.toString();
} }
public Map<String, Object> glAccountTransaction(GLAccontTranasctionRequestModel glAccontTranasctionRequestModel) { public Map<String, Object> glAccountTransaction(GLAccontTranasctionRequestModel glAccontTranasctionRequestModel) {

Loading…
Cancel
Save