public void execute(ProcessBundle bundle) throws Exception {
    dao = new AdvPaymentMngtDao();
    OBError msg = new OBError();
    msg.setType("Success");
    msg.setTitle(
        Utility.messageBD(bundle.getConnection(), "Success", bundle.getContext().getLanguage()));

    try {
      // retrieve custom params
      final String strAction = (String) bundle.getParams().get("action");

      // retrieve standard params
      final String recordID = (String) bundle.getParams().get("Fin_FinAcc_Transaction_ID");
      final FIN_FinaccTransaction transaction =
          dao.getObject(FIN_FinaccTransaction.class, recordID);
      final VariablesSecureApp vars = bundle.getContext().toVars();
      final ConnectionProvider conProvider = bundle.getConnection();
      final String language = bundle.getContext().getLanguage();

      OBContext.setAdminMode();
      try {
        if (strAction.equals("P")) {
          // ***********************
          // Process Transaction
          // ***********************
          boolean orgLegalWithAccounting =
              FIN_Utility.periodControlOpened(
                  transaction.TABLE_NAME,
                  transaction.getId(),
                  transaction.TABLE_NAME + "_ID",
                  "LE");
          boolean documentEnabled = getDocumentConfirmation(conProvider, transaction.getId());
          if (documentEnabled
              && !FIN_Utility.isPeriodOpen(
                  transaction.getClient().getId(),
                  AcctServer.DOCTYPE_FinAccTransaction,
                  transaction.getOrganization().getId(),
                  OBDateUtils.formatDate(transaction.getDateAcct()))
              && orgLegalWithAccounting) {
            msg.setType("Error");
            msg.setTitle(Utility.messageBD(conProvider, "Error", language));
            msg.setMessage(
                Utility.parseTranslation(conProvider, vars, language, "@PeriodNotAvailable@"));
            bundle.setResult(msg);
            OBDal.getInstance().rollbackAndClose();
            return;
          }
          final FIN_FinancialAccount financialAccount = transaction.getAccount();
          financialAccount.setCurrentBalance(
              financialAccount
                  .getCurrentBalance()
                  .add(transaction.getDepositAmount().subtract(transaction.getPaymentAmount())));
          transaction.setProcessed(true);
          FIN_Payment payment = transaction.getFinPayment();
          if (payment != null) {
            if (transaction.getBusinessPartner() == null) {
              transaction.setBusinessPartner(payment.getBusinessPartner());
            }
            payment.setStatus(payment.isReceipt() ? "RDNC" : "PWNC");
            transaction.setStatus(payment.isReceipt() ? "RDNC" : "PWNC");
            OBDal.getInstance().save(payment);
            if (transaction.getDescription() == null || "".equals(transaction.getDescription())) {
              transaction.setDescription(payment.getDescription());
            }
            Boolean invoicePaidold = false;
            for (FIN_PaymentDetail pd : payment.getFINPaymentDetailList()) {
              for (FIN_PaymentScheduleDetail psd : pd.getFINPaymentScheduleDetailList()) {
                invoicePaidold = psd.isInvoicePaid();
                if (!invoicePaidold) {
                  if ((FIN_Utility.invoicePaymentStatus(payment).equals(payment.getStatus()))) {
                    psd.setInvoicePaid(true);
                  }
                  if (psd.isInvoicePaid()) {
                    FIN_Utility.updatePaymentAmounts(psd);
                    FIN_Utility.updateBusinessPartnerCredit(payment);
                  }
                  OBDal.getInstance().save(psd);
                }
              }
            }

          } else {
            transaction.setStatus(
                transaction.getDepositAmount().compareTo(transaction.getPaymentAmount()) > 0
                    ? "RDNC"
                    : "PWNC");
          }
          if (transaction.getForeignCurrency() != null
              && !transaction.getCurrency().equals(transaction.getForeignCurrency())
              && getConversionRateDocument(transaction).size() == 0) {
            insertConversionRateDocument(transaction);
          }
          OBDal.getInstance().save(financialAccount);
          OBDal.getInstance().save(transaction);
          OBDal.getInstance().flush();
          bundle.setResult(msg);

        } else if (strAction.equals("R")) {
          // ***********************
          // Reactivate Transaction
          // ***********************
          // Already Posted Document
          if ("Y".equals(transaction.getPosted())) {
            msg.setType("Error");
            msg.setTitle(Utility.messageBD(conProvider, "Error", language));
            msg.setMessage(
                Utility.parseTranslation(
                    conProvider,
                    vars,
                    language,
                    "@PostedDocument@" + ": " + transaction.getIdentifier()));
            bundle.setResult(msg);
            return;
          }
          // Already Reconciled
          if (transaction.getReconciliation() != null || "RPPC".equals(transaction.getStatus())) {
            msg.setType("Error");
            msg.setTitle(Utility.messageBD(conProvider, "Error", language));
            msg.setMessage(
                Utility.parseTranslation(
                    conProvider,
                    vars,
                    language,
                    "@APRM_ReconciledDocument@" + ": " + transaction.getIdentifier()));
            bundle.setResult(msg);
            return;
          }
          // Remove conversion rate at document level for the given transaction
          OBContext.setAdminMode();
          try {
            OBCriteria<ConversionRateDoc> obc =
                OBDal.getInstance().createCriteria(ConversionRateDoc.class);
            obc.add(
                Restrictions.eq(
                    ConversionRateDoc.PROPERTY_FINANCIALACCOUNTTRANSACTION, transaction));
            for (ConversionRateDoc conversionRateDoc : obc.list()) {
              OBDal.getInstance().remove(conversionRateDoc);
            }
            OBDal.getInstance().flush();
          } finally {
            OBContext.restorePreviousMode();
          }
          transaction.setProcessed(false);
          final FIN_FinancialAccount financialAccount = transaction.getAccount();
          financialAccount.setCurrentBalance(
              financialAccount
                  .getCurrentBalance()
                  .subtract(transaction.getDepositAmount())
                  .add(transaction.getPaymentAmount()));
          OBDal.getInstance().save(financialAccount);
          OBDal.getInstance().save(transaction);
          OBDal.getInstance().flush();
          FIN_Payment payment = transaction.getFinPayment();
          if (payment != null) {
            Boolean invoicePaidold = false;
            for (FIN_PaymentDetail pd : payment.getFINPaymentDetailList()) {
              for (FIN_PaymentScheduleDetail psd : pd.getFINPaymentScheduleDetailList()) {
                invoicePaidold = psd.isInvoicePaid();
                if (invoicePaidold) {
                  boolean restore =
                      (FIN_Utility.seqnumberpaymentstatus(payment.getStatus()))
                          == (FIN_Utility.seqnumberpaymentstatus(
                              FIN_Utility.invoicePaymentStatus(payment)));
                  if (restore) {
                    FIN_Utility.restorePaidAmounts(psd);
                  }
                }
              }
            }
            payment.setStatus(payment.isReceipt() ? "RPR" : "PPM");
            transaction.setStatus(payment.isReceipt() ? "RPR" : "PPM");
            OBDal.getInstance().save(payment);
          } else {
            transaction.setStatus(
                transaction.getDepositAmount().compareTo(transaction.getPaymentAmount()) > 0
                    ? "RPR"
                    : "PPM");
          }
          OBDal.getInstance().save(transaction);
          OBDal.getInstance().flush();
          bundle.setResult(msg);
        }
        bundle.setResult(msg);
      } finally {
        OBContext.restorePreviousMode();
      }
    } catch (final Exception e) {
      OBDal.getInstance().rollbackAndClose();
      e.printStackTrace(System.err);
      msg.setType("Error");
      msg.setTitle(
          Utility.messageBD(bundle.getConnection(), "Error", bundle.getContext().getLanguage()));
      msg.setMessage(FIN_Utility.getExceptionMessage(e));
      bundle.setResult(msg);
    }
  }