Skip to content

Commit

Permalink
now possble to apply a payment on an invoice of another currency, rem…
Browse files Browse the repository at this point in the history
…oved the convertinvoice service as suggested by jacopo.

git-svn-id: https://svn.apache.org/repos/asf/ofbiz/trunk@701022 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
hansbak committed Oct 2, 2008
1 parent e0bae8f commit afafe0e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -506,57 +506,6 @@ under the License.
<call-simple-method method-name="copyInvoice"/>
</simple-method>

<simple-method method-name="convertInvoiceToOtherCurrency" short-description="service to convert an invoice to another currency having the original currency still there using the exchange rate table.">
<entity-one entity-name="Invoice" value-name="invoice"/>
<if-empty field="invoice">
<add-error><fail-message message="Invoice not found"/></add-error>
</if-empty>
<entity-one entity-name="Uom" value-name="newCurrencyUom">
<field-map field-name="uomId" env-name="parameters.newCurrencyUomId"/>
</entity-one>
<if-empty field="newCurrencyUom">
<add-error><fail-message message="New Currency Code not found"/></add-error>
</if-empty>
<if-compare-field field="parameters.newCurrencyUomId" operator="equals" to-field="invoice.currencyUomId">
<add-error><fail-message message="Invoice already has the requested currency"/></add-error>
</if-compare-field>
<check-errors/>

<get-related value-name="invoice" relation-name="InvoiceItem" list-name="invoiceItems"/>
<iterate list-name="invoiceItems" entry-name="invoiceItem">
<calculate field-name="invoiceItem.amount" type="Double" decimal-scale="15">
<calcop operator="divide">
<calcop operator="get" field-name="invoiceItem.amount"/>
<calcop operator="get" field-name="parameters.exchangeRate"/>
</calcop>
</calculate>
<store-value value-name="invoiceItem"/>
</iterate>

<entity-one entity-name="UomConversionDated" value-name="uomValue">
<field-map field-name="uomId" env-name="parameters.newCurrencyUomId"/>
<field-map field-name="uomIdTo" env-name="invoice.currencyUomId"/>
<field-map field-name="fromDate" env-name="invoice.invoiceDate"/>
</entity-one>

<make-value entity-name="UomConversionDated" value-name="uomConversionDated"/>
<set field="uomConversionDated.uomId" from-field="parameters.newCurrencyUomId"/>
<set field="uomConversionDated.uomIdTo" from-field="invoice.currencyUomId"/>
<set field="uomConversionDated.fromDate" from-field="invoice.invoiceDate"/>
<set field="uomConversionDated.thruDate" from-field="invoice.invoiceDate"/>
<set field="uomConversionDated.conversionFactor" from-field="parameters.exchangeRate"/>
<if-empty field="uomValue">
<create-value value-name="uomConversionDated"/>
<else>
<store-value value-name="uomConversionDated"/>
</else>
</if-empty>

<set field="invoice.currencyUomId" from-field="parameters.newCurrencyUomId"/>
<store-value value-name="invoice"/>
<field-to-result field-name="parameters.invoiceId" result-name="invoiceId"/>
</simple-method>

<!-- ===============subroutine services =================-->
<simple-method method-name="InvoiceStatusInProgress" short-description="Check if the invoiceStatus is in progress">
<!-- find the current header record -->
Expand Down
7 changes: 0 additions & 7 deletions applications/accounting/servicedef/services_invoice.xml
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,4 @@ under the License.
<auto-attributes mode="IN" include="pk" optional="false"/>
<auto-attributes mode="IN" include="nonpk" optional="true"/>
</service>
<service name="convertInvoiceToOtherCurrency" engine="simple"
location="org/ofbiz/accounting/invoice/InvoiceServices.xml" invoke="convertInvoiceToOtherCurrency">
<description>service to convert an invoice to another currency having the original currency still there using the exchange rate table.</description>
<attribute name="invoiceId" mode="INOUT" type="String"/>
<attribute name="newCurrencyUomId" mode="IN" type="String"/>
<attribute name="exchangeRate" mode="IN" type="Double"/>
</service>
</services>
Original file line number Diff line number Diff line change
Expand Up @@ -2507,31 +2507,19 @@ public static Map updatePaymentApplicationDefBd(DispatchContext dctx, Map contex
!payment.getString("currencyUomId").equals(invoice.getString("currencyUomId"))) {
Debug.logInfo(UtilProperties.getMessage(resource, "AccountingInvoicePaymentCurrencyProblem",
UtilMisc.toMap("invoiceCurrency", invoice.getString("currencyUomId"), "paymentCurrency", payment.getString("currencyUomId")),locale), module);
Debug.logInfo("will convert invoice currency according original currency amount on payment", module);
Debug.logInfo("will try to apply payment on the actualCurrency amount on payment", module);

if (payment.get("actualCurrencyAmount") == null || payment.get("actualCurrencyUomId") == null) {
errorMessageList.add("in order to properly convert the Invoice we need the actual currency and actual amount on the payment");
errorMessageList.add("Actual amounts are required in the currency of the invoice to make this work....");
} else {
if (!payment.get("actualCurrencyUomId").equals(invoice.get("currencyUomId"))) {
errorMessageList.add("actual currency on payment not the same as original invoice currency");
} else {
// calculate exchange rate, convert/retrieve invoice
try {
Double exchangeRate = new Double( payment.getDouble("actualCurrencyAmount").doubleValue() / payment.getDouble("amount").doubleValue());
Map inMap = UtilMisc.toMap("userLogin", userLogin, "invoiceId", invoiceId, "newCurrencyUomId", payment.getString("currencyUomId"));
inMap.put("exchangeRate", exchangeRate);
dispatcher.runSync("convertInvoiceToOtherCurrency", inMap);
invoice = delegator.findByPrimaryKey("Invoice", UtilMisc.toMap("invoiceId", invoiceId));
} catch (GenericServiceException se) {
Debug.logError(se, se.getMessage(), module);
return ServiceUtil.returnError(se.getMessage());
} catch (GenericEntityException e) {
ServiceUtil.returnError(e.getMessage());
}
}
}
}
paymentApplyAvailable = payment.getBigDecimal("actualCurrencyAmount").subtract(PaymentWorker.getPaymentAppliedBd(payment)).setScale(decimals,rounding);
if (amountApplied.signum() == 0) {
amountAppliedMax = paymentApplyAvailable;
}


}

// check if the invoice already covered by payments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.ofbiz.accounting.payment;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
Expand Down Expand Up @@ -253,6 +254,32 @@ public static BigDecimal getPaymentAppliedBd(GenericDelegator delegator, String

return getPaymentAppliedBd(payment);
}
/**
* Method to return the amount applied converted to the currency of payment
* @param String paymentApplicationId
* @return the applied amount as BigDecimal
*/
public static BigDecimal getPaymentAppliedAmount(GenericDelegator delegator, String paymentApplicationId) {
GenericValue paymentApplication = null;
BigDecimal appliedAmount = BigDecimal.ZERO;
try {
paymentApplication = delegator.findByPrimaryKey("PaymentApplication", UtilMisc.toMap("paymentApplicationId", paymentApplicationId));
appliedAmount = paymentApplication.getBigDecimal("amountApplied");
if (paymentApplication.get("paymentId") != null) {
GenericValue payment = paymentApplication.getRelatedOne("Payment");
if (paymentApplication.get("invoiceId") != null && payment.get("actualCurrencyAmount") != null && payment.get("actualCurrencyUomId") != null) {
GenericValue invoice = paymentApplication.getRelatedOne("Invoice");
if (payment.getString("actualCurrencyUomId").equals(invoice.getString("currencyUomId"))) {
appliedAmount = appliedAmount.multiply(payment.getBigDecimal("amount")).divide(payment.getBigDecimal("actualCurrencyAmount"),new MathContext(100));
}
}
}
} catch (GenericEntityException e) {
Debug.logError(e, "Problem getting Payment", module);
}
return appliedAmount;
}

/**
* Method to return the total amount of an payment which is applied to a payment
* @param payment GenericValue object of the Payment
Expand All @@ -267,30 +294,24 @@ public static BigDecimal getPaymentAppliedBd(GenericValue payment) {
List paymentApplications = null;
try {
paymentApplications = payment.getRelated("PaymentApplication");
} catch (GenericEntityException e) {
Debug.logError(e, "Trouble getting paymentApplicationlist", module);
}
if (UtilValidate.isNotEmpty(paymentApplications)) {
Iterator p = paymentApplications.iterator();
while (p.hasNext()) {
GenericValue paymentApplication = (GenericValue) p.next();
paymentApplied = paymentApplied.add(paymentApplication.getBigDecimal("amountApplied")).setScale(decimals,rounding);
}
}
// check for payment to payment applications
paymentApplications = null;
try {
paymentApplications = payment.getRelated("ToPaymentApplication");
} catch (GenericEntityException e) {
Debug.logError(e, "Trouble getting the 'to' paymentApplicationlist", module);
}
if (UtilValidate.isNotEmpty(paymentApplications)) {
Iterator p = paymentApplications.iterator();
while (p.hasNext()) {
GenericValue paymentApplication = (GenericValue) p.next();
paymentApplied = paymentApplied.add(paymentApplication.getBigDecimal("amountApplied")).setScale(decimals,rounding);
if (UtilValidate.isNotEmpty(paymentApplications)) {
Iterator p = paymentApplications.iterator();
while (p.hasNext()) {
GenericValue paymentApplication = (GenericValue) p.next();
BigDecimal amountApplied = paymentApplication.getBigDecimal("amountApplied");
// check currency invoice and if different convert amount applied for display
if (paymentApplication.get("invoiceId") != null && payment.get("actualCurrencyAmount") != null && payment.get("actualCurrencyUomId") != null) {
GenericValue invoice = paymentApplication.getRelatedOne("Invoice");
if (payment.getString("actualCurrencyUomId").equals(invoice.getString("currencyUomId"))) {
amountApplied = amountApplied.multiply(payment.getBigDecimal("amount")).divide(payment.getBigDecimal("actualCurrencyAmount"),new MathContext(100));
}
}
paymentApplied = paymentApplied.add(amountApplied).setScale(decimals,rounding);
}
}
}
} catch (GenericEntityException e) {
Debug.logError(e, "Trouble getting entities", module);
}
return paymentApplied;
}
public static double getPaymentNotApplied(GenericValue payment) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,76 +24,68 @@ import org.ofbiz.base.util.collections.*;
import org.ofbiz.accounting.invoice.*;
import org.ofbiz.accounting.payment.*;
import org.ofbiz.accounting.util.UtilAccounting;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.entity.condition.EntityExpr;
import org.ofbiz.entity.condition.EntityConditionList;
import java.math.*;
import java.text.NumberFormat;

paymentId = parameters.paymentId;
payment = delegator.findByPrimaryKey("Payment", [paymentId : paymentId]);

decimals = UtilNumber.getBigDecimalScale("invoice.decimals");
rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding");

//retrieve invoices for the related parties which have not been (fully) applied yet and which have the same currency.
List invoices = delegator.findByAnd("Invoice", [partyId : payment.partyIdFrom, partyIdFrom : payment.partyIdTo, currencyUomId : payment.currencyUomId], ["invoiceDate"]);
if (invoices) {
invoicesList = []; // to pass back to the screeen list of unapplied invoices
paymentApplied = PaymentWorker.getPaymentAppliedBd(payment);
paymentToApply = payment.getBigDecimal("amount").setScale(decimals,rounding).subtract(paymentApplied);
invoices.each { invoice ->
invoiceAmount = InvoiceWorker.getInvoiceTotalBd(invoice).setScale(decimals,rounding);
invoiceApplied = InvoiceWorker.getInvoiceAppliedBd(invoice).setScale(decimals,rounding);
if (!invoiceAmount.equals(invoiceApplied) &&
!invoice.statusId.equals("INVOICE_CANCELLED") &&
!invoice.statusId.equals("INVOICE_IN_PROCESS")) {
// put in the map
invoiceToApply = invoiceAmount.subtract(invoiceApplied);
invoiceMap = [:];
invoiceMap.invoiceId = invoice.invoiceId;
invoiceMap.currencyUomId = invoice.currencyUomId;
invoiceMap.amount = invoiceAmount;
invoiceMap.description = invoice.description;
invoiceMap.invoiceDate = invoice.invoiceDate.toString().substring(0,10); // display only YYYY-MM-DD
invoiceMap.amountApplied = invoiceApplied;
if (paymentToApply.compareTo(invoiceToApply) < 0 ) {
invoiceMap.amountToApply = paymentToApply;
} else {
invoiceMap.amountToApply = invoiceToApply;
}
invoicesList.add(invoiceMap);
}
}
context.invoices = invoicesList;
}
exprList = [EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, payment.partyIdFrom),
EntityCondition.makeCondition("partyIdFrom", EntityOperator.EQUALS, payment.partyIdTo)];
partyCond = EntityCondition.makeCondition(exprList, EntityOperator.OR);

exprList1 = [EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "INVOICE_APPROVED"),
EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "INVOICE_SEND"),
EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "INVOICE_READY"),
EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "INVOICE_RECEIVED")];
statusCond = EntityCondition.makeCondition(exprList1, EntityOperator.OR);

currCond = EntityCondition.makeCondition("currencyUomId", EntityOperator.EQUALS, payment.currencyUomId);
actualCurrCond = EntityCondition.makeCondition("currencyUomId", EntityOperator.EQUALS, payment.actualCurrencyUomId);

//retrieve invoices for the related parties which have not been (fully) applied yet and which have another currency
invoices = delegator.findByAnd("Invoice", [partyId : payment.partyIdFrom, partyIdFrom : payment.partyIdTo], ["invoiceDate"]);
// remove same currencies
for (int ind=0; ind < invoices.size(); ind++ ) {
if (invoices[ind].currencyUomId.equals(payment.currencyUomId)) {
invoices.remove(ind);
topCond = EntityCondition.makeCondition([partyCond, statusCond, currCond], EntityOperator.AND);
topCondActual = EntityCondition.makeCondition([partyCond, statusCond, actualCurrCond], EntityOperator.AND);
fields = new HashSet(["invoiceId", "currencyUomId", "description", "invoiceDate"]);

//retrieve invoices for the related parties which have not been (fully) applied yet and which have the same currency as the payment
invoices = delegator.findList("Invoice", topCond, fields, ["invoiceDate"], null, false);
context.invoices = getInvoices(invoices, false);
//retrieve invoices for the related parties which have not been (fully) applied yet and which have the same originalCurrency as the payment
invoices = delegator.findList("Invoice", topCondActual, fields, ["invoiceDate"], null, false);
context.invoicesOtherCurrency = getInvoices(invoices, true);

List getInvoices(List invoices, boolean actual) {
if (invoices) {
invoicesList = []; // to pass back to the screeen list of unapplied invoices
paymentApplied = PaymentWorker.getPaymentAppliedBd(payment);
paymentToApply = payment.getBigDecimal("amount").setScale(decimals,rounding).subtract(paymentApplied);
if (actual) {
paymentToApply = payment.getBigDecimal("actualCurrencyAmount").setScale(decimals,rounding).subtract(paymentApplied);
}
invoices.each { invoice ->
invoiceAmount = InvoiceWorker.getInvoiceTotalBd(invoice).setScale(decimals,rounding);
invoiceApplied = InvoiceWorker.getInvoiceAppliedBd(invoice).setScale(decimals,rounding);
invoiceToApply = invoiceAmount.subtract(invoiceApplied);
if (invoiceToApply.signum() == 1) {
invoiceMap = [:];
invoiceMap.putAll(invoice);
invoiceMap.amount = invoiceAmount;
invoiceMap.description = invoice.description;
invoiceMap.amountApplied = invoiceApplied;
if (paymentToApply.compareTo(invoiceToApply) < 0 ) {
invoiceMap.amountToApply = paymentToApply;
} else {
invoiceMap.amountToApply = invoiceToApply;
}
invoicesList.add(invoiceMap);
}
}
return invoicesList;
}
}
if (invoices) {
invoicesList = []; // to pass back to the screeen list of unapplied invoices
paymentApplied = PaymentWorker.getPaymentAppliedBd(payment);
paymentToApply = payment.getBigDecimal("amount").setScale(decimals,rounding).subtract(paymentApplied);
invoices.each { invoice ->
invoiceAmount = InvoiceWorker.getInvoiceTotalBd(invoice).setScale(decimals,rounding);
invoiceApplied = InvoiceWorker.getInvoiceAppliedBd(invoice).setScale(decimals,rounding);
if (!invoiceAmount.equals(invoiceApplied) &&
!invoice.statusId.equals("INVOICE_CANCELLED") &&
!invoice.statusId.equals("INVOICE_IN_PROCESS")) {
// put in the map
invoiceToApply = invoiceAmount.subtract(invoiceApplied);
invoiceMap = [:];
invoiceMap.invoiceId = invoice.invoiceId;
invoiceMap.currencyUomId = invoice.currencyUomId;
invoiceMap.amount = invoiceAmount;
invoiceMap.description = invoice.description;
invoiceMap.invoiceDate = invoice.invoiceDate.toString().substring(0,10); // display only YYYY-MM-DD
invoiceMap.amountApplied = invoiceApplied;
invoicesList.add(invoiceMap);
}
}
context.invoicesOtherCurrency = invoicesList;
}
Loading

0 comments on commit afafe0e

Please sign in to comment.