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

Reply via email to