}
return updatePaymentApplication(dctx, context);
}
public static Map<String, Object> updatePaymentApplicationDefBd(DispatchContext dctx, Map<String, Object> context) {
Delegator delegator = dctx.getDelegator();
Locale locale = (Locale) context.get("locale");
if (DECIMALS == -1 || ROUNDING == -1) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"AccountingAritmeticPropertiesNotConfigured", locale));
}
if (!context.containsKey("useHighestAmount")) {
context.put("useHighestAmount","Y");
}
String defaultInvoiceProcessing = UtilProperties.getPropertyValue("AccountingConfig","invoiceProcessing");
boolean debug = true; // show processing messages in the log..or not....
// a 'y' in invoiceProssesing will reverse the default processing
String changeProcessing = (String) context.get("invoiceProcessing");
String invoiceId = (String) context.get("invoiceId");
String invoiceItemSeqId = (String) context.get("invoiceItemSeqId");
String paymentId = (String) context.get("paymentId");
String toPaymentId = (String) context.get("toPaymentId");
String paymentApplicationId = (String) context.get("paymentApplicationId");
BigDecimal amountApplied = (BigDecimal) context.get("amountApplied");
String billingAccountId = (String) context.get("billingAccountId");
String taxAuthGeoId = (String) context.get("taxAuthGeoId");
String useHighestAmount = (String) context.get("useHighestAmount");
List<String> errorMessageList = FastList.newInstance();
if (debug) Debug.logInfo("updatePaymentApplicationDefBd input parameters..." +
" defaultInvoiceProcessing: " + defaultInvoiceProcessing +
" changeDefaultInvoiceProcessing: " + changeProcessing +
" useHighestAmount: " + useHighestAmount +
" paymentApplicationId: " + paymentApplicationId +
" PaymentId: " + paymentId +
" InvoiceId: " + invoiceId +
" InvoiceItemSeqId: " + invoiceItemSeqId +
" BillingAccountId: " + billingAccountId +
" toPaymentId: " + toPaymentId +
" amountApplied: " + amountApplied +
" TaxAuthGeoId: " + taxAuthGeoId, module);
if (changeProcessing == null) {
changeProcessing = "N"; // not provided, so no change
}
boolean invoiceProcessing = true;
if (defaultInvoiceProcessing.equals("YY")) {
invoiceProcessing = true;
} else if (defaultInvoiceProcessing.equals("NN")) {
invoiceProcessing = false;
} else if (defaultInvoiceProcessing.equals("Y")) {
invoiceProcessing = !"Y".equals(changeProcessing);
} else if (defaultInvoiceProcessing.equals("N")) {
invoiceProcessing = "Y".equals(changeProcessing);
}
// on a new paymentApplication check if only billing or invoice or tax
// id is provided not 2,3... BUT a combination of billingAccountId and invoiceId is permitted - that's how you use a
// Billing Account to pay for an Invoice
if (paymentApplicationId == null) {
int count = 0;
if (invoiceId != null) count++;
if (toPaymentId != null) count++;
if (billingAccountId != null) count++;
if (taxAuthGeoId != null) count++;
if ((billingAccountId != null) && (invoiceId != null)) count--;
if (count != 1) {
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingSpecifyInvoiceToPaymentBillingAccountTaxGeoId", locale));
}
}
// avoid null pointer exceptions.
if (amountApplied == null) amountApplied = ZERO;
// makes no sense to have an item numer without an invoice number
if (invoiceId == null) invoiceItemSeqId = null;
// retrieve all information and perform checking on the retrieved info.....
// Payment.....
BigDecimal paymentApplyAvailable = ZERO;
// amount available on the payment reduced by the already applied amounts
BigDecimal amountAppliedMax = ZERO;
// the maximum that can be applied taking payment,invoice,invoiceitem,billing account in concideration
// if maxApplied is missing, this value can be used,
// Payment this should be checked after the invoice checking because it is possible the currency is changed
GenericValue payment = null;
String currencyUomId = null;
if (paymentId == null || paymentId.equals("")) {
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingPaymentIdBlankNotSupplied", locale));
} else {
try {
payment = delegator.findByPrimaryKey("Payment", UtilMisc.toMap("paymentId", paymentId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (payment == null) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentRecordNotFound", UtilMisc.toMap("paymentId", paymentId), locale));
}
paymentApplyAvailable = payment.getBigDecimal("amount").subtract(PaymentWorker.getPaymentApplied(payment)).setScale(DECIMALS,ROUNDING);
if (payment.getString("statusId").equals("PMNT_CANCELLED")) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentCancelled", UtilMisc.toMap("paymentId", paymentId), locale));
}
if (payment.getString("statusId").equals("PMNT_CONFIRMED")) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentConfirmed", UtilMisc.toMap("paymentId", paymentId), locale));
}
currencyUomId = payment.getString("currencyUomId");
// if the amount to apply is 0 give it amount the payment still need
// to apply
if (amountApplied.signum() == 0) {
amountAppliedMax = paymentApplyAvailable;
}
}
// the "TO" Payment.....
BigDecimal toPaymentApplyAvailable = ZERO;
GenericValue toPayment = null;
if (toPaymentId != null && !toPaymentId.equals("")) {
try {
toPayment = delegator.findByPrimaryKey("Payment", UtilMisc.toMap("paymentId", toPaymentId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (toPayment == null) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentRecordNotFound", UtilMisc.toMap("paymentId", toPaymentId), locale));
}
toPaymentApplyAvailable = toPayment.getBigDecimal("amount").subtract(PaymentWorker.getPaymentApplied(toPayment)).setScale(DECIMALS,ROUNDING);
if (toPayment.getString("statusId").equals("PMNT_CANCELLED")) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentCancelled", UtilMisc.toMap("paymentId", paymentId), locale));
}
if (toPayment.getString("statusId").equals("PMNT_CONFIRMED")) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentConfirmed", UtilMisc.toMap("paymentId", paymentId), locale));
}
// if the amount to apply is less then required by the payment reduce it
if (amountAppliedMax.compareTo(toPaymentApplyAvailable) > 0) {
amountAppliedMax = toPaymentApplyAvailable;
}
if (paymentApplicationId == null) {
// only check for new application records, update on existing records is checked in the paymentApplication section
if (toPaymentApplyAvailable.signum() == 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentAlreadyApplied", UtilMisc.toMap("paymentId", toPaymentId), locale));
} else {
// check here for too much application if a new record is
// added (paymentApplicationId == null)
if (amountApplied.compareTo(toPaymentApplyAvailable) > 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentLessRequested",
UtilMisc.<String, Object>toMap("paymentId",toPaymentId,
"paymentApplyAvailable", toPaymentApplyAvailable,
"amountApplied", amountApplied, "isoCode", currencyUomId), locale));
}
}
}
// check if at least one send is the same as one receiver on the other payment
if (!payment.getString("partyIdFrom").equals(toPayment.getString("partyIdTo")) &&
!payment.getString("partyIdTo").equals(toPayment.getString("partyIdFrom"))) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingFromPartySameToParty", locale));
}
if (debug) Debug.logInfo("toPayment info retrieved and checked...", module);
}
// assign payment to billing account if the invoice is assigned to this billing account
if (invoiceId != null) {
GenericValue invoice = null;
try {
invoice = delegator.findByPrimaryKey("Invoice", UtilMisc.toMap("invoiceId", invoiceId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (invoice == null) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceNotFound", UtilMisc.toMap("invoiceId", invoiceId), locale));
} else {
if (invoice.getString("billingAccountId") != null) {
billingAccountId = invoice.getString("billingAccountId");
}
}
}
// billing account
GenericValue billingAccount = null;
if (billingAccountId != null && !billingAccountId.equals("")) {
try {
billingAccount = delegator.findByPrimaryKey("BillingAccount",
UtilMisc.toMap("billingAccountId", billingAccountId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (billingAccount == null) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingBillingAccountNotFound", UtilMisc.toMap("billingAccountId", billingAccountId), locale));
}
// check the currency
if (billingAccount.get("accountCurrencyUomId") != null && currencyUomId != null &&
!billingAccount.getString("accountCurrencyUomId").equals(currencyUomId)) {
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingBillingAccountCurrencyProblem",
UtilMisc.toMap("billingAccountId", billingAccountId,
"accountCurrencyUomId", billingAccount.getString("accountCurrencyUomId"),
"paymentId", paymentId, "paymentCurrencyUomId", currencyUomId), locale));
}
if (debug) Debug.logInfo("Billing Account info retrieved and checked...", module);
}
// get the invoice (item) information
BigDecimal invoiceApplyAvailable = ZERO;
// amount available on the invoice reduced by the already applied amounts
BigDecimal invoiceItemApplyAvailable = ZERO;
// amount available on the invoiceItem reduced by the already applied amounts
GenericValue invoice = null;
GenericValue invoiceItem = null;
if (invoiceId != null) {
try {
invoice = delegator.findByPrimaryKey("Invoice", UtilMisc.toMap("invoiceId", invoiceId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (invoice == null) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceNotFound", UtilMisc.toMap("invoiceId", invoiceId), locale));
} else { // check the invoice and when supplied the invoice item...
if (invoice.getString("statusId").equals("INVOICE_CANCELLED")) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceCancelledCannotApplyTo", UtilMisc.toMap("invoiceId", invoiceId), locale));
}
// check the currency
if (currencyUomId != null && invoice.get("currencyUomId") != null &&
!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 try to apply payment on the actualCurrency amount on payment", module);
if (payment.get("actualCurrencyAmount") == null || payment.get("actualCurrencyUomId") == null) {
errorMessageList.add("Actual amounts are required in the currency of the invoice to make this work....");
} else {
currencyUomId = payment.getString("actualCurrencyUomId");
if (!currencyUomId.equals(invoice.getString("currencyUomId"))) {
errorMessageList.add("actual currency on payment (" + currencyUomId + ") not the same as original invoice currency (" + invoice.getString("currencyUomId") + ")");
}
}
paymentApplyAvailable = payment.getBigDecimal("actualCurrencyAmount").subtract(PaymentWorker.getPaymentApplied(payment)).setScale(DECIMALS,ROUNDING);
if (amountApplied.signum() == 0) {
amountAppliedMax = paymentApplyAvailable;
}
}
// check if the invoice already covered by payments
BigDecimal invoiceTotal = InvoiceWorker.getInvoiceTotal(invoice);
invoiceApplyAvailable = InvoiceWorker.getInvoiceNotApplied(invoice);
// adjust the amountAppliedMax value if required....
if (invoiceApplyAvailable.compareTo(amountAppliedMax) < 0) {
amountAppliedMax = invoiceApplyAvailable;
}
if (invoiceTotal.signum() == 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceTotalZero", UtilMisc.toMap("invoiceId", invoiceId), locale));
} else if (paymentApplicationId == null) {
// only check for new records here...updates are checked in the paymentApplication section
if (invoiceApplyAvailable.signum() == 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceCompletelyApplied", UtilMisc.toMap("invoiceId", invoiceId), locale));
}
// check here for too much application if a new record(s) are
// added (paymentApplicationId == null)
else if (amountApplied.compareTo(invoiceApplyAvailable) > 0) {
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingInvoiceLessRequested",
UtilMisc.<String, Object>toMap("invoiceId", invoiceId,
"invoiceApplyAvailable", invoiceApplyAvailable,
"amountApplied", amountApplied,
"isoCode", invoice.getString("currencyUomId")), locale));
}
}
// check if at least one sender is the same as one receiver on the invoice
if (!payment.getString("partyIdFrom").equals(invoice.getString("partyId")) &&
!payment.getString("partyIdTo").equals(invoice.getString("partyIdFrom"))) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingFromPartySameToParty", locale));
}
if (debug) Debug.logInfo("Invoice info retrieved and checked ...", module);
}
// if provided check the invoice item.
if (invoiceItemSeqId != null) {
// when itemSeqNr not provided delay checking on invoiceItemSeqId
try {
invoiceItem = delegator.findByPrimaryKey("InvoiceItem",
UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (invoiceItem == null) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceItemNotFound",
UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId), locale));
} else {
if (invoice.get("currencyUomId") != null && currencyUomId != null && !invoice.getString("currencyUomId").equals(currencyUomId)) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoicePaymentCurrencyProblem",
UtilMisc.toMap("paymentCurrencyId", currencyUomId,
"itemCurrency", invoice.getString("currencyUomId")), locale));
}
// get the invoice item applied value
BigDecimal quantity = null;
if (invoiceItem.get("quantity") == null) {
quantity = BigDecimal.ONE;
} else {
quantity = invoiceItem.getBigDecimal("quantity").setScale(DECIMALS,ROUNDING);
}
invoiceItemApplyAvailable = invoiceItem.getBigDecimal("amount").multiply(quantity).setScale(DECIMALS,ROUNDING).subtract(InvoiceWorker.getInvoiceItemApplied(invoiceItem));
// check here for too much application if a new record is added
// (paymentApplicationId == null)
if (paymentApplicationId == null && amountApplied.compareTo(invoiceItemApplyAvailable) > 0) {
// new record
errorMessageList.add("Invoice(" + invoiceId + ") item(" + invoiceItemSeqId + ") has " + invoiceItemApplyAvailable + " to apply but " + amountApplied + " is requested\n");
String uomId = invoice.getString("currencyUomId");
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingInvoiceItemLessRequested",
UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId,
"invoiceItemApplyAvailable", invoiceItemApplyAvailable,
"amountApplied", amountApplied, "isoCode", uomId), locale));
}
}
if (debug) Debug.logInfo("InvoiceItem info retrieved and checked against the Invoice (currency and amounts) ...", module);
}
}
// check this at the end because the invoice can change the currency.......
if (paymentApplicationId == null) {
// only check for new application records, update on existing records is checked in the paymentApplication section
if (paymentApplyAvailable.signum() == 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentAlreadyApplied", UtilMisc.toMap("paymentId", paymentId), locale));
} else {
// check here for too much application if a new record is
// added (paymentApplicationId == null)
if (amountApplied.compareTo(paymentApplyAvailable) > 0) {
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingPaymentLessRequested",
UtilMisc.<String, Object>toMap("paymentId", paymentId,
"paymentApplyAvailable", paymentApplyAvailable,
"amountApplied", amountApplied,"isoCode", currencyUomId), locale));
}
}
}
// get the application record if the applicationId is supplied if not
// create empty record.
BigDecimal newInvoiceApplyAvailable = invoiceApplyAvailable;
// amount available on the invoice taking into account if the invoiceItemnumber has changed
BigDecimal newInvoiceItemApplyAvailable = invoiceItemApplyAvailable;
// amount available on the invoiceItem taking into account if the itemnumber has changed
BigDecimal newToPaymentApplyAvailable = toPaymentApplyAvailable;
BigDecimal newPaymentApplyAvailable = paymentApplyAvailable;
GenericValue paymentApplication = null;
if (paymentApplicationId == null) {
paymentApplication = delegator.makeValue("PaymentApplication");
// prepare for creation
} else { // retrieve existing paymentApplication
try {
paymentApplication = delegator.findByPrimaryKey("PaymentApplication",
UtilMisc.toMap("paymentApplicationId", paymentApplicationId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (paymentApplication == null) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentApplicationNotFound",
UtilMisc.toMap("paymentApplicationId", paymentApplicationId), locale));
paymentApplicationId = null;
} else {
// if both invoiceId and BillingId is entered there was
// obviously a change
// only take the newly entered item, same for tax authority and toPayment
if (paymentApplication.get("invoiceId") == null && invoiceId != null) {
billingAccountId = null;
taxAuthGeoId = null;
toPaymentId = null;
} else if (paymentApplication.get("toPaymentId") == null && toPaymentId != null) {
invoiceId = null;
invoiceItemSeqId = null;
taxAuthGeoId = null;
billingAccountId = null;
} else if (paymentApplication.get("billingAccountId") == null && billingAccountId != null) {
invoiceId = null;
invoiceItemSeqId = null;
toPaymentId = null;
taxAuthGeoId = null;
} else if (paymentApplication.get("taxAuthGeoId") == null && taxAuthGeoId != null) {
invoiceId = null;
invoiceItemSeqId = null;
toPaymentId = null;
billingAccountId = null;
}
// check if the payment for too much application if an existing
// application record is changed
if (paymentApplyAvailable.compareTo(ZERO) == 0) {
newPaymentApplyAvailable = paymentApplyAvailable.add(paymentApplication.getBigDecimal("amountApplied")).subtract(amountApplied).setScale(DECIMALS, ROUNDING);
} else {
newPaymentApplyAvailable = paymentApplyAvailable.add(paymentApplyAvailable).subtract(amountApplied).setScale(DECIMALS, ROUNDING);
}
if (newPaymentApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentNotEnough",
UtilMisc.<String, Object>toMap("paymentId", paymentId,
"paymentApplyAvailable", paymentApplyAvailable.add(paymentApplication.getBigDecimal("amountApplied")),
"amountApplied", amountApplied), locale));
}
if (invoiceId != null) {
// only when we are processing an invoice on existing paymentApplication check invoice item for to much application if the invoice
// number did not change
if (invoiceId.equals(paymentApplication .getString("invoiceId"))) {
// check if both the itemNumbers are null then this is a
// record for the whole invoice
if (invoiceItemSeqId == null && paymentApplication.get("invoiceItemSeqId") == null) {
newInvoiceApplyAvailable = invoiceApplyAvailable.add(paymentApplication.getBigDecimal("amountApplied")).subtract(amountApplied).setScale(DECIMALS, ROUNDING);
if (invoiceApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceNotEnough",
UtilMisc.<String, Object>toMap("tooMuch", newInvoiceApplyAvailable.negate(),
"invoiceId", invoiceId), locale));
}
} else if (invoiceItemSeqId == null && paymentApplication.get("invoiceItemSeqId") != null) {
// check if the item number changed from a real Item number to a null value
newInvoiceApplyAvailable = invoiceApplyAvailable.add(paymentApplication.getBigDecimal("amountApplied")).subtract(amountApplied).setScale(DECIMALS, ROUNDING);
if (invoiceApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceNotEnough",
UtilMisc.<String, Object>toMap("tooMuch", newInvoiceApplyAvailable.negate(),
"invoiceId", invoiceId), locale));
}
} else if (invoiceItemSeqId != null && paymentApplication.get("invoiceItemSeqId") == null) {
// check if the item number changed from a null value to
// a real Item number
newInvoiceItemApplyAvailable = invoiceItemApplyAvailable.subtract(amountApplied).setScale(DECIMALS, ROUNDING);
if (newInvoiceItemApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingItemInvoiceNotEnough",
UtilMisc.<String, Object>toMap("tooMuch", newInvoiceItemApplyAvailable.negate(),
"invoiceId", invoiceId,
"invoiceItemSeqId", invoiceItemSeqId), locale));
}
} else if (invoiceItemSeqId.equals(paymentApplication.getString("invoiceItemSeqId"))) {
// check if the real item numbers the same
// item number the same numeric value
newInvoiceItemApplyAvailable = invoiceItemApplyAvailable.add(paymentApplication.getBigDecimal("amountApplied")).subtract(amountApplied).setScale(DECIMALS, ROUNDING);
if (newInvoiceItemApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingItemInvoiceNotEnough",
UtilMisc.<String, Object>toMap("tooMuch", newInvoiceItemApplyAvailable.negate(),
"invoiceId", invoiceId,
"invoiceItemSeqId", invoiceItemSeqId), locale));
}
} else {
// item number changed only check new item
newInvoiceItemApplyAvailable = invoiceItemApplyAvailable.add(amountApplied).setScale(DECIMALS, ROUNDING);
if (newInvoiceItemApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingItemInvoiceNotEnough",
UtilMisc.<String, Object>toMap("tooMuch", newInvoiceItemApplyAvailable.negate(),
"invoiceId", invoiceId,
"invoiceItemSeqId", invoiceItemSeqId), locale));
}
}
// if the amountApplied = 0 give it the higest possible
// value
if (amountApplied.signum() == 0) {
if (newInvoiceItemApplyAvailable.compareTo(newPaymentApplyAvailable) < 0) {
amountApplied = newInvoiceItemApplyAvailable;
// from the item number
} else {
amountApplied = newPaymentApplyAvailable;
// from the payment
}
}
// check the invoice
newInvoiceApplyAvailable = invoiceApplyAvailable.add(paymentApplication.getBigDecimal("amountApplied").subtract(amountApplied)).setScale(DECIMALS, ROUNDING);
if (newInvoiceApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingInvoiceNotEnough",
UtilMisc.<String, Object>toMap("tooMuch", invoiceApplyAvailable.add(paymentApplication.getBigDecimal("amountApplied")).subtract(amountApplied),
"invoiceId", invoiceId), locale));
}
}
}
// check the toPayment account when only the amountApplied has
// changed,
if (toPaymentId != null && toPaymentId.equals(paymentApplication.getString("toPaymentId"))) {
newToPaymentApplyAvailable = toPaymentApplyAvailable.subtract(paymentApplication.getBigDecimal("amountApplied")).add(amountApplied).setScale(DECIMALS, ROUNDING);
if (newToPaymentApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentNotEnough",
UtilMisc.<String, Object>toMap("paymentId", toPaymentId,
"paymentApplyAvailable", newToPaymentApplyAvailable,
"amountApplied", amountApplied), locale));
}
} else if (toPaymentId != null) {
// billing account entered number has changed so we have to
// check the new billing account number.
newToPaymentApplyAvailable = toPaymentApplyAvailable.add(amountApplied).setScale(DECIMALS, ROUNDING);
if (newToPaymentApplyAvailable.compareTo(ZERO) < 0) {
errorMessageList.add(UtilProperties.getMessage(resource,
"AccountingPaymentNotEnough",
UtilMisc.<String, Object>toMap("paymentId", toPaymentId,
"paymentApplyAvailable", newToPaymentApplyAvailable,
"amountApplied", amountApplied), locale));
}
}
}
if (debug) Debug.logInfo("paymentApplication record info retrieved and checked...", module);
}
// show the maximumus what can be added in the payment application file.
String toMessage = null; // prepare for success message
if (debug) {
String extra = "";
if (invoiceItemSeqId != null) {
extra = " Invoice item(" + invoiceItemSeqId + ") amount not yet applied: " + newInvoiceItemApplyAvailable;
}
Debug.logInfo("checking finished, start processing with the following data... ", module);
if (invoiceId != null) {
Debug.logInfo(" Invoice(" + invoiceId + ") amount not yet applied: " + newInvoiceApplyAvailable + extra + " Payment(" + paymentId + ") amount not yet applied: " + newPaymentApplyAvailable + " Requested amount to apply:" + amountApplied, module);
toMessage = UtilProperties.getMessage(resource,
"AccountingApplicationToInvoice",
UtilMisc.toMap("invoiceId", invoiceId), locale);
if (extra.length() > 0) toMessage = UtilProperties.getMessage(resource,
"AccountingApplicationToInvoiceItem",
UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId), locale);
}
if (toPaymentId != null) {
Debug.logInfo(" toPayment(" + toPaymentId + ") amount not yet applied: " + newToPaymentApplyAvailable + " Payment(" + paymentId + ") amount not yet applied: " + newPaymentApplyAvailable + " Requested amount to apply:" + amountApplied, module);
toMessage = UtilProperties.getMessage(resource,
"AccountingApplicationToPayment",
UtilMisc.toMap("paymentId", toPaymentId), locale);
}
if (taxAuthGeoId != null) {
Debug.logInfo(" taxAuthGeoId(" + taxAuthGeoId + ") Payment(" + paymentId + ") amount not yet applied: " + newPaymentApplyAvailable + " Requested amount to apply:" + amountApplied, module);
toMessage = UtilProperties.getMessage(resource,
"AccountingApplicationToTax",
UtilMisc.toMap("taxAuthGeoId", taxAuthGeoId), locale);
}
}
// if the amount to apply was not provided or was zero fill it with the maximum possible and provide information to the user
if (amountApplied.signum() == 0 && useHighestAmount.equals("Y")) {
amountApplied = newPaymentApplyAvailable;
if (invoiceId != null && newInvoiceApplyAvailable.compareTo(amountApplied) < 0) {
amountApplied = newInvoiceApplyAvailable;
toMessage = UtilProperties.getMessage(resource,
"AccountingApplicationToInvoice",
UtilMisc.toMap("invoiceId", invoiceId), locale);
}
if (toPaymentId != null && newToPaymentApplyAvailable.compareTo(amountApplied) < 0) {
amountApplied = newToPaymentApplyAvailable;
toMessage = UtilProperties.getMessage(resource,
"AccountingApplicationToPayment",
UtilMisc.toMap("paymentId", toPaymentId), locale);
}
}
String successMessage = null;
if (amountApplied.signum() == 0) {
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingNoAmount", locale));
} else {
successMessage = UtilProperties.getMessage(resource,
"AccountingApplicationSuccess",
UtilMisc.<String, Object>toMap("amountApplied", amountApplied,
"paymentId", paymentId,
"isoCode", currencyUomId,
"toMessage", toMessage), locale);
}
// report error messages if any
if (errorMessageList.size() > 0) {
return ServiceUtil.returnError(errorMessageList);
}
// ============ start processing ======================
// if the application is specified it is easy, update the existing record only
if (paymentApplicationId != null) {
// record is already retrieved previously
if (debug) Debug.logInfo("Process an existing paymentApplication record: " + paymentApplicationId, module);
// update the current record
paymentApplication.set("invoiceId", invoiceId);
paymentApplication.set("invoiceItemSeqId", invoiceItemSeqId);
paymentApplication.set("paymentId", paymentId);
paymentApplication.set("toPaymentId", toPaymentId);
paymentApplication.set("amountApplied", amountApplied);
paymentApplication.set("billingAccountId", billingAccountId);
paymentApplication.set("taxAuthGeoId", taxAuthGeoId);
return storePaymentApplication(delegator, paymentApplication,locale);
}
// if no invoice sequence number is provided it assumed the requested paymentAmount will be
// spread over the invoice starting with the lowest sequence number if
// itemprocessing is on otherwise create one record
if (invoiceId != null && paymentId != null && (invoiceItemSeqId == null)) {
if (invoiceProcessing) {
// create only a single record with a null seqId
if (debug) Debug.logInfo("Try to allocate the payment to the invoice as a whole", module);
paymentApplication.set("paymentId", paymentId);
paymentApplication.set("toPaymentId",null);
paymentApplication.set("invoiceId", invoiceId);
paymentApplication.set("invoiceItemSeqId", null);
paymentApplication.set("toPaymentId", null);
paymentApplication.set("amountApplied", amountApplied);
paymentApplication.set("billingAccountId", billingAccountId);
paymentApplication.set("taxAuthGeoId", null);
if (debug) Debug.logInfo("creating new paymentapplication", module);
return storePaymentApplication(delegator, paymentApplication,locale);
} else { // spread the amount over every single item number
if (debug) Debug.logInfo("Try to allocate the payment to the itemnumbers of the invoice", module);
// get the invoice items
List<GenericValue> invoiceItems = null;
try {
invoiceItems = delegator.findByAnd("InvoiceItem", UtilMisc.toMap("invoiceId", invoiceId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(e.getMessage());
}
if (invoiceItems.size() == 0) {
errorMessageList.add(UtilProperties.getMessage(resource, "AccountingNoInvoiceItemsFoundForInvoice", UtilMisc.toMap("invoiceId", invoiceId), locale));