/** * */ package org.compiere.model; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Timestamp; import java.util.Properties; import java.util.logging.Level; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Msg; import org.idempiere.exceptions.NoCurrencyConversionException; /** * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ public final class MConversionRateUtil { /** Logger */ private static final CLogger s_log = CLogger.getCLogger (MConversionRateUtil.class); private MConversionRateUtil() { // nothing } /** * Convert an amount to base currency and update model fields (CurrencyRate, "AmtName"). * @param model * @param DateName conversion date field name * @param SourceAmtName source amount field name * @param AmtName converted amount field name (optional); if null then the converted amount field will not be updated * @param changedColumnName the column that has changed (the controller); optional * @return converted amount or null if error */ public static BigDecimal convertBase(SetGetModel model, String DateName, String SourceAmtName, String AmtName, String changedColumnName) { // If Currency changed, reset rate if (changedColumnName != null && "C_Currency_ID".equalsIgnoreCase(changedColumnName)) { model.set_AttrValue("CurrencyRate", Env.ZERO); } // Source Amount BigDecimal sourceAmt = SetGetUtil.get_AttrValueAsBigDecimal(model, SourceAmtName); if (sourceAmt == null || sourceAmt.signum() == 0) { if (AmtName != null) { model.set_AttrValue(AmtName, Env.ZERO); } return Env.ZERO; } // AD_Client_ID int AD_Client_ID = SetGetUtil.get_AttrValueAsInt(model, "AD_Client_ID"); // Currency To int C_Currency_ID_To = MClient.get(model.getCtx(), AD_Client_ID).getAcctSchema().getC_Currency_ID(); // Get Rate BigDecimal rate = SetGetUtil.get_AttrValueAsBigDecimal(model, "CurrencyRate"); if (rate == null || rate.signum() == 0) { int AD_Org_ID = SetGetUtil.get_AttrValueAsInt(model, "AD_Client_ID"); Timestamp ConvDate = SetGetUtil.get_AttrValueAsDate(model, DateName); int C_Currency_ID = SetGetUtil.get_AttrValueAsInt(model, "C_Currency_ID"); if (C_Currency_ID == C_Currency_ID_To) { rate = Env.ONE; } else { int C_ConversionType_ID = SetGetUtil.get_AttrValueAsInt(model, "C_ConversionType_ID"); rate = MConversionRate.getRate (C_Currency_ID, C_Currency_ID_To, ConvDate, C_ConversionType_ID, AD_Client_ID, AD_Org_ID); if (rate == null) { // NoCurrencyConversion throw new NoCurrencyConversionException(C_Currency_ID, C_Currency_ID_To, ConvDate, C_ConversionType_ID, AD_Client_ID, AD_Org_ID); } } } model.set_AttrValue("CurrencyRate", rate); // Calculate converted amount BigDecimal amt = sourceAmt.multiply(rate); int stdPrecision = MCurrency.getStdPrecision(model.getCtx(), C_Currency_ID_To); amt = amt.setScale(stdPrecision, RoundingMode.HALF_UP); // Update model if (AmtName != null) model.set_AttrValue(AmtName, amt); // Return amt if (s_log.isLoggable(Level.FINE)) s_log.fine("amt=" + sourceAmt + " * " + rate + "=" + amt + ", scale=" + stdPrecision); return amt; } // convert /** * @param ctx * @param adMessage * @param currencyFromID * @param currencyToID * @param convertionTypeID * @param date * @param trxName * @return the message to show when no exchange rate is found */ public static String getErrorMessage(Properties ctx, String adMessage, int currencyFromID, int currencyToID, int convertionTypeID, Timestamp date, String trxName) { if (convertionTypeID == 0) convertionTypeID = MConversionType.getDefault(Env.getAD_Client_ID(ctx)); String retValue = Msg.getMsg(ctx, adMessage, new Object[] {MCurrency.get(ctx, currencyFromID).getISO_Code(), MCurrency.get(ctx, currencyToID).getISO_Code(), new MConversionType(ctx, convertionTypeID, trxName).getName(), date}); return retValue; } }