details: https://code.openbravo.com/erp/devel/pi/rev/336cbe497bec changeset: 27917:336cbe497bec user: Alvaro Ferraz <alvaro.ferraz <at> openbravo.com> date: Mon Nov 16 13:39:15 2015 +0100 summary: Fixes issue 30971: Cancel PaymentScheduleDetails when voiding an unpaid invoice
When voiding an unpaid invoice, a dummy payment will be created related with both the actual invoice and the voided invoice. In case there is no financial account available for invoice payment method, an error will be shown. getFinancialAccountPaymentMethod method has been moved from AddPaymentDefaultValuesHandler to FIN_Utility, in order to use it in ProcessInvoice class. diffstat: modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_MESSAGE.xml | 12 + modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/ad_actionbutton/ProcessInvoice.java | 160 +++++++++- modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddPaymentDefaultValuesHandler.java | 68 +--- modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java | 56 +++ 4 files changed, 237 insertions(+), 59 deletions(-) diffs (truncated from 419 to 300 lines): diff -r aaf78ab227d5 -r 336cbe497bec modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_MESSAGE.xml --- a/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_MESSAGE.xml Tue Nov 17 18:03:25 2015 +0100 +++ b/modules/org.openbravo.advpaymentmngt/src-db/database/sourcedata/AD_MESSAGE.xml Mon Nov 16 13:39:15 2015 +0100 @@ -1405,6 +1405,18 @@ <!--E92C3899BD924A5C991A39B2CDA74D29--> <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N> <!--E92C3899BD924A5C991A39B2CDA74D29--></AD_MESSAGE> +<!--EAA6B599637E4A909131395D843C3C61--><AD_MESSAGE> +<!--EAA6B599637E4A909131395D843C3C61--> <AD_MESSAGE_ID><![CDATA[EAA6B599637E4A909131395D843C3C61]]></AD_MESSAGE_ID> +<!--EAA6B599637E4A909131395D843C3C61--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID> +<!--EAA6B599637E4A909131395D843C3C61--> <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID> +<!--EAA6B599637E4A909131395D843C3C61--> <ISACTIVE><![CDATA[Y]]></ISACTIVE> +<!--EAA6B599637E4A909131395D843C3C61--> <VALUE><![CDATA[APRM_NoFinancialAccountAvailable]]></VALUE> +<!--EAA6B599637E4A909131395D843C3C61--> <MSGTEXT><![CDATA[It does not exist any Financial Account available for this Payment Method]]></MSGTEXT> +<!--EAA6B599637E4A909131395D843C3C61--> <MSGTYPE><![CDATA[E]]></MSGTYPE> +<!--EAA6B599637E4A909131395D843C3C61--> <AD_MODULE_ID><![CDATA[A918E3331C404B889D69AA9BFAFB23AC]]></AD_MODULE_ID> +<!--EAA6B599637E4A909131395D843C3C61--> <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N> +<!--EAA6B599637E4A909131395D843C3C61--></AD_MESSAGE> + <!--EDEA16A966B94F63A7C1E339FC095B08--><AD_MESSAGE> <!--EDEA16A966B94F63A7C1E339FC095B08--> <AD_MESSAGE_ID><![CDATA[EDEA16A966B94F63A7C1E339FC095B08]]></AD_MESSAGE_ID> <!--EDEA16A966B94F63A7C1E339FC095B08--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID> diff -r aaf78ab227d5 -r 336cbe497bec modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/ad_actionbutton/ProcessInvoice.java --- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/ad_actionbutton/ProcessInvoice.java Tue Nov 17 18:03:25 2015 +0100 +++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/ad_actionbutton/ProcessInvoice.java Mon Nov 16 13:39:15 2015 +0100 @@ -44,10 +44,13 @@ import org.openbravo.advpaymentmngt.process.FIN_PaymentProcess; import org.openbravo.advpaymentmngt.utility.FIN_Utility; import org.openbravo.base.filter.IsIDFilter; +import org.openbravo.base.provider.OBProvider; import org.openbravo.base.secureApp.HttpSecureAppServlet; import org.openbravo.base.secureApp.VariablesSecureApp; import org.openbravo.base.session.OBPropertiesProvider; import org.openbravo.dal.core.OBContext; +import org.openbravo.dal.security.OrganizationStructureProvider; +import org.openbravo.dal.service.OBCriteria; import org.openbravo.dal.service.OBDal; import org.openbravo.dal.service.OBDao; import org.openbravo.data.FieldProvider; @@ -66,8 +69,10 @@ import org.openbravo.model.common.currency.ConversionRate; import org.openbravo.model.common.enterprise.DocumentType; import org.openbravo.model.common.invoice.Invoice; +import org.openbravo.model.common.invoice.ReversedInvoice; import org.openbravo.model.financialmgmt.payment.FIN_FinancialAccount; import org.openbravo.model.financialmgmt.payment.FIN_Payment; +import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetail; import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetailV; import org.openbravo.model.financialmgmt.payment.FIN_PaymentSchedule; import org.openbravo.model.financialmgmt.payment.FIN_PaymentScheduleDetail; @@ -182,10 +187,10 @@ OBContext.restorePreviousMode(); } + Date voidDate = null; + Date voidAcctDate = null; Map<String, String> parameters = null; if (!strVoidInvoiceDate.isEmpty() && !strVoidInvoiceAcctDate.isEmpty()) { - Date voidDate = null; - Date voidAcctDate = null; try { voidDate = OBDateUtils.getDate(strVoidInvoiceDate); voidAcctDate = OBDateUtils.getDate(strVoidInvoiceAcctDate); @@ -199,6 +204,107 @@ parameters.put("voidedDocumentDate", OBDateUtils.formatDate(voidDate, "yyyy-MM-dd")); parameters.put("voidedDocumentAcctDate", OBDateUtils.formatDate(voidAcctDate, "yyyy-MM-dd")); + + } + + // In case of void a non paid invoice, create a dummy payment related to it with zero amount + FIN_Payment dummyPayment = null; + if ("RC".equals(strdocaction) && !invoice.isPaymentComplete() + && invoice.getTotalPaid().compareTo(BigDecimal.ZERO) == 0) { + try { + OBContext.setAdminMode(true); + final boolean isSOTrx = invoice.isSalesTransaction(); + final DocumentType docType = FIN_Utility.getDocumentType(invoice.getOrganization(), + isSOTrx ? AcctServer.DOCTYPE_ARReceipt : AcctServer.DOCTYPE_APPayment); + final String strPaymentDocumentNo = FIN_Utility.getDocumentNo(docType, + docType.getTable() != null ? docType.getTable().getDBTableName() : ""); + final OrganizationStructureProvider osp = OBContext.getOBContext() + .getOrganizationStructureProvider(invoice.getClient().getId()); + + // Get default Financial Account as it is done in Add Payment + FIN_FinancialAccount bpFinAccount = null; + if (isSOTrx + && invoice.getBusinessPartner().getAccount() != null + && FIN_Utility.getFinancialAccountPaymentMethod(invoice.getPaymentMethod().getId(), + invoice.getBusinessPartner().getAccount().getId(), isSOTrx, invoice + .getCurrency().getId()) != null + && osp.isInNaturalTree(invoice.getBusinessPartner().getAccount().getOrganization(), + invoice.getOrganization())) { + bpFinAccount = invoice.getBusinessPartner().getAccount(); + } else if (!isSOTrx + && invoice.getBusinessPartner().getPOFinancialAccount() != null + && FIN_Utility.getFinancialAccountPaymentMethod(invoice.getPaymentMethod().getId(), + invoice.getBusinessPartner().getPOFinancialAccount().getId(), isSOTrx, invoice + .getCurrency().getId()) != null + && osp.isInNaturalTree(invoice.getBusinessPartner().getPOFinancialAccount() + .getOrganization(), invoice.getOrganization())) { + bpFinAccount = invoice.getBusinessPartner().getPOFinancialAccount(); + } else { + FinAccPaymentMethod fpm = FIN_Utility.getFinancialAccountPaymentMethod(invoice + .getPaymentMethod().getId(), null, isSOTrx, invoice.getCurrency().getId()); + if (fpm != null + && osp.isInNaturalTree(fpm.getAccount().getOrganization(), + invoice.getOrganization())) { + bpFinAccount = fpm.getAccount(); + } + } + + // If no Financial Account exists, show an Error + if (bpFinAccount == null) { + msg = new OBError(); + msg.setType("Error"); + msg.setTitle(Utility.messageBD(this, "Error", vars.getLanguage())); + msg.setMessage(OBMessageUtils.messageBD("APRM_NoFinancialAccountAvailable")); + vars.setMessage(strTabId, msg); + printPageClosePopUp(response, vars, Utility.getTabURL(strTabId, "R", true)); + return; + } + + // Calculate Conversion Rate + Date date = voidDate != null ? voidDate : invoice.getInvoiceDate(); + BigDecimal rate = null; + if (!StringUtils.equals(invoice.getCurrency().getId(), bpFinAccount.getCurrency() + .getId())) { + final ConversionRate conversionRate = FinancialUtils.getConversionRate(date, + invoice.getCurrency(), bpFinAccount.getCurrency(), invoice.getOrganization(), + invoice.getClient()); + if (conversionRate != null) { + rate = conversionRate.getMultipleRateBy(); + } + } + + // Create dummy payment + dummyPayment = dao + .getNewPayment(isSOTrx, invoice.getOrganization(), docType, strPaymentDocumentNo, + invoice.getBusinessPartner(), invoice.getPaymentMethod(), bpFinAccount, "0", + date, invoice.getDocumentNo(), invoice.getCurrency(), rate, null); + OBDal.getInstance().save(dummyPayment); + + List<FIN_PaymentDetail> paymentDetails = new ArrayList<FIN_PaymentDetail>(); + List<FIN_PaymentScheduleDetail> paymentScheduleDetails = dao + .getInvoicePendingScheduledPaymentDetails(invoice); + for (FIN_PaymentScheduleDetail psd : paymentScheduleDetails) { + FIN_PaymentDetail pd = OBProvider.getInstance().get(FIN_PaymentDetail.class); + pd.setFinPayment(dummyPayment); + pd.setAmount(psd.getAmount()); + pd.setRefund(false); + OBDal.getInstance().save(pd); + + paymentDetails.add(pd); + psd.setPaymentDetails(pd); + pd.getFINPaymentScheduleDetailList().add(psd); + OBDal.getInstance().save(psd); + } + dummyPayment.setFINPaymentDetailList(paymentDetails); + OBDal.getInstance().save(dummyPayment); + + } catch (final Exception e) { + log4j.error("Exception while creating dummy payment for the invoice: " + + strC_Invoice_ID); + e.printStackTrace(); + } finally { + OBContext.restorePreviousMode(); + } } final ProcessInstance pinstance = CallProcess.getInstance().call(process, strC_Invoice_ID, @@ -206,6 +312,56 @@ OBDal.getInstance().getSession().refresh(invoice); invoice.setAPRMProcessinvoice(invoice.getDocumentAction()); + + if ("RC".equals(strdocaction) && pinstance.getResult() != 0L) { + try { + OBContext.setAdminMode(true); + + // Get reversed payment + OBCriteria<ReversedInvoice> revInvoiceCriteria = OBDal.getInstance().createCriteria( + ReversedInvoice.class); + revInvoiceCriteria.add(Restrictions.eq(ReversedInvoice.PROPERTY_REVERSEDINVOICE, + invoice)); + revInvoiceCriteria.setMaxResults(1); + ReversedInvoice revInvoice = (ReversedInvoice) revInvoiceCriteria.uniqueResult(); + + if (revInvoice != null && dummyPayment != null) { + + List<FIN_PaymentDetail> paymentDetails = new ArrayList<FIN_PaymentDetail>(); + List<FIN_PaymentScheduleDetail> paymentScheduleDetails = dao + .getInvoicePendingScheduledPaymentDetails(revInvoice.getInvoice()); + for (FIN_PaymentScheduleDetail psd : paymentScheduleDetails) { + FIN_PaymentDetail pd = OBProvider.getInstance().get(FIN_PaymentDetail.class); + pd.setFinPayment(dummyPayment); + pd.setAmount(psd.getAmount()); + pd.setRefund(false); + OBDal.getInstance().save(pd); + + paymentDetails.add(pd); + psd.setPaymentDetails(pd); + pd.getFINPaymentScheduleDetailList().add(psd); + OBDal.getInstance().save(psd); + } + dummyPayment.getFINPaymentDetailList().addAll(paymentDetails); + OBDal.getInstance().save(dummyPayment); + + // Process dummy payment related with both actual invoice and reversed invoice + OBError message = FIN_AddPayment.processPayment(vars, this, "P", dummyPayment); + if ("Error".equals(message.getType())) { + message.setMessage(OBMessageUtils.messageBD("PaymentError") + " " + + message.getMessage()); + vars.setMessage(strTabId, message); + } + } + } catch (final Exception e) { + log4j.error("Exception while creating dummy payment for the invoice: " + + strC_Invoice_ID); + e.printStackTrace(); + } finally { + OBContext.restorePreviousMode(); + } + } + // Remove invoice's used credit description if ("RE".equals(strdocaction) && pinstance.getResult() != 0L) { final String invDesc = invoice.getDescription(); diff -r aaf78ab227d5 -r 336cbe497bec modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddPaymentDefaultValuesHandler.java --- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddPaymentDefaultValuesHandler.java Tue Nov 17 18:03:25 2015 +0100 +++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddPaymentDefaultValuesHandler.java Mon Nov 16 13:39:15 2015 +0100 @@ -32,13 +32,10 @@ import org.openbravo.dal.core.OBContext; import org.openbravo.dal.security.OrganizationStructureProvider; import org.openbravo.dal.service.OBDal; -import org.openbravo.dal.service.OBQuery; import org.openbravo.model.common.businesspartner.BusinessPartner; -import org.openbravo.model.common.currency.Currency; import org.openbravo.model.common.enterprise.Organization; import org.openbravo.model.financialmgmt.payment.FIN_FinancialAccount; import org.openbravo.model.financialmgmt.payment.FIN_Payment; -import org.openbravo.model.financialmgmt.payment.FIN_PaymentMethod; import org.openbravo.model.financialmgmt.payment.FIN_PaymentSchedule; import org.openbravo.model.financialmgmt.payment.FIN_PaymentScheduleDetail; import org.openbravo.model.financialmgmt.payment.FinAccPaymentMethod; @@ -303,14 +300,14 @@ strBPartnerId); if (isSOTrx && businessPartner.getAccount() != null - && getFinancialAccountPaymentMethod(paymentMethodId, businessPartner.getAccount() - .getId(), isSOTrx, currencyId) != null + && FIN_Utility.getFinancialAccountPaymentMethod(paymentMethodId, businessPartner + .getAccount().getId(), isSOTrx, currencyId) != null && osp.isInNaturalTree(businessPartner.getAccount().getOrganization(), OBDal .getInstance().get(Organization.class, context.getString("inpadOrgId")))) { return businessPartner.getAccount().getId(); } else if (!isSOTrx && businessPartner.getPOFinancialAccount() != null - && getFinancialAccountPaymentMethod(paymentMethodId, businessPartner + && FIN_Utility.getFinancialAccountPaymentMethod(paymentMethodId, businessPartner .getPOFinancialAccount().getId(), isSOTrx, currencyId) != null && osp.isInNaturalTree(businessPartner.getPOFinancialAccount().getOrganization(), OBDal .getInstance().get(Organization.class, context.getString("inpadOrgId")))) { @@ -318,8 +315,8 @@ } } - FinAccPaymentMethod fpm = getFinancialAccountPaymentMethod(paymentMethodId, null, isSOTrx, - currencyId); + FinAccPaymentMethod fpm = FIN_Utility.getFinancialAccountPaymentMethod(paymentMethodId, null, + isSOTrx, currencyId); if (fpm != null && osp.isInNaturalTree(fpm.getAccount().getOrganization(), OBDal.getInstance().get(Organization.class, context.getString("inpadOrgId")))) { @@ -371,8 +368,8 @@ boolean isSOTrx = "Y".equals(getDefaultIsSOTrx(requestMap)); strFinancialAccountId = getContextFinancialAccount(requestMap); if (strFinPaymentMethodId != null - && getFinancialAccountPaymentMethod(strFinPaymentMethodId, strFinancialAccountId, isSOTrx, - null) != null) { + && FIN_Utility.getFinancialAccountPaymentMethod(strFinPaymentMethodId, + strFinancialAccountId, isSOTrx, null) != null) { return strFinPaymentMethodId; } @@ -387,8 +384,8 @@ if (isSOTrx && businessPartner.getPaymentMethod() != null - && getFinancialAccountPaymentMethod(businessPartner.getPaymentMethod().getId(), - strFinancialAccountId, isSOTrx, null) != null + && FIN_Utility.getFinancialAccountPaymentMethod(businessPartner.getPaymentMethod() + .getId(), strFinancialAccountId, isSOTrx, null) != null && osp.isInNaturalTree(businessPartner.getPaymentMethod().getOrganization(), OBDal .getInstance().get(Organization.class, context.getString("inpadOrgId")))) { return businessPartner.getPaymentMethod().getId(); @@ -396,8 +393,8 @@ else if (!isSOTrx && businessPartner.getPOPaymentMethod() != null ------------------------------------------------------------------------------ _______________________________________________ Openbravo-commits mailing list Openbravo-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openbravo-commits