IDEMPIERE-2134 Issues found on Payment Selection process - implement trx management

* Payment Selection Manual:
** PaySelect.generatePaySelect: out of transaction, dangerous, if a line fails the header is still there
* Payment Print/Export
** PayPrint.cmd_export and cmd_print: both are creating and completing payments out of transaction, if something fails in the middle the process can leave partial things
This commit is contained in:
Carlos Ruiz 2014-08-12 09:51:20 +02:00
parent 5a4654e649
commit 062f2a8ca6
5 changed files with 237 additions and 142 deletions

View File

@ -0,0 +1,15 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Aug 12, 2014 9:41:46 AM CEST
-- IDEMPIERE-2134 Issues found on Payment Selection process
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,CreatedBy,UpdatedBy,Created,AD_Client_ID,AD_Org_ID,Updated) VALUES ('I','This process creates and complete payments automatically, do you want to print and at the same time create/complete payments?',200306,'D','e623e783-7b0d-4882-9ea6-0f04c30880ca','CreatePayments?','Y',100,100,TO_DATE('2014-08-12 09:41:45','YYYY-MM-DD HH24:MI:SS'),0,0,TO_DATE('2014-08-12 09:41:45','YYYY-MM-DD HH24:MI:SS'))
;
-- Aug 12, 2014 9:47:55 AM CEST
UPDATE AD_Message SET MsgText='Is the payment print correct ? If answered yes, then it will create and complete payments.',Updated=TO_DATE('2014-08-12 09:47:55','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=585
;
SELECT register_migration_script('201408120942_IDEMPIERE-2134.sql') FROM dual
;

View File

@ -0,0 +1,12 @@
-- Aug 12, 2014 9:41:46 AM CEST
-- IDEMPIERE-2134 Issues found on Payment Selection process
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,CreatedBy,UpdatedBy,Created,AD_Client_ID,AD_Org_ID,Updated) VALUES ('I','This process creates and complete payments automatically, do you want to print and at the same time create/complete payments?',200306,'D','e623e783-7b0d-4882-9ea6-0f04c30880ca','CreatePayments?','Y',100,100,TO_TIMESTAMP('2014-08-12 09:41:45','YYYY-MM-DD HH24:MI:SS'),0,0,TO_TIMESTAMP('2014-08-12 09:41:45','YYYY-MM-DD HH24:MI:SS'))
;
-- Aug 12, 2014 9:47:55 AM CEST
UPDATE AD_Message SET MsgText='Is the payment print correct ? If answered yes, then it will create and complete payments.',Updated=TO_TIMESTAMP('2014-08-12 09:47:55','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=585
;
SELECT register_migration_script('201408120942_IDEMPIERE-2134.sql') FROM dual
;

View File

@ -30,6 +30,7 @@ import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
/**
* Payment Print/Export model.
@ -42,7 +43,7 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
/**
*
*/
private static final long serialVersionUID = -5890511999934551763L;
private static final long serialVersionUID = -5752888482207479355L;
/**
* Get Check for Payment
@ -268,7 +269,17 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
*/
public static void confirmPrint (MPaySelectionCheck check, MPaymentBatch batch)
{
MPayment payment = new MPayment(check.getCtx(), check.getC_Payment_ID(), check.get_TrxName());
boolean localTrx = false;
String trxName = check.get_TrxName();
Trx trx = null;
if (trxName == null) {
localTrx = true;
trxName = Trx.createTrxName("ConfirmPrintSingle");
trx = Trx.get(trxName, true);
check.set_TrxName(trxName);
}
try {
MPayment payment = new MPayment(check.getCtx(), check.getC_Payment_ID(), trxName);
// Existing Payment
if (check.getC_Payment_ID() != 0)
{
@ -276,13 +287,12 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
if (check.getPaymentRule().equals(PAYMENTRULE_Check))
{
payment.setCheckNo(check.getDocumentNo());
if (!payment.save())
s_log.log(Level.SEVERE, "Payment not saved: " + payment);
payment.saveEx();
}
}
else // New Payment
{
payment = new MPayment(check.getCtx(), 0, check.get_TrxName());
payment = new MPayment(check.getCtx(), 0, trxName);
payment.setAD_Org_ID(check.getAD_Org_ID());
//
if (check.getPaymentRule().equals(PAYMENTRULE_Check))
@ -307,11 +317,11 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
if (batch != null)
{
if (batch.getC_PaymentBatch_ID() == 0)
batch.saveEx(); // new
batch.saveEx(trxName); // new
payment.setC_PaymentBatch_ID(batch.getC_PaymentBatch_ID());
}
// Link to Invoice
MPaySelectionLine[] psls = check.getPaySelectionLines(false);
MPaySelectionLine[] psls = check.getPaySelectionLines(true);
if (s_log.isLoggable(Level.FINE)) s_log.fine("confirmPrint - " + check + " (#SelectionLines=" + psls.length + ")");
if (check.getQty() == 1 && psls != null && psls.length == 1)
{
@ -328,8 +338,7 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
else
payment.setDiscountAmt(Env.ZERO);
payment.setWriteOffAmt(Env.ZERO);
if (!payment.save())
s_log.log(Level.SEVERE, "Payment not saved: " + payment);
payment.saveEx();
//
int C_Payment_ID = payment.get_ID();
if (C_Payment_ID < 1)
@ -342,15 +351,26 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
if (!payment.processIt(DocAction.ACTION_Complete))
throw new AdempiereException("Failed when processing document - " + payment.getProcessMsg());
// end added
if (!payment.save())
s_log.log(Level.SEVERE, "Payment not saved: " + payment);
payment.saveEx();
}
} // new Payment
check.setIsPrinted(true);
check.setProcessed(true);
if (!check.save ())
s_log.log(Level.SEVERE, "Check not saved: " + check);
check.saveEx();
} catch (Exception e) {
if (localTrx && trx != null) {
trx.rollback();
trx.close();
trx = null;
}
throw new AdempiereException(e);
} finally {
if (localTrx && trx != null) {
trx.commit();
trx.close();
}
}
} // confirmPrint
/**************************************************************************
@ -362,10 +382,23 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
*/
public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch)
{
boolean localTrx = false;
String trxName = null;
if (checks.length > 0)
trxName = checks[0].get_TrxName();
Trx trx = null;
if (trxName == null) {
localTrx = true;
trxName = Trx.createTrxName("ConfirmPrintMulti");
trx = Trx.get(trxName, true);
}
int lastDocumentNo = 0;
try {
for (int i = 0; i < checks.length; i++)
{
MPaySelectionCheck check = checks[i];
if (localTrx)
check.set_TrxName(trxName);
confirmPrint(check, batch);
// Get Check Document No
@ -380,6 +413,19 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
s_log.log(Level.SEVERE, "DocumentNo=" + check.getDocumentNo(), ex);
}
} // all checks
} catch (Exception e) {
if (localTrx && trx != null) {
trx.rollback();
trx.close();
trx = null;
}
throw new AdempiereException(e);
} finally {
if (localTrx && trx != null) {
trx.commit();
trx.close();
}
}
if (s_log.isLoggable(Level.FINE)) s_log.fine("Last Document No = " + lastDocumentNo);
return lastDocumentNo;
@ -560,7 +606,7 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck
/**
* Get Payment Selection Lines of this check
* @param requery requery
* @return array of peyment selection lines
* @return array of payment selection lines
*/
public MPaySelectionLine[] getPaySelectionLines (boolean requery)
{

View File

@ -253,7 +253,7 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene
else if (e.getTarget() == bProcess)
cmd_EFT();
else if (e.getTarget() == bPrint)
cmd_print();
confirm_cmd_print();
} // actionPerformed
/**
@ -410,6 +410,25 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene
dispose();
} // cmd_EFT
/**
* Confirm before printing
*/
protected void confirm_cmd_print()
{
FDialog.ask(m_WindowNo, form, "CreatePayments?", new Callback<Boolean>() {
@Override
public void onCallback(Boolean result)
{
if (result)
{
cmd_print();
}
}
});
}
/**
* Print Checks and/or Remittance
*/

View File

@ -51,12 +51,6 @@ public class PaySelect
{
/** @todo withholding */
/**
*
*/
@SuppressWarnings("unused")
private static final long serialVersionUID = 2872767371244295934L;
/** Window No */
public int m_WindowNo = 0;
@ -417,10 +411,12 @@ public class PaySelect
public String generatePaySelect(IMiniTable miniTable, ValueNamePair paymentRule, Timestamp payDate, BankInfo bi)
{
log.info("");
// String trxName Trx.createTrxName("PaySelect");
// Trx trx = Trx.get(trxName, true); trx needs to be committed too
String trxName = null;
trx = null;
Trx trx = null;
try {
trxName = Trx.createTrxName("PaySelect");
trx = Trx.get(trxName, true);
String PaymentRule = paymentRule.getValue();
@ -432,11 +428,7 @@ public class PaySelect
m_ps.setPayDate (payDate);
m_ps.setC_BankAccount_ID(bi.C_BankAccount_ID);
m_ps.setIsApproved(true);
if (!m_ps.save())
{
m_ps = null;
return Msg.translate(Env.getCtx(), "C_PaySelection_ID");
}
m_ps.saveEx();
if (log.isLoggable(Level.CONFIG)) log.config(m_ps.toString());
// Create Lines
@ -456,13 +448,24 @@ public class PaySelect
//
psl.setInvoice(C_Invoice_ID, isSOTrx,
OpenAmt, PayAmt, OpenAmt.subtract(PayAmt));
if (!psl.save(trxName))
{
return Msg.translate(Env.getCtx(), "C_PaySelectionLine_ID");
}
psl.saveEx(trxName);
if (log.isLoggable(Level.FINE)) log.fine("C_Invoice_ID=" + C_Invoice_ID + ", PayAmt=" + PayAmt);
}
} // for all rows in table
} catch (Exception e) {
if (trx != null) {
trx.rollback();
trx.close();
trx = null;
}
m_ps = null;
throw new AdempiereException(e);
} finally {
if (trx != null) {
trx.commit();
trx.close();
}
}
return null;
} // generatePaySelect
@ -507,4 +510,4 @@ public class PaySelect
}
} // BankInfo
} // VPaySelect
} // PaySelect