Fixed bug 17823, Fixed bug 17825, Fixed bug 17828, Fixed bug 17841, Fixed bug 17842, Fixed bug 17843, Fixed bug 17844, Fixed bug 17848, Fixed bug 17852
authorSalvador Zapata <salvador.zapata@openbravo.com>
Mon, 04 Jul 2011 16:01:18 +0200
changeset 13327 354aa0b865ad
parent 13326 ecd741920f59
child 13328 887a041f92a6
Fixed bug 17823, Fixed bug 17825, Fixed bug 17828, Fixed bug 17841, Fixed bug 17842, Fixed bug 17843, Fixed bug 17844, Fixed bug 17848, Fixed bug 17852
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java
src-db/database/model/triggers/C_CONVERSION_RATE_DOCUMENT_TRG.xml
src-db/database/model/triggers/C_INVOICE_REVERSE_TRG.xml
src-db/database/sourcedata/AD_COLUMN.xml
src-db/database/sourcedata/AD_VAL_RULE.xml
src/org/openbravo/erpCommon/ad_callouts/SE_CalculateExchangeRate.java
src/org/openbravo/erpCommon/ad_forms/AcctServer.java
src/org/openbravo/erpCommon/ad_forms/DocFINPayment.java
src/org/openbravo/erpCommon/ad_forms/FactLine.java
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java	Fri Jun 24 16:33:21 2011 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java	Mon Jul 04 16:01:18 2011 +0200
@@ -39,6 +39,7 @@
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.common.businesspartner.BusinessPartner;
 import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.common.currency.ConversionRateDoc;
 import org.openbravo.model.financialmgmt.payment.FIN_FinaccTransaction;
 import org.openbravo.model.financialmgmt.payment.FIN_Payment;
 import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetail;
@@ -371,6 +372,7 @@
             }
           }
           List<FIN_PaymentDetail> paymentDetails = payment.getFINPaymentDetailList();
+          List<ConversionRateDoc> conversionRates = payment.getCurrencyConversionRateDocList();
           for (FIN_PaymentDetail paymentDetail : paymentDetails) {
             removedPDS = new ArrayList<FIN_PaymentScheduleDetail>();
             for (FIN_PaymentScheduleDetail paymentScheduleDetail : paymentDetail
@@ -421,6 +423,8 @@
             OBDal.getInstance().remove(OBDal.getInstance().get(FIN_PaymentDetail.class, pdToRm));
           }
           payment.getFINPaymentDetailList().removeAll(removedPD);
+          payment.getCurrencyConversionRateDocList().removeAll(conversionRates);
+          payment.setFinancialTransactionConvertRate(BigDecimal.ZERO);
           OBDal.getInstance().save(payment);
 
           if (payment.getGeneratedCredit().compareTo(BigDecimal.ZERO) == 0
--- a/src-db/database/model/triggers/C_CONVERSION_RATE_DOCUMENT_TRG.xml	Fri Jun 24 16:33:21 2011 +0200
+++ b/src-db/database/model/triggers/C_CONVERSION_RATE_DOCUMENT_TRG.xml	Mon Jul 04 16:01:18 2011 +0200
@@ -35,7 +35,7 @@
 
 
     -- If invoice is posted, CRUD is not allowed
-    IF INSERTING OR UPDATING OR DELETING
+    IF INSERTING
     THEN
 	IF :NEW.C_INVOICE_ID IS NOT NULL THEN
 		SELECT POSTED INTO v_Posted 
@@ -59,6 +59,48 @@
 		THEN  RAISE_APPLICATION_ERROR(-20501, 'Document processed/posted');
 	END IF;
     END IF;
+    IF UPDATING THEN
+	IF :OLD.C_INVOICE_ID IS NOT NULL THEN
+		SELECT POSTED INTO v_Posted 
+		FROM C_INVOICE
+		WHERE C_INVOICE_ID = :OLD.C_INVOICE_ID;
+	END IF;
+
+	IF :OLD.FIN_PAYMENT_ID IS NOT NULL THEN
+		SELECT POSTED INTO v_Posted 
+		FROM FIN_PAYMENT
+		WHERE FIN_PAYMENT_ID = :OLD.FIN_PAYMENT_ID;
+	END IF;
+
+	IF :OLD.aprm_finacc_transaction_v_id IS NOT NULL THEN
+		SELECT POSTED INTO v_Posted 
+		FROM aprm_finacc_transaction_v
+		WHERE aprm_finacc_transaction_v_id = :OLD.aprm_finacc_transaction_v_id;
+	END IF;
+    END IF;
+    IF DELETING THEN
+	IF :OLD.C_INVOICE_ID IS NOT NULL THEN
+		SELECT POSTED INTO v_Posted 
+		FROM C_INVOICE
+		WHERE C_INVOICE_ID = :OLD.C_INVOICE_ID;
+	END IF;
+
+	IF :OLD.FIN_PAYMENT_ID IS NOT NULL THEN
+		SELECT POSTED INTO v_Posted 
+		FROM FIN_PAYMENT
+		WHERE FIN_PAYMENT_ID = :OLD.FIN_PAYMENT_ID;
+	END IF;
+
+	IF :OLD.aprm_finacc_transaction_v_id IS NOT NULL THEN
+		SELECT POSTED INTO v_Posted 
+		FROM aprm_finacc_transaction_v
+		WHERE aprm_finacc_transaction_v_id = :OLD.aprm_finacc_transaction_v_id;
+	END IF;
+
+	IF(v_Posted='Y')
+		THEN  RAISE_APPLICATION_ERROR(-20501, 'Document processed/posted');
+	END IF;
+    END IF;
     
     
 END C_CONVERSION_RATE_DOCUMENT_TRG
--- a/src-db/database/model/triggers/C_INVOICE_REVERSE_TRG.xml	Fri Jun 24 16:33:21 2011 +0200
+++ b/src-db/database/model/triggers/C_INVOICE_REVERSE_TRG.xml	Mon Jul 04 16:01:18 2011 +0200
@@ -33,6 +33,8 @@
    v_docstatus C_Invoice.DOCSTATUS%TYPE;
    v_isposted C_Invoice.POSTED%TYPE;
    v_amt C_Invoice.GrandTotal%TYPE;
+   TYPE RECORD IS REF CURSOR;
+   Cur_Exchange_info RECORD;
 
 BEGIN
     
@@ -68,7 +70,35 @@
    
    IF(v_bpheader_id <> v_bpreversed_id) THEN
      RAISE_APPLICATION_ERROR(-20000, '@NotEqualBPartner@');
-   END IF;  
+   END IF; 
+
+   -- Copy Exchange rate info
+  FOR Cur_Exchange_info IN (
+	SELECT * FROM 
+	C_CONVERSION_RATE_DOCUMENT 
+	WHERE C_INVOICE_ID = :NEW.REVERSED_C_INVOICE_ID
+  ) 
+  LOOP
+    INSERT
+    INTO c_conversion_rate_document
+      (
+        c_conversion_rate_document_id, AD_CLIENT_ID, AD_ORG_ID,
+        ISACTIVE, CREATED, CREATEDBY,
+        UPDATED, UPDATEDBY, C_CURRENCY_ID,
+        C_CURRENCY_ID_TO, C_INVOICE_ID, FIN_PAYMENT_ID,
+        APRM_FINACC_TRANSACTION_V_ID, RATE, FOREIGN_AMOUNT
+      )
+      VALUES
+      (
+        get_uuid(), Cur_Exchange_info.AD_Client_ID, Cur_Exchange_info.AD_Org_ID,
+         Cur_Exchange_info.ISACTIVE, now(), Cur_Exchange_info.CREATEDBY,
+        now(), Cur_Exchange_info.UPDATEDBY, Cur_Exchange_info.C_CURRENCY_ID,
+        Cur_Exchange_info.C_CURRENCY_ID_TO, :NEW.C_INVOICE_ID, Cur_Exchange_info.FIN_PAYMENT_ID,
+        Cur_Exchange_info.APRM_FINACC_TRANSACTION_V_ID, Cur_Exchange_info.RATE, Cur_Exchange_info.FOREIGN_AMOUNT
+      )
+      ;
+  END LOOP;
+    
   END IF;
   
   IF(DELETING) THEN
@@ -86,6 +116,7 @@
    END IF;
    
   END IF;
+  
 END C_INVOICE_REVERSE_TRG
 ]]></body>
     </trigger>
--- a/src-db/database/sourcedata/AD_COLUMN.xml	Fri Jun 24 16:33:21 2011 +0200
+++ b/src-db/database/sourcedata/AD_COLUMN.xml	Mon Jul 04 16:01:18 2011 +0200
@@ -207831,7 +207831,7 @@
 <!--05A12278486748828E4DC33428752E72-->  <DEFAULTVALUE><![CDATA[0]]></DEFAULTVALUE>
 <!--05A12278486748828E4DC33428752E72-->  <ISKEY><![CDATA[N]]></ISKEY>
 <!--05A12278486748828E4DC33428752E72-->  <ISPARENT><![CDATA[N]]></ISPARENT>
-<!--05A12278486748828E4DC33428752E72-->  <ISMANDATORY><![CDATA[N]]></ISMANDATORY>
+<!--05A12278486748828E4DC33428752E72-->  <ISMANDATORY><![CDATA[Y]]></ISMANDATORY>
 <!--05A12278486748828E4DC33428752E72-->  <ISUPDATEABLE><![CDATA[Y]]></ISUPDATEABLE>
 <!--05A12278486748828E4DC33428752E72-->  <ISIDENTIFIER><![CDATA[N]]></ISIDENTIFIER>
 <!--05A12278486748828E4DC33428752E72-->  <SEQNO><![CDATA[150]]></SEQNO>
--- a/src-db/database/sourcedata/AD_VAL_RULE.xml	Fri Jun 24 16:33:21 2011 +0200
+++ b/src-db/database/sourcedata/AD_VAL_RULE.xml	Mon Jul 04 16:01:18 2011 +0200
@@ -1779,7 +1779,7 @@
 <!--FF8081813092D5DC013092DD70AD000C-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--FF8081813092D5DC013092DD70AD000C-->  <NAME><![CDATA[Document currency]]></NAME>
 <!--FF8081813092D5DC013092DD70AD000C-->  <TYPE><![CDATA[S]]></TYPE>
-<!--FF8081813092D5DC013092DD70AD000C-->  <CODE><![CDATA[C_Currency.C_Currency_id in (SELECT C_Currency_ID FROM C_Invoice WHERE C_Invoice_ID =@C_Invoice_ID@)  or C_Currency.C_Currency_id in (SELECT C_Currency_ID FROM aprm_finacc_transaction_v WHERE aprm_finacc_transaction_v_id=@APRM_Finacc_Transaction_V_ID@) or C_Currency.C_Currency_id in (SELECT C_Currency_ID FROM FIN_Payment WHERE FIN_Payment_ID = @FIN_Payment_ID@)]]></CODE>
+<!--FF8081813092D5DC013092DD70AD000C-->  <CODE><![CDATA[C_Currency.C_Currency_id in (SELECT C_Currency_ID FROM C_Invoice WHERE C_Invoice_ID =@C_Invoice_ID@)  or C_Currency.C_Currency_id in (SELECT foreign_currency_id FROM aprm_finacc_transaction_v WHERE aprm_finacc_transaction_v_id=@APRM_Finacc_Transaction_V_ID@) or C_Currency.C_Currency_id in (SELECT C_Currency_ID FROM FIN_Payment WHERE FIN_Payment_ID = @FIN_Payment_ID@)]]></CODE>
 <!--FF8081813092D5DC013092DD70AD000C-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--FF8081813092D5DC013092DD70AD000C--></AD_VAL_RULE>
 
--- a/src/org/openbravo/erpCommon/ad_callouts/SE_CalculateExchangeRate.java	Fri Jun 24 16:33:21 2011 +0200
+++ b/src/org/openbravo/erpCommon/ad_callouts/SE_CalculateExchangeRate.java	Mon Jul 04 16:01:18 2011 +0200
@@ -23,6 +23,7 @@
 import javax.servlet.ServletException;
 
 import org.openbravo.advpaymentmngt.APRM_FinaccTransactionV;
+import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.model.common.invoice.Invoice;
 import org.openbravo.model.financialmgmt.payment.FIN_Payment;
@@ -40,12 +41,12 @@
   protected void execute(CalloutInfo info) throws ServletException {
     String strWindowId = info.getWindowId();
 
+    VariablesSecureApp vars = info.vars;
     String strLastFieldChanged = info.getLastFieldChanged();
-    BigDecimal originalAmt = new BigDecimal(BigDecimal.ZERO.toString());
-    BigDecimal rate = new BigDecimal(info.vars.getStringParameter("inprate"));
-    BigDecimal foreignAmt = new BigDecimal(info.vars.getStringParameter("inpforeignAmount"));
+    BigDecimal originalAmt = BigDecimal.ZERO;
+    BigDecimal rate = new BigDecimal(vars.getNumericParameter("inprate", "0"));
+    BigDecimal foreignAmt = new BigDecimal(vars.getNumericParameter("inpforeignAmount", "0"));
     try {
-      // info.addResult("inppayinAllow", paymentMethod.isPayinAllow() ? "Y" : "N");
       if (strWindowId.equals(ADWINDOW_PurchaseInvoice) || strWindowId.equals(ADWINDOW_SalesInvoice)) {
         String strcInvoiceId = info.vars.getStringParameter("inpcInvoiceId");
         Invoice invoice = OBDal.getInstance().get(Invoice.class, strcInvoiceId);
--- a/src/org/openbravo/erpCommon/ad_forms/AcctServer.java	Fri Jun 24 16:33:21 2011 +0200
+++ b/src/org/openbravo/erpCommon/ad_forms/AcctServer.java	Mon Jul 04 16:01:18 2011 +0200
@@ -30,11 +30,8 @@
 import javax.servlet.ServletException;
 
 import org.apache.log4j.Logger;
-import org.hibernate.criterion.Expression;
 import org.hibernate.criterion.Restrictions;
-import org.openbravo.advpaymentmngt.APRMPendingPaymentFromInvoice;
 import org.openbravo.advpaymentmngt.APRM_FinaccTransactionV;
-import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.base.session.OBPropertiesProvider;
 import org.openbravo.dal.core.OBContext;
@@ -51,17 +48,16 @@
 import org.openbravo.exception.NoConnectionAvailableException;
 import org.openbravo.model.common.businesspartner.CustomerAccounts;
 import org.openbravo.model.common.businesspartner.VendorAccounts;
+import org.openbravo.model.common.currency.ConversionRateDoc;
+import org.openbravo.model.common.currency.Currency;
+import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.common.invoice.ReversedInvoice;
 import org.openbravo.model.financialmgmt.accounting.FIN_FinancialAccountAccounting;
 import org.openbravo.model.financialmgmt.accounting.coa.AcctSchemaTable;
 import org.openbravo.model.financialmgmt.gl.GLItem;
 import org.openbravo.model.financialmgmt.gl.GLItemAccounts;
 import org.openbravo.model.financialmgmt.payment.FIN_FinancialAccount;
 import org.openbravo.model.financialmgmt.payment.FIN_Payment;
-import org.openbravo.model.financialmgmt.payment.FinAccPaymentMethod;
-import org.openbravo.model.common.currency.ConversionRateDoc;
-import org.openbravo.model.common.currency.Currency;
-import org.openbravo.model.common.invoice.Invoice;
-import org.openbravo.model.common.invoice.ReversedInvoice;
 
 public abstract class AcctServer {
   static Logger log4j = Logger.getLogger(AcctServer.class);
@@ -278,8 +274,8 @@
 
   /** GL Accounts */
   public static final String ACCTTYPE_PPVOffset = "60";
-  
-  /** Document Types for document level conversion rates*/
+
+  /** Document Types for document level conversion rates */
   public static final String EXCHANGE_DOCTYPE_Invoice = "318";
   public static final String EXCHANGE_DOCTYPE_Payment = "D1A97202E832470285C9B1EB026D54E2";
   public static final String EXCHANGE_DOCTYPE_Transaction = "4D8C3B3C31D1410DA046140C9F024D17";
@@ -1119,7 +1115,7 @@
         // if (log4j.isDebugEnabled()) log4j.debug
         // ("AcctServer - get converted amount (init)");
         String amt = getConvertedAmt("1", currency, acctSchema.m_C_Currency_ID, DateAcct,
-            acctSchema.m_CurrencyRateType, AD_Client_ID, AD_Org_ID, "","", conn);
+            acctSchema.m_CurrencyRateType, AD_Client_ID, AD_Org_ID, "", "", conn);
         // if (log4j.isDebugEnabled()) log4j.debug
         // ("get converted amount (end)");
         if (amt == null || amt.equals("")) {
@@ -1176,9 +1172,9 @@
       String ConvDate, String RateType, ConnectionProvider conn) {
     if (log4j.isDebugEnabled())
       log4j.debug("AcctServer - getConvertedAmount no client nor org");
-    return getConvertedAmt(Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, "", "","", "", conn);
+    return getConvertedAmt(Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, "", "", "", "", conn);
   }
-  
+
   /**
    * Convert an amount
    * 
@@ -1198,13 +1194,14 @@
       String ConvDate, String RateType, String record_ID, String docType, ConnectionProvider conn) {
     if (log4j.isDebugEnabled())
       log4j.debug("AcctServer - getConvertedAmount no client nor org");
-    return getConvertedAmt(Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, "", "",record_ID, docType, conn);
+    return getConvertedAmt(Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, "", "", record_ID,
+        docType, conn);
   }
 
   public static String getConvertedAmt(String Amt, String CurFrom_ID, String CurTo_ID,
-      String ConvDate, String RateType, String client, String org, 
-      String recordId, String docType, ConnectionProvider conn) {
-	boolean useSystemConversionRate = true;
+      String ConvDate, String RateType, String client, String org, String recordId, String docType,
+      ConnectionProvider conn) {
+    boolean useSystemConversionRate = true;
     if (log4j.isDebugEnabled())
       log4j.debug("AcctServer - getConvertedAmount - starting method - Amt : " + Amt
           + " - CurFrom_ID : " + CurFrom_ID + " - CurTo_ID : " + CurTo_ID + "- ConvDate: "
@@ -1213,7 +1210,8 @@
     if (Amt.equals(""))
       throw new IllegalArgumentException(
           "AcctServer - getConvertedAmt - required parameter missing - Amt");
-    if (CurFrom_ID.equals(CurTo_ID) || Amt.equals("0"))
+    if ((CurFrom_ID.equals(CurTo_ID) && !docType.equals(EXCHANGE_DOCTYPE_Transaction))
+        || Amt.equals("0"))
       return Amt;
     AcctServerData[] data = null;
     OBContext.setAdminMode();
@@ -1225,69 +1223,91 @@
         RateType = "S";
       data = AcctServerData.currencyConvert(conn, Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType,
           client, org);
-      //Search if exists any conversion rate at document level
-      
-      OBCriteria<ConversionRateDoc> docRateCriteria = OBDal.getInstance().createCriteria(ConversionRateDoc.class);
-      if(docType.equals(EXCHANGE_DOCTYPE_Invoice)){
-    	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID) ));
-    	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, CurFrom_ID)));
-    	  //get reversed invoice id if exist.
-    	  OBCriteria<ReversedInvoice> reversedCriteria = OBDal.getInstance().createCriteria(ReversedInvoice.class);
-    	  reversedCriteria.add(Restrictions.eq(ReversedInvoice.PROPERTY_INVOICE, OBDal.getInstance().get(Invoice.class, recordId)));
-    	  if(!reversedCriteria.list().isEmpty()){
-    		    String strDateFormat;
-    	        strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty("dateFormat.java");
-    	        final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat);
-    	        ConvDate = dateFormat.format(reversedCriteria.list().get(0).getReversedInvoice().getAccountingDate());
-    	    	data = AcctServerData.currencyConvert(conn, Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType,
-    	    	          client, org);
-    	    	docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal.getInstance().get(Invoice.class, reversedCriteria.list().get(0).getReversedInvoice().getId())));
-    	  }else{
-    		  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal.getInstance().get(Invoice.class, recordId)));	 
-        	  
-    	  }
-    	  useSystemConversionRate = false;
-    	  
-      }else if(docType.equals(EXCHANGE_DOCTYPE_Payment)){
-    	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID) ));
-    	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, CurFrom_ID)));
-    	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_PAYMENT, OBDal.getInstance().get(FIN_Payment.class, recordId)));
-    	  useSystemConversionRate = false;
-    	  
-      }else if(docType.equals(EXCHANGE_DOCTYPE_Transaction)){
-    	  
-    	  APRM_FinaccTransactionV a = OBDal.getInstance().get(APRM_FinaccTransactionV.class, recordId);
-    	  if(a.getForeignCurrency() != null && !a.getForeignCurrency().getId().equals(CurTo_ID)){
-    		  String strDateFormat;
-  	          strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty("dateFormat.java");
-  	          final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat);
-  	          Amt = a.getForeignAmount().toString();
-  	    	  data = AcctServerData.currencyConvert(conn, Amt, a.getForeignCurrency().getId(), CurTo_ID, ConvDate, RateType,
-  	    	          client, org);
-    		  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID) ));
-        	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, a.getForeignCurrency().getId())));
-    	  }else{
-    		  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID) ));
-        	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, CurFrom_ID)));
-    	  }
-    	  docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_FINANCIALACCOUNTTRANSACTION, OBDal.getInstance().get(APRM_FinaccTransactionV.class, recordId)));
-    	  useSystemConversionRate = false;
+      // Search if exists any conversion rate at document level
+
+      OBCriteria<ConversionRateDoc> docRateCriteria = OBDal.getInstance().createCriteria(
+          ConversionRateDoc.class);
+      if (docType.equals(EXCHANGE_DOCTYPE_Invoice) && recordId != null) {
+        docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal
+            .getInstance().get(Currency.class, CurTo_ID)));
+        docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal
+            .getInstance().get(Currency.class, CurFrom_ID)));
+        // get reversed invoice id if exist.
+        OBCriteria<ReversedInvoice> reversedCriteria = OBDal.getInstance().createCriteria(
+            ReversedInvoice.class);
+        reversedCriteria.add(Restrictions.eq(ReversedInvoice.PROPERTY_INVOICE, OBDal.getInstance()
+            .get(Invoice.class, recordId)));
+        if (!reversedCriteria.list().isEmpty()) {
+          String strDateFormat;
+          strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty(
+              "dateFormat.java");
+          final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat);
+          ConvDate = dateFormat.format(reversedCriteria.list().get(0).getReversedInvoice()
+              .getAccountingDate());
+          data = AcctServerData.currencyConvert(conn, Amt, CurFrom_ID, CurTo_ID, ConvDate,
+              RateType, client, org);
+          docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal
+              .getInstance().get(Invoice.class,
+                  reversedCriteria.list().get(0).getReversedInvoice().getId())));
+
+        } else {
+          docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal
+              .getInstance().get(Invoice.class, recordId)));
+
+        }
+        useSystemConversionRate = false;
+
+      } else if (docType.equals(EXCHANGE_DOCTYPE_Payment)) {
+        docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal
+            .getInstance().get(Currency.class, CurTo_ID)));
+        docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal
+            .getInstance().get(Currency.class, CurFrom_ID)));
+        docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_PAYMENT, OBDal.getInstance()
+            .get(FIN_Payment.class, recordId)));
+        useSystemConversionRate = false;
+
+      } else if (docType.equals(EXCHANGE_DOCTYPE_Transaction)) {
+
+        APRM_FinaccTransactionV a = OBDal.getInstance()
+            .get(APRM_FinaccTransactionV.class, recordId);
+        if (a.getForeignCurrency() != null) { // && !a.getForeignCurrency().getId().equals(CurTo_ID)
+          String strDateFormat;
+          strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty(
+              "dateFormat.java");
+          final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat);
+          Amt = a.getForeignAmount().toString();
+          data = AcctServerData.currencyConvert(conn, Amt, a.getForeignCurrency().getId(),
+              CurTo_ID, ConvDate, RateType, client, org);
+          docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal
+              .getInstance().get(Currency.class, CurTo_ID)));
+          docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal
+              .getInstance().get(Currency.class, a.getForeignCurrency().getId())));
+        } else {
+          docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal
+              .getInstance().get(Currency.class, CurTo_ID)));
+          docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal
+              .getInstance().get(Currency.class, CurFrom_ID)));
+        }
+        docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_FINANCIALACCOUNTTRANSACTION,
+            OBDal.getInstance().get(APRM_FinaccTransactionV.class, recordId)));
+        useSystemConversionRate = false;
       }
-      
-      if(docType.equals(EXCHANGE_DOCTYPE_Invoice) || docType.equals(EXCHANGE_DOCTYPE_Payment) || docType.equals(EXCHANGE_DOCTYPE_Transaction)){
-    	  List<ConversionRateDoc> conversionRates = docRateCriteria.list();
-    	  if(!conversionRates.isEmpty() && !useSystemConversionRate){
-        	  BigDecimal Amount = new BigDecimal(Amt);
-        	  BigDecimal AmountConverted = Amount.multiply(conversionRates.get(0).getRate());
-        	  return AmountConverted.toString();
-          }
+
+      if (docType.equals(EXCHANGE_DOCTYPE_Invoice) || docType.equals(EXCHANGE_DOCTYPE_Payment)
+          || docType.equals(EXCHANGE_DOCTYPE_Transaction)) {
+        List<ConversionRateDoc> conversionRates = docRateCriteria.list();
+        if (!conversionRates.isEmpty() && !useSystemConversionRate) {
+          BigDecimal Amount = new BigDecimal(Amt);
+          BigDecimal AmountConverted = Amount.multiply(conversionRates.get(0).getRate()).setScale(
+              2, BigDecimal.ROUND_HALF_UP);
+          return AmountConverted.toString();
+        }
       }
-      
-      
+
     } catch (ServletException e) {
       log4j.warn(e);
       e.printStackTrace();
-    }finally {
+    } finally {
       OBContext.restorePreviousMode();
     }
     if (data == null || data.length == 0) {
--- a/src/org/openbravo/erpCommon/ad_forms/DocFINPayment.java	Fri Jun 24 16:33:21 2011 +0200
+++ b/src/org/openbravo/erpCommon/ad_forms/DocFINPayment.java	Mon Jul 04 16:01:18 2011 +0200
@@ -331,13 +331,14 @@
         }
 
         if ("".equals(line.getC_GLItem_ID())) {
-          fact.createLine(
-              line,
-              getAccountBPartner(
-                  (line.m_C_BPartner_ID == null || line.m_C_BPartner_ID.equals("")) ? this.C_BPartner_ID
-                      : line.m_C_BPartner_ID, as, isReceipt, isPrepayment, conn), C_Currency_ID,
-              (isReceipt ? "" : bpAmount), (isReceipt ? bpAmount : ""), Fact_Acct_Group_ID,
-              nextSeqNo(SeqNo), DocumentType, invoiceAccountingDate, null, EXCHANGE_DOCTYPE_Invoice, line.getInvoice().getId(), conn);
+          fact
+              .createLine(line,
+                  getAccountBPartner((line.m_C_BPartner_ID == null || line.m_C_BPartner_ID
+                      .equals("")) ? this.C_BPartner_ID : line.m_C_BPartner_ID, as, isReceipt,
+                      isPrepayment, conn), C_Currency_ID, (isReceipt ? "" : bpAmount),
+                  (isReceipt ? bpAmount : ""), Fact_Acct_Group_ID, nextSeqNo(SeqNo), DocumentType,
+                  invoiceAccountingDate, null, EXCHANGE_DOCTYPE_Invoice,
+                  line.getInvoice() != null ? line.getInvoice().getId() : null, conn);
         } else {
           fact.createLine(
               line,
@@ -358,11 +359,11 @@
             payment.getFinancialTransactionConvertRate(), MathContext.DECIMAL64);
       }
       fact.createLine(null, getAccount(conn, payment.getPaymentMethod(), payment.getAccount(), as,
-          payment.isReceipt()), C_Currency_ID,
-          (payment.isReceipt() ? payment.getAmount().toString() : ""), (payment.isReceipt() ? ""
-              : payment.getAmount().toString()), Fact_Acct_Group_ID, "999999", DocumentType, null,
-          accountToSchemaConversionRate, EXCHANGE_DOCTYPE_Payment, payment.getId(),conn);
-     
+          payment.isReceipt()), C_Currency_ID, (payment.isReceipt() ? payment.getAmount()
+          .toString() : ""), (payment.isReceipt() ? "" : payment.getAmount().toString()),
+          Fact_Acct_Group_ID, "999999", DocumentType, null, accountToSchemaConversionRate,
+          EXCHANGE_DOCTYPE_Payment, payment.getId(), conn);
+
       // Pre-payment is consumed when Used Credit Amount not equals Zero. When consuming Credit no
       // credit is generated
       if (new BigDecimal(usedAmount).compareTo(ZERO) != 0
--- a/src/org/openbravo/erpCommon/ad_forms/FactLine.java	Fri Jun 24 16:33:21 2011 +0200
+++ b/src/org/openbravo/erpCommon/ad_forms/FactLine.java	Mon Jul 04 16:01:18 2011 +0200
@@ -23,12 +23,10 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.text.SimpleDateFormat;
-import java.util.List;
 
 import javax.servlet.ServletException;
 
 import org.apache.log4j.Logger;
-import org.openbravo.advpaymentmngt.APRMPendingPaymentFromInvoice;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.base.session.OBPropertiesProvider;
 import org.openbravo.dal.service.OBDal;
@@ -39,7 +37,6 @@
 import org.openbravo.model.common.invoice.Invoice;
 import org.openbravo.model.financialmgmt.payment.FIN_FinaccTransaction;
 import org.openbravo.model.financialmgmt.payment.FIN_Payment;
-import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetailV;
 
 public class FactLine {
   static Logger log4jFactLine = Logger.getLogger(FactLine.class);
@@ -80,7 +77,7 @@
   public String m_SeqNo;
   public String m_DocBaseType;
   public String m_ConversionType;
-  
+
   public String EXCHANGE_DOCTYPE_Invoice = "318";
   public String EXCHANGE_DOCTYPE_Payment = "D1A97202E832470285C9B1EB026D54E2";
   public String EXCHANGE_DOCTYPE_Transaction = "4D8C3B3C31D1410DA046140C9F024D17";
@@ -244,62 +241,76 @@
       return false;
     }
     m_AmtAcctDr = AcctServer.getConvertedAmt(m_AmtSourceDr, m_C_Currency_ID, Acct_Currency_ID,
-        ConversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, m_Record_ID, m_AD_Table_ID, conn);
+        ConversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, m_Record_ID,
+        m_AD_Table_ID, conn);
     if (m_AmtAcctDr == null || m_AmtAcctDr.equals(""))
       return false;
     m_AmtAcctCr = AcctServer.getConvertedAmt(m_AmtSourceCr, m_C_Currency_ID, Acct_Currency_ID,
-        ConversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, m_Record_ID, m_AD_Table_ID, conn);
+        ConversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, m_Record_ID,
+        m_AD_Table_ID, conn);
     return true;
   } // convert
-  
+
   public boolean convertByDocumentData(String Acct_Currency_ID, String CurrencyRateType,
-	      String documentId, String AD_Table_ID, ConnectionProvider conn) {
-	    String docType="";
-	    String strDateFormat;
-        strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty("dateFormat.java");
-        final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat);
-	    String conversionDate="";
-	    
-	    // Document has no currency
-	    log4jFactLine.debug("convert - beginning");
-	    log4jFactLine.debug("convert - m_C_Currency_ID : " + m_C_Currency_ID);
-	    if (m_C_Currency_ID == null || m_C_Currency_ID.equals(AcctServer.NO_CURRENCY))
-	      m_C_Currency_ID = Acct_Currency_ID;
-	    log4jFactLine.debug("convert - Acct_Currency_ID : " + Acct_Currency_ID);
-	    if (Acct_Currency_ID.equals(m_C_Currency_ID)) {
-	      m_AmtAcctDr = m_AmtSourceDr;
-	      m_AmtAcctCr = m_AmtSourceCr;
-	      return true;
-	    }
-	    if (m_docVO == null) {
-	      log4jFactLine.warn("convert - No Document VO");
-	      return false;
-	    }
-	    if(AD_Table_ID.equals(EXCHANGE_DOCTYPE_Invoice)){
-	    	//Get Invoice
-	    	docType= EXCHANGE_DOCTYPE_Invoice;
-		    Invoice invoice = OBDal.getInstance().get(Invoice.class, documentId);
-		    conversionDate = dateFormat.format(invoice.getAccountingDate());
-		    	//SimpleDateFormat.getInstance().format(invoice.getAccountingDate());
-	    }else if(AD_Table_ID.equals(EXCHANGE_DOCTYPE_Payment)){
-	    	docType= EXCHANGE_DOCTYPE_Payment;
-		    FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, documentId);
-		    conversionDate = dateFormat.format(payment.getPaymentDate());
-	    }else if(AD_Table_ID.equals(EXCHANGE_DOCTYPE_Transaction)){
-	    	docType= EXCHANGE_DOCTYPE_Transaction;
-	    	FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class,
-	    	        documentId);
-	    	conversionDate = dateFormat.format(transaction.getDateAcct());
-	    }
-	    
-	    m_AmtAcctDr = AcctServer.getConvertedAmt(m_AmtSourceDr, m_C_Currency_ID, Acct_Currency_ID,
-	    		conversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, documentId, docType, conn);
-	    if (m_AmtAcctDr == null || m_AmtAcctDr.equals(""))
-	      return false;
-	    m_AmtAcctCr = AcctServer.getConvertedAmt(m_AmtSourceCr, m_C_Currency_ID, Acct_Currency_ID,
-	    		conversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, documentId, docType, conn);
-	    return true;
-	  } // convert
+      String documentId, String AD_Table_ID, ConnectionProvider conn) {
+    String docType = "";
+    String strDateFormat;
+    strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty(
+        "dateFormat.java");
+    final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat);
+    String conversionDate = "";
+
+    // Document has no currency
+    log4jFactLine.debug("convert - beginning");
+    log4jFactLine.debug("convert - m_C_Currency_ID : " + m_C_Currency_ID);
+    if (m_C_Currency_ID == null || m_C_Currency_ID.equals(AcctServer.NO_CURRENCY))
+      m_C_Currency_ID = Acct_Currency_ID;
+    log4jFactLine.debug("convert - Acct_Currency_ID : " + Acct_Currency_ID);
+    if (Acct_Currency_ID.equals(m_C_Currency_ID)
+        && !AD_Table_ID.equals(EXCHANGE_DOCTYPE_Transaction)) {
+      m_AmtAcctDr = m_AmtSourceDr;
+      m_AmtAcctCr = m_AmtSourceCr;
+      return true;
+    }
+    if (m_docVO == null) {
+      log4jFactLine.warn("convert - No Document VO");
+      return false;
+    }
+    if (AD_Table_ID.equals(EXCHANGE_DOCTYPE_Invoice)) {
+      // Get Invoice
+      docType = EXCHANGE_DOCTYPE_Invoice;
+      if (documentId != null) {
+        Invoice invoice = OBDal.getInstance().get(Invoice.class, documentId);
+        conversionDate = dateFormat.format(invoice.getAccountingDate());
+      }
+      // SimpleDateFormat.getInstance().format(invoice.getAccountingDate());
+    } else if (AD_Table_ID.equals(EXCHANGE_DOCTYPE_Payment)) {
+      docType = EXCHANGE_DOCTYPE_Payment;
+      FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, documentId);
+      conversionDate = dateFormat.format(payment.getPaymentDate());
+    } else if (AD_Table_ID.equals(EXCHANGE_DOCTYPE_Transaction)) {
+
+      docType = EXCHANGE_DOCTYPE_Transaction;
+      FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class,
+          documentId);
+      if (transaction.getForeignCurrency() == null) {
+        m_AmtAcctDr = m_AmtSourceDr;
+        m_AmtAcctCr = m_AmtSourceCr;
+        return true;
+      }
+      conversionDate = dateFormat.format(transaction.getDateAcct());
+    }
+
+    m_AmtAcctDr = AcctServer.getConvertedAmt(m_AmtSourceDr, m_C_Currency_ID, Acct_Currency_ID,
+        conversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, documentId,
+        docType, conn);
+    if (m_AmtAcctDr == null || m_AmtAcctDr.equals(""))
+      return false;
+    m_AmtAcctCr = AcctServer.getConvertedAmt(m_AmtSourceCr, m_C_Currency_ID, Acct_Currency_ID,
+        conversionDate, CurrencyRateType, m_docVO.AD_Client_ID, m_docVO.AD_Org_ID, documentId,
+        docType, conn);
+    return true;
+  } // convert
 
   /**
    * Convert to Accounted Currency