Fixes issue 22876: "No Currency Conversion Rate between currencies found"
authorJavier Etxarri <javier.echarri@openbravo.com>
Mon, 28 Jan 2013 18:31:56 +0100
changeset 19488 f8bfaf4760bf
parent 19487 e035b2855377
child 19489 90f9cb9d0c77
Fixes issue 22876: "No Currency Conversion Rate between currencies found"
in "Add Payment" process although conversion rate at doc level is definedD
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/ad_actionbutton/AddPaymentFromInvoice.java
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/ad_actionbutton/AddPaymentFromInvoice.java	Mon Jan 28 16:29:49 2013 +0100
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/ad_actionbutton/AddPaymentFromInvoice.java	Mon Jan 28 18:31:56 2013 +0100
@@ -53,6 +53,7 @@
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.common.businesspartner.BusinessPartner;
 import org.openbravo.model.common.currency.ConversionRate;
+import org.openbravo.model.common.currency.ConversionRateDoc;
 import org.openbravo.model.common.currency.Currency;
 import org.openbravo.model.common.enterprise.DocumentType;
 import org.openbravo.model.common.enterprise.Organization;
@@ -124,16 +125,18 @@
       String strCurrencyId = vars.getRequestGlobalVariable("inpCurrencyId", "");
       String strPaymentDate = vars.getRequestGlobalVariable("inpPaymentDate", "");
       boolean isReceipt = vars.getRequiredStringParameter("isReceipt").equals("Y");
+      String strInvoiceId = vars.getRequestGlobalVariable("inpcInvoiceId", "");
       refreshFinancialAccountCombo(response, vars, strPaymentMethodId, strFinancialAccountId,
-          strOrgId, strCurrencyId, isReceipt, strPaymentDate, conversionRatePrecision);
+          strOrgId, strCurrencyId, isReceipt, strPaymentDate, conversionRatePrecision, strInvoiceId);
     } else if (vars.commandIn("FILLFINANCIALACCOUNT")) {
       String strFinancialAccountId = vars.getRequestGlobalVariable("inpFinancialAccount", "");
       String strOrgId = vars.getRequestGlobalVariable("inpadOrgId", "");
       String strCurrencyId = vars.getRequestGlobalVariable("inpCurrencyId", "");
       String strPaymentDate = vars.getRequestGlobalVariable("inpPaymentDate", "");
       boolean isReceipt = vars.getRequiredStringParameter("isReceipt").equals("Y");
+      String strInvoiceId = vars.getRequestGlobalVariable("inpcInvoiceId", "");
       refreshFinancialAccountCombo(response, vars, "", strFinancialAccountId, strOrgId,
-          strCurrencyId, isReceipt, strPaymentDate, conversionRatePrecision);
+          strCurrencyId, isReceipt, strPaymentDate, conversionRatePrecision, strInvoiceId);
 
     } else if (vars.commandIn("FILLPAYMENTMETHOD")) {
       String strPaymentMethodId = vars.getRequiredStringParameter("inpPaymentMethod");
@@ -148,8 +151,9 @@
       final String strOrgId = vars.getRequestGlobalVariable("inpadOrgId", "");
       final String strPaymentDate = vars.getRequestGlobalVariable("inpPaymentDate", "");
       Organization org = OBDal.getInstance().get(Organization.class, strOrgId);
+      String strInvoiceId = vars.getGlobalVariable("inpcInvoiceId", "");
       refreshExchangeRate(response, vars, strCurrencyId, strFinancialAccountCurrencyId,
-          strPaymentDate, org, conversionRatePrecision);
+          strPaymentDate, org, conversionRatePrecision, strInvoiceId);
 
     } else if (vars.commandIn("BPARTNERBLOCK")) {
       boolean isReceipt = vars.getRequiredStringParameter("isReceipt").equals("Y");
@@ -447,7 +451,7 @@
       }
       BigDecimal exchangeRate = findExchangeRate(vars, paymentCurrency, financialAccountCurrency,
           new Date(), OBDal.getInstance().get(Organization.class, strOrgId),
-          conversionRatePrecision);
+          conversionRatePrecision, inv);
 
       if (exchangeRate == null) {
         final OBError myMessage = Utility.translateError(this, vars, vars.getLanguage(),
@@ -556,8 +560,8 @@
 
   private void refreshFinancialAccountCombo(HttpServletResponse response, VariablesSecureApp vars,
       String strPaymentMethodId, String strFinancialAccountId, String strOrgId,
-      String strCurrencyId, boolean isReceipt, String paymentDate, int conversionRatePrecision)
-      throws IOException, ServletException {
+      String strCurrencyId, boolean isReceipt, String paymentDate, int conversionRatePrecision,
+      String strInvoiceId) throws IOException, ServletException {
     log4j.debug("Callout: Payment Method has changed to " + strPaymentMethodId);
 
     dao = new AdvPaymentMngtDao();
@@ -571,9 +575,10 @@
     final String formatOutput = vars.getSessionValue("#FormatOutput|generalQtyRelation",
         "#,##0.######");
 
+    Invoice inv = OBDal.getInstance().get(Invoice.class, strInvoiceId);
     BigDecimal exchangeRate = findExchangeRate(vars, paymentCurrency, financialAccountCurrency,
         FIN_Utility.getDate(paymentDate), OBDal.getInstance().get(Organization.class, strOrgId),
-        conversionRatePrecision);
+        conversionRatePrecision, inv);
 
     FIN_FinancialAccount financialAccount = dao.getObject(FIN_FinancialAccount.class,
         strFinancialAccountId);
@@ -605,7 +610,8 @@
 
   private void refreshExchangeRate(HttpServletResponse response, VariablesSecureApp vars,
       String strCurrencyId, String strFinancialAccountCurrencyId, String strPaymentDate,
-      Organization organization, int conversionRatePrecision) throws IOException, ServletException {
+      Organization organization, int conversionRatePrecision, String strInvoiceId)
+      throws IOException, ServletException {
 
     dao = new AdvPaymentMngtDao();
 
@@ -615,8 +621,9 @@
     final String formatOutput = vars.getSessionValue("#FormatOutput|generalQtyRelation",
         "#,##0.######");
 
+    Invoice inv = OBDal.getInstance().get(Invoice.class, strInvoiceId);
     BigDecimal exchangeRate = findExchangeRate(vars, paymentCurrency, financialAccountCurrency,
-        FIN_Utility.getDate(strPaymentDate), organization, conversionRatePrecision);
+        FIN_Utility.getDate(strPaymentDate), organization, conversionRatePrecision, inv);
 
     JSONObject msg = new JSONObject();
     try {
@@ -677,21 +684,48 @@
 
   private BigDecimal findExchangeRate(VariablesSecureApp vars, Currency paymentCurrency,
       Currency financialAccountCurrency, Date paymentDate, Organization organization,
-      int conversionRatePrecision) {
+      int conversionRatePrecision, Invoice invoice) {
+
     BigDecimal exchangeRate = BigDecimal.ONE;
+
     if (financialAccountCurrency != null && !financialAccountCurrency.equals(paymentCurrency)) {
-      final ConversionRate conversionRate = FIN_Utility.getConversionRate(paymentCurrency,
-          financialAccountCurrency, paymentDate, organization);
-      if (conversionRate == null) {
-        exchangeRate = null;
-      } else {
-        exchangeRate = conversionRate.getMultipleRateBy().setScale(conversionRatePrecision,
-            RoundingMode.HALF_UP);
+      if (checkDocumentConversionRate(invoice.getId())) {
+        final ConversionRateDoc conversionRateDoc = FIN_Utility.getConversionRateDoc(
+            paymentCurrency, financialAccountCurrency, invoice.getId(), invoice.getEntity());
+        if (conversionRateDoc == null) {
+          exchangeRate = null;
+        } else {
+          exchangeRate = conversionRateDoc.getRate().setScale(conversionRatePrecision,
+              RoundingMode.HALF_UP);
+        }
+
+      }
+      if (exchangeRate == null) {
+        final ConversionRate conversionRate = FIN_Utility.getConversionRate(paymentCurrency,
+            financialAccountCurrency, paymentDate, organization);
+        if (conversionRate == null) {
+          exchangeRate = null;
+        } else {
+          exchangeRate = conversionRate.getMultipleRateBy().setScale(conversionRatePrecision,
+              RoundingMode.HALF_UP);
+        }
       }
     }
     return exchangeRate;
   }
 
+  private boolean checkDocumentConversionRate(String documentId) {
+    OBCriteria<ConversionRateDoc> conversionRateDocCriteria = OBDal.getInstance().createCriteria(
+        ConversionRateDoc.class);
+    conversionRateDocCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal
+        .getInstance().get(Invoice.class, documentId)));
+    if (conversionRateDocCriteria.count() > 0) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   private FieldProvider[] set() throws ServletException {
     HashMap<String, String> empty = new HashMap<String, String>();
     empty.put("finScheduledPaymentId", "");
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java	Mon Jan 28 16:29:49 2013 +0100
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java	Mon Jan 28 18:31:56 2013 +0100
@@ -42,6 +42,8 @@
 import org.hibernate.Session;
 import org.hibernate.criterion.Restrictions;
 import org.openbravo.advpaymentmngt.dao.AdvPaymentMngtDao;
+import org.openbravo.base.model.Entity;
+import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.base.session.OBPropertiesProvider;
 import org.openbravo.base.structure.BaseOBObject;
@@ -61,11 +63,13 @@
 import org.openbravo.model.ad.utility.Sequence;
 import org.openbravo.model.common.businesspartner.BusinessPartner;
 import org.openbravo.model.common.currency.ConversionRate;
+import org.openbravo.model.common.currency.ConversionRateDoc;
 import org.openbravo.model.common.currency.Currency;
 import org.openbravo.model.common.enterprise.DocumentType;
 import org.openbravo.model.common.enterprise.Organization;
 import org.openbravo.model.common.enterprise.OrganizationInformation;
 import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.financialmgmt.payment.FIN_FinaccTransaction;
 import org.openbravo.model.financialmgmt.payment.FIN_FinancialAccount;
 import org.openbravo.model.financialmgmt.payment.FIN_Payment;
 import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetail;
@@ -873,6 +877,47 @@
     return conversionRate;
   }
 
+  /**
+   * Determine the conversion rate from one currency to another on a given date and given
+   * documentId. Will use the spot conversion rate defined by the system for that date
+   * 
+   * @param fromCurrency
+   *          Currency to convert from
+   * @param toCurrency
+   *          Currency being converted to
+   * @param conversionDate
+   *          Date conversion is being performed
+   * @param documentId
+   *          DocumentId to find the value in table c_conversion_rate_document
+   * @param entity
+   *          Entity type of the document
+   * @return A valid conversion rate for the parameters, or null if no conversion rate can be found
+   */
+  public static ConversionRateDoc getConversionRateDoc(Currency fromCurrency, Currency toCurrency,
+      String documentId, Entity entity) {
+
+    final OBCriteria<ConversionRateDoc> obcConvRateDoc = OBDal.getInstance().createCriteria(
+        ConversionRateDoc.class);
+
+    if (entity.equals(ModelProvider.getInstance().getEntity("Invoice"))) {
+      obcConvRateDoc.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal.getInstance()
+          .get(Invoice.class, documentId)));
+    } else if (entity.equals(ModelProvider.getInstance().getEntity("FIN_Payment"))) {
+      obcConvRateDoc.add(Restrictions.eq(ConversionRateDoc.PROPERTY_PAYMENT, OBDal.getInstance()
+          .get(FIN_Payment.class, documentId)));
+    } else if (entity.equals(ModelProvider.getInstance().getEntity("FIN_Finacc_Transaction"))) {
+      obcConvRateDoc.add(Restrictions.eq(ConversionRateDoc.PROPERTY_FINANCIALACCOUNTTRANSACTION,
+          OBDal.getInstance().get(FIN_FinaccTransaction.class, documentId)));
+    }
+    obcConvRateDoc.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, fromCurrency));
+    obcConvRateDoc.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, toCurrency));
+    obcConvRateDoc.setMaxResults(1);
+    if (obcConvRateDoc.uniqueResult() != null) {
+      return (ConversionRateDoc) obcConvRateDoc.uniqueResult();
+    } else
+      return null;
+  }
+
   public static int getConversionRatePrecision(VariablesSecureApp vars) {
     try {
       String formatOutput = vars