details: https://code.openbravo.com/erp/devel/pi/rev/24d5b02440ca changeset: 27830:24d5b02440ca user: Atul Gaware <atul.gaware <at> openbravo.com> date: Thu Oct 29 14:26:35 2015 +0530 summary: Fixes Issue 0031193:Execute Pending Payments background process is taken into account payments that are not Awaiting Execution
- Remove lines from APRMPendingPaymentFromInvoice when payment does not have status as Awaiting Execution - While processing payment check whether records exists in APRMPendingPaymentsFromInvoice if no create them, if yes check whether they have proper execution process, if not set it. details: https://code.openbravo.com/erp/devel/pi/rev/07dbbd544216 changeset: 27831:07dbbd544216 user: Víctor Martínez Romanos <victor.martinez <at> openbravo.com> date: Wed Nov 04 18:55:33 2015 +0100 summary: Fixed bug 31193: code review improvements Changes in the solution: 1. When a payment in awaiting execution is reactivated or voided, we immediately delete the associated APRMPendingPaymentFromInvoice record. This is a way to ensure the same behavior as when creating the payment manually, where no APRMPendingPaymentFromInvoice record is created and the user must process manually the payment. 2. In case the payment is in awaiting execution, and there is any update, we update the APRMPendingPaymentFromInvoice record to point to the current Payment Process. This is a way to ensure the payment originally created by the system can be processed by the background process with the right payment process. 3. In case the payment is in awaiting execution, and the payment method is updated to any other without a payment process, then the APRMPendingPaymentFromInvoice record is deleted. This is done to ensure the payment is not processed by the background process with the Payment Process associated before. 4. The changes in the FIN_PaymentProcess have been reverted, because there is no need to create always a APRMPendingPaymentFromInvoice record before processing the payment 5. The ExecutePendingPayments class, which is the background process that processes the payments in the APRMPendingPaymentFromInvoice entity, will remove any APRMPendingPaymentFromInvoice record linked to a payment in Voided status, and it will execute only the payments in Awaiting Execution. 6. The code in the ExecutePendingPayments will probably require a deeper review to properly write it. diffstat: modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/event/FIN_PaymentEventListener.java | 114 +++++++++- modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/ExecutePendingPayments.java | 33 ++- 2 files changed, 141 insertions(+), 6 deletions(-) diffs (217 lines): diff -r cd794e1d482e -r 07dbbd544216 modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/event/FIN_PaymentEventListener.java --- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/event/FIN_PaymentEventListener.java Thu Nov 05 10:32:23 2015 +0100 +++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/event/FIN_PaymentEventListener.java Wed Nov 04 18:55:33 2015 +0100 @@ -11,7 +11,7 @@ * under the License. * The Original Code is Openbravo ERP. * The Initial Developer of the Original Code is Openbravo SLU - * All portions are Copyright (C) 2012 Openbravo SLU + * All portions are Copyright (C) 2012-2015 Openbravo SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************* @@ -22,17 +22,23 @@ import javax.enterprise.event.Observes; +import org.apache.commons.lang.StringUtils; +import org.hibernate.Query; +import org.openbravo.advpaymentmngt.dao.AdvPaymentMngtDao; import org.openbravo.base.exception.OBException; import org.openbravo.base.model.Entity; import org.openbravo.base.model.ModelProvider; +import org.openbravo.base.model.Property; import org.openbravo.client.kernel.event.EntityDeleteEvent; import org.openbravo.client.kernel.event.EntityPersistenceEventObserver; +import org.openbravo.client.kernel.event.EntityUpdateEvent; import org.openbravo.dal.core.OBContext; import org.openbravo.dal.service.OBDal; import org.openbravo.database.ConnectionProvider; import org.openbravo.erpCommon.utility.Utility; import org.openbravo.model.financialmgmt.payment.FIN_Payment; import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetail; +import org.openbravo.model.financialmgmt.payment.PaymentExecutionProcess; import org.openbravo.service.db.DalConnectionProvider; public class FIN_PaymentEventListener extends EntityPersistenceEventObserver { @@ -44,8 +50,15 @@ return entities; } - public void onDelete(@Observes - EntityDeleteEvent event) { + public void onUpdate(@Observes EntityUpdateEvent event) { + if (!isValidEvent(event)) { + return; + } + + manageAPRMPendingPaymentFromInvoiceRecord(event); + } + + public void onDelete(@Observes EntityDeleteEvent event) { if (!isValidEvent(event)) { return; } @@ -57,4 +70,99 @@ throw new OBException(Utility.messageBD(conn, "ForeignKeyViolation", language)); } } + + /** + * Manages the APRMPendingPaymentFromInvoice record linked to the payment: + * + * If the current payment status is Awaiting Execution, it updates the Payment Execution Process + * Id of the APRMPendingPaymentFromInvoice record to point to the current Payment Execution + * Process Id. If the current Payment Execution Process Id is null (because, for example, the + * payment is associated to another payment method without payment process), then we delete the + * APRMPendingPaymentFromInvoice record. + * + * The APRMPendingPaymentFromInvoice record is also deleted when the payment status has evolved + * from Awaiting Execution to Awaiting Payment or Voided (i.e. a reactivation has taken place). + * This way the behavior is exactly the same as when creating a manual payment in awaiting + * execution. + * + * Returns the number of records updated or deleted (0 or 1) + * + */ + private int manageAPRMPendingPaymentFromInvoiceRecord(final EntityUpdateEvent event) { + try { + OBContext.setAdminMode(true); + + int rowCount = 0; + + final FIN_Payment payment = (FIN_Payment) event.getTargetInstance(); + final Entity paymentEntity = ModelProvider.getInstance().getEntity(FIN_Payment.ENTITY_NAME); + final Property paymentStatusProperty = paymentEntity.getProperty(FIN_Payment.PROPERTY_STATUS); + final String currentPaymentStatus = (String) event.getCurrentState(paymentStatusProperty); + final String oldPaymentStatus = (String) event.getPreviousState(paymentStatusProperty); + + if (StringUtils.equals("RPAE", currentPaymentStatus)) { + final PaymentExecutionProcess executionProcess = new AdvPaymentMngtDao() + .getExecutionProcess(payment); + if (executionProcess == null) { + rowCount = deleteAPRMPendingPaymentFromInvoiceRecord(payment); + } else { + rowCount = updateAPRMPendingPaymentFromInvoiceRecord(payment, executionProcess); + } + } else if (StringUtils.equals("RPAE", oldPaymentStatus) + && (StringUtils.equals(currentPaymentStatus, "RPAP") || StringUtils.equals( + currentPaymentStatus, "RPVOID"))) { + rowCount = deleteAPRMPendingPaymentFromInvoiceRecord(payment); + } + + return rowCount; + } finally { + OBContext.restorePreviousMode(); + } + } + + /** + * Updates the APRMPendingPaymentFromInvoice record setting the given Payment Execution Process Id + * + * Returns the number of records updated (0 or 1) + */ + private int updateAPRMPendingPaymentFromInvoiceRecord(final FIN_Payment payment, + final PaymentExecutionProcess executionProcess) { + if (executionProcess == null || payment == null) { + return 0; + } + + int rowCount; + final StringBuffer hql = new StringBuffer(); + hql.append("update APRM_PendingPaymentInvoice "); + hql.append("set paymentExecutionProcess.id = :paymentExecutionProcessId "); + hql.append("where paymentExecutionProcess.id <> :paymentExecutionProcessId "); + hql.append("and payment.id = :paymentId "); + + Query updateQry = OBDal.getInstance().getSession().createQuery(hql.toString()); + updateQry.setString("paymentExecutionProcessId", executionProcess.getId()); + updateQry.setString("paymentId", payment.getId()); + rowCount = updateQry.executeUpdate(); + return rowCount; + } + + /** + * Updates the APRMPendingPaymentFromInvoice record linked to the given payment + * + * Returns the number of records deleted (0 or 1) + */ + private int deleteAPRMPendingPaymentFromInvoiceRecord(final FIN_Payment payment) { + if (payment == null) { + return 0; + } + + int rowCount; + final StringBuffer hql = new StringBuffer(); + hql.append("delete from APRM_PendingPaymentInvoice "); + hql.append("where payment.id = :paymentId "); + + Query updateQry = OBDal.getInstance().getSession().createQuery(hql.toString()); + updateQry.setString("paymentId", payment.getId()); + rowCount = updateQry.executeUpdate(); + return rowCount; + } } diff -r cd794e1d482e -r 07dbbd544216 modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/ExecutePendingPayments.java --- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/ExecutePendingPayments.java Thu Nov 05 10:32:23 2015 +0100 +++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/ExecutePendingPayments.java Wed Nov 04 18:55:33 2015 +0100 @@ -1,3 +1,21 @@ +/* + ************************************************************************* + * The contents of this file are subject to the Openbravo Public License + * Version 1.0 (the "License"), being the Mozilla Public License + * Version 1.1 with a permitted attribution clause; you may not use this + * file except in compliance with the License. You may obtain a copy of + * the License at http://www.openbravo.com/legal/license.html + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * The Original Code is Openbravo ERP. + * The Initial Developer of the Original Code is Openbravo SLU + * All portions are Copyright (C) 2010-2015 Openbravo SLU + * All Rights Reserved. + * Contributor(s): ______________________________________. + ************************************************************************* + */ package org.openbravo.advpaymentmngt.process; import java.util.ArrayList; @@ -7,6 +25,7 @@ import org.openbravo.advpaymentmngt.dao.AdvPaymentMngtDao; import org.openbravo.base.secureApp.VariablesSecureApp; import org.openbravo.dal.core.OBContext; +import org.openbravo.dal.service.OBDal; import org.openbravo.erpCommon.utility.OBError; import org.openbravo.erpCommon.utility.Utility; import org.openbravo.model.common.enterprise.Organization; @@ -36,9 +55,13 @@ List<APRMPendingPaymentFromInvoice> pendingPayments = dao.getPendingPayments(); List<FIN_Payment> payments = new ArrayList<FIN_Payment>(); // If there are no pending payments to process, return and skip this process. - if (pendingPayments.size() == 0) { + if (pendingPayments.isEmpty()) { return; } + // FIXME: this code is not properly written and it's impossible to understand. + // The comparations of objects are wrong (!=), probably they are always false in runtime. + // The first time we iterate the for, the executionProcess is null, so it won't enter the if. + // Is it right? try { for (APRMPendingPaymentFromInvoice pendingPayment : pendingPayments) { if (executionProcess != null @@ -58,8 +81,12 @@ } executionProcess = pendingPayment.getPaymentExecutionProcess(); organization = pendingPayment.getOrganization(); - payments.add(pendingPayment.getPayment()); - + FIN_Payment payment = pendingPayment.getPayment(); + if (payment.getStatus().equals("RPAE")) { + payments.add(pendingPayment.getPayment()); + } else { + OBDal.getInstance().remove(pendingPayment); + } } logger.logln(executionProcess.getIdentifier()); if (dao.isAutomaticExecutionProcess(executionProcess)) { ------------------------------------------------------------------------------ _______________________________________________ Openbravo-commits mailing list Openbravo-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openbravo-commits
