From 42b7a6438baaeb13caa2c9df5916d09891b6d21f Mon Sep 17 00:00:00 2001 From: armenrz Date: Wed, 9 May 2007 09:13:29 +0000 Subject: [PATCH] Bug Fix #1694472 --- base/src/org/compiere/model/MPayment.java | 4416 ++++++++++----------- 1 file changed, 2208 insertions(+), 2208 deletions(-) diff --git a/base/src/org/compiere/model/MPayment.java b/base/src/org/compiere/model/MPayment.java index 9d26e29dfa..08aa0dd568 100644 --- a/base/src/org/compiere/model/MPayment.java +++ b/base/src/org/compiere/model/MPayment.java @@ -3,258 +3,258 @@ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ -package org.compiere.model; - -import java.io.*; -import java.math.*; -import java.rmi.*; -import java.sql.*; -import java.util.*; -import java.util.logging.*; - -import org.compiere.db.*; -import org.compiere.interfaces.*; -import org.compiere.process.*; -import org.compiere.util.*; - -/** - * Payment Model. - * - retrieve and create payments for invoice - *
- *  Event chain
- *  - Payment inserted
- *      C_Payment_Trg fires
- *          update DocumentNo with payment summary
- *  - Payment posted (C_Payment_Post)
- *      create allocation line
- *          C_Allocation_Trg fires
- *              Update C_BPartner Open Item Amount
- *      update invoice (IsPaid)
- *      link invoice-payment if batch
- *
- *  Lifeline:
- *  -   Created by VPayment or directly
- *  -   When changed in VPayment
- *      - old payment is reversed
- *      - new payment created
- *
- *  When Payment is posed, the Allocation is made
- *  
- * @author Jorg Janke - * @version $Id: MPayment.java,v 1.4 2006/10/02 05:18:39 jjanke Exp $ - */ -public final class MPayment extends X_C_Payment - implements DocAction, ProcessCall -{ - /** - * Get Payments Of BPartner - * @param ctx context - * @param C_BPartner_ID id - * @param trxName transaction - * @return array - */ - public static MPayment[] getOfBPartner (Properties ctx, int C_BPartner_ID, String trxName) - { - ArrayList list = new ArrayList(); - String sql = "SELECT * FROM C_Payment WHERE C_BPartner_ID=?"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, trxName); - pstmt.setInt(1, C_BPartner_ID); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - list.add(new MPayment(ctx,rs, trxName)); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - s_log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - - // - MPayment[] retValue = new MPayment[list.size()]; - list.toArray(retValue); - return retValue; - } // getOfBPartner - - - /************************************************************************** - * Default Constructor - * @param ctx context - * @param C_Payment_ID payment to load, (0 create new payment) - * @param trxName trx name - */ - public MPayment (Properties ctx, int C_Payment_ID, String trxName) - { - super (ctx, C_Payment_ID, trxName); - // New - if (C_Payment_ID == 0) - { - setDocAction(DOCACTION_Complete); - setDocStatus(DOCSTATUS_Drafted); - setTrxType(TRXTYPE_Sales); - // - setR_AvsAddr (R_AVSZIP_Unavailable); - setR_AvsZip (R_AVSZIP_Unavailable); - // - setIsReceipt (true); - setIsApproved (false); - setIsReconciled (false); - setIsAllocated(false); - setIsOnline (false); - setIsSelfService(false); - setIsDelayedCapture (false); - setIsPrepayment(false); - setProcessed(false); - setProcessing(false); - setPosted (false); - // - setPayAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setTaxAmt(Env.ZERO); - setWriteOffAmt(Env.ZERO); - setIsOverUnderPayment (false); - setOverUnderAmt(Env.ZERO); - // - setDateTrx (new Timestamp(System.currentTimeMillis())); - setDateAcct (getDateTrx()); - setTenderType(TENDERTYPE_Check); - } - } // MPayment - - /** - * Load Constructor - * @param ctx context - * @param rs result set record - * @param trxName transaction - */ - public MPayment (Properties ctx, ResultSet rs, String trxName) - { - super(ctx, rs, trxName); - } // MPayment - - /** Temporary Payment Processors */ - private MPaymentProcessor[] m_mPaymentProcessors = null; - /** Temporary Payment Processor */ - private MPaymentProcessor m_mPaymentProcessor = null; - /** Logger */ - private static CLogger s_log = CLogger.getCLogger (MPayment.class); - /** Error Message */ - private String m_errorMessage = null; - - /** Reversal Indicator */ - public static String REVERSE_INDICATOR = "^"; - - /** - * Reset Payment to new status - */ - public void resetNew() - { - setC_Payment_ID(0); // forces new Record - set_ValueNoCheck ("DocumentNo", null); - setDocAction(DOCACTION_Prepare); - setDocStatus(DOCSTATUS_Drafted); - setProcessed(false); - setPosted (false); - setIsReconciled (false); - setIsAllocated(false); - setIsOnline(false); - setIsDelayedCapture (false); - // setC_BPartner_ID(0); - setC_Invoice_ID(0); - setC_Order_ID(0); - setC_Charge_ID(0); - setC_Project_ID(0); - setIsPrepayment(false); - } // resetNew - - /** - * Is Cashbook Transfer Trx - * @return true if Cash Trx - */ - public boolean isCashTrx() - { - return "X".equals(getTenderType()); - } // isCashTrx - - /************************************************************************** - * Set Credit Card. - * Need to set PatmentProcessor after Amount/Currency Set - * - * @param TrxType Transaction Type see TRX_ - * @param creditCardType CC type - * @param creditCardNumber CC number - * @param creditCardVV CC verification - * @param creditCardExpMM CC Exp MM - * @param creditCardExpYY CC Exp YY - * @return true if valid - */ - public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, - String creditCardVV, int creditCardExpMM, int creditCardExpYY) - { - setTenderType(TENDERTYPE_CreditCard); - setTrxType(TrxType); - // - setCreditCardType (creditCardType); - setCreditCardNumber (creditCardNumber); - setCreditCardVV (creditCardVV); - setCreditCardExpMM (creditCardExpMM); - setCreditCardExpYY (creditCardExpYY); - // - int check = MPaymentValidate.validateCreditCardNumber(creditCardNumber, creditCardType).length() - + MPaymentValidate.validateCreditCardExp(creditCardExpMM, creditCardExpYY).length(); - if (creditCardVV.length() > 0) - check += MPaymentValidate.validateCreditCardVV(creditCardVV, creditCardType).length(); - return check == 0; - } // setCreditCard - - /** - * Set Credit Card - Exp. - * Need to set PatmentProcessor after Amount/Currency Set - * - * @param TrxType Transaction Type see TRX_ - * @param creditCardType CC type - * @param creditCardNumber CC number - * @param creditCardVV CC verification - * @param creditCardExp CC Exp - * @return true if valid - */ - public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, - String creditCardVV, String creditCardExp) - { - return setCreditCard(TrxType, creditCardType, creditCardNumber, - creditCardVV, MPaymentValidate.getCreditCardExpMM(creditCardExp), - MPaymentValidate.getCreditCardExpYY(creditCardExp)); - } // setCreditCard - - /** - * Set ACH BankAccount Info - * - * @param C_BankAccount_ID bank account + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.compiere.model; + +import java.io.*; +import java.math.*; +import java.rmi.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; + +import org.compiere.db.*; +import org.compiere.interfaces.*; +import org.compiere.process.*; +import org.compiere.util.*; + +/** + * Payment Model. + * - retrieve and create payments for invoice + *
+ *  Event chain
+ *  - Payment inserted
+ *      C_Payment_Trg fires
+ *          update DocumentNo with payment summary
+ *  - Payment posted (C_Payment_Post)
+ *      create allocation line
+ *          C_Allocation_Trg fires
+ *              Update C_BPartner Open Item Amount
+ *      update invoice (IsPaid)
+ *      link invoice-payment if batch
+ *
+ *  Lifeline:
+ *  -   Created by VPayment or directly
+ *  -   When changed in VPayment
+ *      - old payment is reversed
+ *      - new payment created
+ *
+ *  When Payment is posed, the Allocation is made
+ *  
+ * @author Jorg Janke + * @version $Id: MPayment.java,v 1.4 2006/10/02 05:18:39 jjanke Exp $ + */ +public final class MPayment extends X_C_Payment + implements DocAction, ProcessCall +{ + /** + * Get Payments Of BPartner + * @param ctx context + * @param C_BPartner_ID id + * @param trxName transaction + * @return array + */ + public static MPayment[] getOfBPartner (Properties ctx, int C_BPartner_ID, String trxName) + { + ArrayList list = new ArrayList(); + String sql = "SELECT * FROM C_Payment WHERE C_BPartner_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, trxName); + pstmt.setInt(1, C_BPartner_ID); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + list.add(new MPayment(ctx,rs, trxName)); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + // + MPayment[] retValue = new MPayment[list.size()]; + list.toArray(retValue); + return retValue; + } // getOfBPartner + + + /************************************************************************** + * Default Constructor + * @param ctx context + * @param C_Payment_ID payment to load, (0 create new payment) + * @param trxName trx name + */ + public MPayment (Properties ctx, int C_Payment_ID, String trxName) + { + super (ctx, C_Payment_ID, trxName); + // New + if (C_Payment_ID == 0) + { + setDocAction(DOCACTION_Complete); + setDocStatus(DOCSTATUS_Drafted); + setTrxType(TRXTYPE_Sales); + // + setR_AvsAddr (R_AVSZIP_Unavailable); + setR_AvsZip (R_AVSZIP_Unavailable); + // + setIsReceipt (true); + setIsApproved (false); + setIsReconciled (false); + setIsAllocated(false); + setIsOnline (false); + setIsSelfService(false); + setIsDelayedCapture (false); + setIsPrepayment(false); + setProcessed(false); + setProcessing(false); + setPosted (false); + // + setPayAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setTaxAmt(Env.ZERO); + setWriteOffAmt(Env.ZERO); + setIsOverUnderPayment (false); + setOverUnderAmt(Env.ZERO); + // + setDateTrx (new Timestamp(System.currentTimeMillis())); + setDateAcct (getDateTrx()); + setTenderType(TENDERTYPE_Check); + } + } // MPayment + + /** + * Load Constructor + * @param ctx context + * @param rs result set record + * @param trxName transaction + */ + public MPayment (Properties ctx, ResultSet rs, String trxName) + { + super(ctx, rs, trxName); + } // MPayment + + /** Temporary Payment Processors */ + private MPaymentProcessor[] m_mPaymentProcessors = null; + /** Temporary Payment Processor */ + private MPaymentProcessor m_mPaymentProcessor = null; + /** Logger */ + private static CLogger s_log = CLogger.getCLogger (MPayment.class); + /** Error Message */ + private String m_errorMessage = null; + + /** Reversal Indicator */ + public static String REVERSE_INDICATOR = "^"; + + /** + * Reset Payment to new status + */ + public void resetNew() + { + setC_Payment_ID(0); // forces new Record + set_ValueNoCheck ("DocumentNo", null); + setDocAction(DOCACTION_Prepare); + setDocStatus(DOCSTATUS_Drafted); + setProcessed(false); + setPosted (false); + setIsReconciled (false); + setIsAllocated(false); + setIsOnline(false); + setIsDelayedCapture (false); + // setC_BPartner_ID(0); + setC_Invoice_ID(0); + setC_Order_ID(0); + setC_Charge_ID(0); + setC_Project_ID(0); + setIsPrepayment(false); + } // resetNew + + /** + * Is Cashbook Transfer Trx + * @return true if Cash Trx + */ + public boolean isCashTrx() + { + return "X".equals(getTenderType()); + } // isCashTrx + + /************************************************************************** + * Set Credit Card. + * Need to set PatmentProcessor after Amount/Currency Set + * + * @param TrxType Transaction Type see TRX_ + * @param creditCardType CC type + * @param creditCardNumber CC number + * @param creditCardVV CC verification + * @param creditCardExpMM CC Exp MM + * @param creditCardExpYY CC Exp YY + * @return true if valid + */ + public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, + String creditCardVV, int creditCardExpMM, int creditCardExpYY) + { + setTenderType(TENDERTYPE_CreditCard); + setTrxType(TrxType); + // + setCreditCardType (creditCardType); + setCreditCardNumber (creditCardNumber); + setCreditCardVV (creditCardVV); + setCreditCardExpMM (creditCardExpMM); + setCreditCardExpYY (creditCardExpYY); + // + int check = MPaymentValidate.validateCreditCardNumber(creditCardNumber, creditCardType).length() + + MPaymentValidate.validateCreditCardExp(creditCardExpMM, creditCardExpYY).length(); + if (creditCardVV.length() > 0) + check += MPaymentValidate.validateCreditCardVV(creditCardVV, creditCardType).length(); + return check == 0; + } // setCreditCard + + /** + * Set Credit Card - Exp. + * Need to set PatmentProcessor after Amount/Currency Set + * + * @param TrxType Transaction Type see TRX_ + * @param creditCardType CC type + * @param creditCardNumber CC number + * @param creditCardVV CC verification + * @param creditCardExp CC Exp + * @return true if valid + */ + public boolean setCreditCard (String TrxType, String creditCardType, String creditCardNumber, + String creditCardVV, String creditCardExp) + { + return setCreditCard(TrxType, creditCardType, creditCardNumber, + creditCardVV, MPaymentValidate.getCreditCardExpMM(creditCardExp), + MPaymentValidate.getCreditCardExpYY(creditCardExp)); + } // setCreditCard + + /** + * Set ACH BankAccount Info + * + * @param C_BankAccount_ID bank account * @param isReceipt true if receipt * @return true if valid */ @@ -272,954 +272,954 @@ public final class MPayment extends X_C_Payment // int check = MPaymentValidate.validateRoutingNo(getRoutingNo()).length() + MPaymentValidate.validateAccountNo(getAccountNo()).length(); - return check == 0; - } // setBankACH - - /** - * Set ACH BankAccount Info - * - * @param C_BankAccount_ID bank account - * @param isReceipt true if receipt - * @param tenderType - Direct Debit or Direct Deposit - * @param routingNo routing - * @param accountNo account - * @return true if valid - */ - public boolean setBankACH (int C_BankAccount_ID, boolean isReceipt, String tenderType, - String routingNo, String accountNo) - { - setTenderType (tenderType); - setIsReceipt (isReceipt); - // - if (C_BankAccount_ID > 0 - && (routingNo == null || routingNo.length() == 0 || accountNo == null || accountNo.length() == 0)) - setBankAccountDetails(C_BankAccount_ID); - else - { - setC_BankAccount_ID(C_BankAccount_ID); - setRoutingNo (routingNo); - setAccountNo (accountNo); - } - setCheckNo (""); - // - int check = MPaymentValidate.validateRoutingNo(routingNo).length() - + MPaymentValidate.validateAccountNo(accountNo).length(); - return check == 0; - } // setBankACH - - /** - * Set Check BankAccount Info - * - * @param C_BankAccount_ID bank account - * @param isReceipt true if receipt - * @param checkNo chack no - * @return true if valid - */ - public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, String checkNo) - { - return setBankCheck (C_BankAccount_ID, isReceipt, null, null, checkNo); - } // setBankCheck - - /** - * Set Check BankAccount Info - * - * @param C_BankAccount_ID bank account - * @param isReceipt true if receipt - * @param routingNo routing no - * @param accountNo account no - * @param checkNo chack no - * @return true if valid - */ - public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, - String routingNo, String accountNo, String checkNo) - { - setTenderType (TENDERTYPE_Check); - setIsReceipt (isReceipt); - // - if (C_BankAccount_ID > 0 - && (routingNo == null || routingNo.length() == 0 - || accountNo == null || accountNo.length() == 0)) - setBankAccountDetails(C_BankAccount_ID); - else - { - setC_BankAccount_ID(C_BankAccount_ID); - setRoutingNo (routingNo); - setAccountNo (accountNo); - } - setCheckNo (checkNo); - // - int check = MPaymentValidate.validateRoutingNo(routingNo).length() - + MPaymentValidate.validateAccountNo(accountNo).length() - + MPaymentValidate.validateCheckNo(checkNo).length(); - return check == 0; // no error message - } // setBankCheck - - /** - * Set Bank Account Details. - * Look up Routing No & Bank Acct No - * @param C_BankAccount_ID bank account - */ - public void setBankAccountDetails (int C_BankAccount_ID) - { - if (C_BankAccount_ID == 0) - return; - setC_BankAccount_ID(C_BankAccount_ID); - // - String sql = "SELECT b.RoutingNo, ba.AccountNo " - + "FROM C_BankAccount ba" - + " INNER JOIN C_Bank b ON (ba.C_Bank_ID=b.C_Bank_ID) " - + "WHERE C_BankAccount_ID=?"; - try - { - PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, C_BankAccount_ID); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - { - setRoutingNo (rs.getString(1)); - setAccountNo (rs.getString(2)); - } - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - } - } // setBankAccountDetails - - /** - * Set Account Address - * - * @param name name - * @param street street - * @param city city - * @param state state - * @param zip zip - * @param country country - */ - public void setAccountAddress (String name, String street, - String city, String state, String zip, String country) - { - setA_Name (name); - setA_Street (street); - setA_City (city); - setA_State (state); - setA_Zip (zip); - setA_Country(country); - } // setAccountAddress - - - /************************************************************************** - * Process Payment - * @return true if approved - */ - public boolean processOnline() - { - log.info ("Amt=" + getPayAmt()); - // - setIsOnline(true); - setErrorMessage(null); - // prevent charging twice - if (isApproved()) - { - log.info("Already processed - " + getR_Result() + " - " + getR_RespMsg()); - setErrorMessage("Payment already Processed"); - return true; - } - - if (m_mPaymentProcessor == null) - setPaymentProcessor(); - if (m_mPaymentProcessor == null) - { - log.log(Level.WARNING, "No Payment Processor Model"); - setErrorMessage("No Payment Processor Model"); - return false; - } - - boolean approved = false; - /** Process Payment on Server */ - if (DB.isRemoteObjects()) - { - Server server = CConnection.get().getServer(); - try - { - if (server != null) - { // See ServerBean - String trxName = null; // unconditionally save - save(trxName); // server reads from disk - approved = server.paymentOnline (getCtx(), getC_Payment_ID(), - m_mPaymentProcessor.getC_PaymentProcessor_ID(), trxName); - if (CLogMgt.isLevelFinest()) - s_log.fine("server => " + approved); - load(trxName); // server saves to disk - setIsApproved(approved); - return approved; - } - log.log(Level.WARNING, "AppsServer not found"); - } - catch (RemoteException ex) - { - log.log(Level.SEVERE, "AppsServer error", ex); - } - } - /** **/ - - // Try locally - try - { - PaymentProcessor pp = PaymentProcessor.create(m_mPaymentProcessor, this); - if (pp == null) - setErrorMessage("No Payment Processor"); - else - { - approved = pp.processCC (); - if (approved) - setErrorMessage(null); - else - setErrorMessage("From " + getCreditCardName() + ": " + getR_RespMsg()); - } - } - catch (Exception e) - { - log.log(Level.SEVERE, "processOnline", e); - setErrorMessage("Payment Processor Error"); - } - setIsApproved(approved); - return approved; - } // processOnline - - /** - * Process Online Payment. - * implements ProcessCall after standard constructor - * Called when pressing the Process_Online button in C_Payment - * - * @param ctx Context - * @param pi Process Info - * @param trx transaction - * @return true if the next process should be performed - */ - public boolean startProcess (Properties ctx, ProcessInfo pi, Trx trx) - { - log.info("startProcess - " + pi.getRecord_ID()); - boolean retValue = false; - // - if (pi.getRecord_ID() != get_ID()) - { - log.log(Level.SEVERE, "startProcess - Not same Payment - " + pi.getRecord_ID()); - return false; - } - // Process it - retValue = processOnline(); - save(); - return retValue; // Payment processed - } // startProcess - - - /** - * Before Save - * @param newRecord new - * @return save - */ - protected boolean beforeSave (boolean newRecord) - { - // We have a charge - if (getC_Charge_ID() != 0) - { - if (newRecord || is_ValueChanged("C_Charge_ID")) - { - setC_Order_ID(0); - setC_Invoice_ID(0); - setWriteOffAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setIsOverUnderPayment(false); - setOverUnderAmt(Env.ZERO); - setIsPrepayment(false); - } - } - // We need a BPartner - else if (getC_BPartner_ID() == 0 && !isCashTrx()) - { - if (getC_Invoice_ID() != 0) - ; - else if (getC_Order_ID() != 0) - ; - else - { - log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@: @C_BPartner_ID@")); - return false; - } - } - // Prepayment: No charge and order or project (not as acct dimension) - if (newRecord - || is_ValueChanged("C_Charge_ID") || is_ValueChanged("C_Invoice_ID") - || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) - setIsPrepayment (getC_Charge_ID() == 0 - && getC_BPartner_ID() != 0 - && (getC_Order_ID() != 0 - || (getC_Project_ID() != 0 && getC_Invoice_ID() == 0))); - if (isPrepayment()) - { - if (newRecord - || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) - { - setWriteOffAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setIsOverUnderPayment(false); - setOverUnderAmt(Env.ZERO); - } - } - - // Document Type/Receipt - if (getC_DocType_ID() == 0) - setC_DocType_ID(); - else - { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); - setIsReceipt(dt.isSOTrx()); - } - setDocumentNo(); - // - if (getDateAcct() == null) - setDateAcct(getDateTrx()); - // - if (!isOverUnderPayment()) - setOverUnderAmt(Env.ZERO); - - // Organization - if ((newRecord || is_ValueChanged("C_BankAccount_ID")) - && getC_Charge_ID() == 0) // allow different org for charge - { - MBankAccount ba = MBankAccount.get(getCtx(), getC_BankAccount_ID()); - if (ba.getAD_Org_ID() != 0) - setAD_Org_ID(ba.getAD_Org_ID()); - } - - return true; - } // beforeSave - - /** - * Get Allocated Amt in Payment Currency - * @return amount or null - */ - public BigDecimal getAllocatedAmt () - { - BigDecimal retValue = null; - if (getC_Charge_ID() != 0) - return getPayAmt(); - // - String sql = "SELECT SUM(currencyConvert(al.Amount," - + "ah.C_Currency_ID, p.C_Currency_ID,ah.DateTrx,p.C_ConversionType_ID, al.AD_Client_ID,al.AD_Org_ID)) " - + "FROM C_AllocationLine al" - + " INNER JOIN C_AllocationHdr ah ON (al.C_AllocationHdr_ID=ah.C_AllocationHdr_ID) " - + " INNER JOIN C_Payment p ON (al.C_Payment_ID=p.C_Payment_ID) " - + "WHERE al.C_Payment_ID=?" - + " AND ah.IsActive='Y' AND al.IsActive='Y'"; - // + " AND al.C_Invoice_ID IS NOT NULL"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_Payment_ID()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - retValue = rs.getBigDecimal(1); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, "getAllocatedAmt", e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // log.fine("getAllocatedAmt - " + retValue); - // ? ROUND(NVL(v_AllocatedAmt,0), 2); - return retValue; - } // getAllocatedAmt - - /** - * Test Allocation (and set allocated flag) - * @return true if updated - */ - public boolean testAllocation() - { - // Cash Trx always allocated - if (isCashTrx()) - { - if (!isAllocated()) - { - setIsAllocated(true); - return true; - } - return false; - } - // - BigDecimal alloc = getAllocatedAmt(); - if (alloc == null) - alloc = Env.ZERO; - BigDecimal total = getPayAmt(); - if (!isReceipt()) - total = total.negate(); - boolean test = total.compareTo(alloc) == 0; - boolean change = test != isAllocated(); - if (change) - setIsAllocated(test); - log.fine("Allocated=" + test - + " (" + alloc + "=" + total + ")"); - return change; - } // testAllocation - - /** - * Set Allocated Flag for payments - * @param ctx context - * @param C_BPartner_ID if 0 all - * @param trxName trx - */ - public static void setIsAllocated (Properties ctx, int C_BPartner_ID, String trxName) - { - int counter = 0; - String sql = "SELECT * FROM C_Payment " - + "WHERE IsAllocated='N' AND DocStatus IN ('CO','CL')"; - if (C_BPartner_ID > 1) - sql += " AND C_BPartner_ID=?"; - else - sql += " AND AD_Client_ID=" + Env.getAD_Client_ID(ctx); - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement (sql, trxName); - if (C_BPartner_ID > 1) - pstmt.setInt (1, C_BPartner_ID); - ResultSet rs = pstmt.executeQuery (); - while (rs.next ()) - { - MPayment pay = new MPayment (ctx, rs, trxName); - if (pay.testAllocation()) - if (pay.save()) - counter++; - } - rs.close (); - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - s_log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close (); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - s_log.config("#" + counter); - } // setIsAllocated - - /************************************************************************** - * Set Error Message - * @param errorMessage error message - */ - public void setErrorMessage(String errorMessage) - { - m_errorMessage = errorMessage; - } // setErrorMessage - - /** - * Get Error Message - * @return error message - */ - public String getErrorMessage() - { - return m_errorMessage; - } // getErrorMessage - - - /** - * Set Bank Account for Payment. - * @param C_BankAccount_ID C_BankAccount_ID - */ - public void setC_BankAccount_ID (int C_BankAccount_ID) - { - if (C_BankAccount_ID == 0) - { - setPaymentProcessor(); - if (getC_BankAccount_ID() == 0) - throw new IllegalArgumentException("Can't find Bank Account"); - } - else - super.setC_BankAccount_ID(C_BankAccount_ID); - } // setC_BankAccount_ID - - /** - * Set BankAccount and PaymentProcessor - * @return true if found - */ - public boolean setPaymentProcessor () - { - return setPaymentProcessor (getTenderType(), getCreditCardType()); - } // setPaymentProcessor - - /** - * Set BankAccount and PaymentProcessor - * @param tender TenderType see TENDER_ - * @param CCType CC Type see CC_ - * @return true if found - */ - public boolean setPaymentProcessor (String tender, String CCType) - { - m_mPaymentProcessor = null; - // Get Processor List - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), - getC_Currency_ID(), getPayAmt(), get_TrxName()); - // Relax Amount - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), - getC_Currency_ID(), Env.ZERO, get_TrxName()); - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - return false; - - // Find the first right one - for (int i = 0; i < m_mPaymentProcessors.length; i++) - { - if (m_mPaymentProcessors[i].accepts (tender, CCType)) - { - m_mPaymentProcessor = m_mPaymentProcessors[i]; - } - } - if (m_mPaymentProcessor != null) - setC_BankAccount_ID (m_mPaymentProcessor.getC_BankAccount_ID()); - // - return m_mPaymentProcessor != null; - } // setPaymentProcessor - - - /** - * Get Accepted Credit Cards for PayAmt (default 0) - * @return credit cards - */ - public ValueNamePair[] getCreditCards () - { - return getCreditCards(getPayAmt()); - } // getCreditCards - - - /** - * Get Accepted Credit Cards for amount - * @param amt trx amount - * @return credit cards - */ - public ValueNamePair[] getCreditCards (BigDecimal amt) - { - try - { - if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) - m_mPaymentProcessors = MPaymentProcessor.find (getCtx (), null, null, - getAD_Client_ID (), getC_Currency_ID (), amt, get_TrxName()); - // - HashMap map = new HashMap(); // to eliminate duplicates - for (int i = 0; i < m_mPaymentProcessors.length; i++) - { - if (m_mPaymentProcessors[i].isAcceptAMEX ()) - map.put (CREDITCARDTYPE_Amex, getCreditCardPair (CREDITCARDTYPE_Amex)); - if (m_mPaymentProcessors[i].isAcceptDiners ()) - map.put (CREDITCARDTYPE_Diners, getCreditCardPair (CREDITCARDTYPE_Diners)); - if (m_mPaymentProcessors[i].isAcceptDiscover ()) - map.put (CREDITCARDTYPE_Discover, getCreditCardPair (CREDITCARDTYPE_Discover)); - if (m_mPaymentProcessors[i].isAcceptMC ()) - map.put (CREDITCARDTYPE_MasterCard, getCreditCardPair (CREDITCARDTYPE_MasterCard)); - if (m_mPaymentProcessors[i].isAcceptCorporate ()) - map.put (CREDITCARDTYPE_PurchaseCard, getCreditCardPair (CREDITCARDTYPE_PurchaseCard)); - if (m_mPaymentProcessors[i].isAcceptVisa ()) - map.put (CREDITCARDTYPE_Visa, getCreditCardPair (CREDITCARDTYPE_Visa)); - } // for all payment processors - // - ValueNamePair[] retValue = new ValueNamePair[map.size ()]; - map.values ().toArray (retValue); - log.fine("getCreditCards - #" + retValue.length + " - Processors=" + m_mPaymentProcessors.length); - return retValue; - } - catch (Exception ex) - { - ex.printStackTrace(); - return null; - } - } // getCreditCards - - /** - * Get Type and name pair - * @param CreditCardType credit card Type - * @return pair - */ - private ValueNamePair getCreditCardPair (String CreditCardType) - { - return new ValueNamePair (CreditCardType, getCreditCardName(CreditCardType)); - } // getCreditCardPair - - - /************************************************************************** - * Credit Card Number - * @param CreditCardNumber CreditCard Number - */ - public void setCreditCardNumber (String CreditCardNumber) - { - super.setCreditCardNumber (MPaymentValidate.checkNumeric(CreditCardNumber)); - } // setCreditCardNumber - - /** - * Verification Code - * @param newCreditCardVV CC verification - */ - public void setCreditCardVV(String newCreditCardVV) - { - super.setCreditCardVV (MPaymentValidate.checkNumeric(newCreditCardVV)); - } // setCreditCardVV - - /** - * Two Digit CreditCard MM - * @param CreditCardExpMM Exp month - */ - public void setCreditCardExpMM (int CreditCardExpMM) - { - if (CreditCardExpMM < 1 || CreditCardExpMM > 12) - ; - else - super.setCreditCardExpMM (CreditCardExpMM); - } // setCreditCardExpMM - - /** - * Two digit CreditCard YY (til 2020) - * @param newCreditCardExpYY 2 or 4 digit year - */ - public void setCreditCardExpYY (int newCreditCardExpYY) - { - int CreditCardExpYY = newCreditCardExpYY; - if (newCreditCardExpYY > 1999) - CreditCardExpYY = newCreditCardExpYY-2000; - super.setCreditCardExpYY(CreditCardExpYY); - } // setCreditCardExpYY - - /** - * CreditCard Exp MMYY - * @param mmyy Exp in form of mmyy - * @return true if valid - */ - public boolean setCreditCardExp (String mmyy) - { - if (MPaymentValidate.validateCreditCardExp(mmyy).length() != 0) - return false; - // - String exp = MPaymentValidate.checkNumeric(mmyy); - String mmStr = exp.substring(0,2); - String yyStr = exp.substring(2,4); - setCreditCardExpMM (Integer.parseInt(mmStr)); - setCreditCardExpYY (Integer.parseInt(yyStr)); - return true; - } // setCreditCardExp - - - /** - * CreditCard Exp MMYY - * @param delimiter / - or null - * @return Exp - */ - public String getCreditCardExp(String delimiter) - { - String mm = String.valueOf(getCreditCardExpMM()); - String yy = String.valueOf(getCreditCardExpYY()); - - StringBuffer retValue = new StringBuffer(); - if (mm.length() == 1) - retValue.append("0"); - retValue.append(mm); - // - if (delimiter != null) - retValue.append(delimiter); - // - if (yy.length() == 1) - retValue.append("0"); - retValue.append(yy); - // - return (retValue.toString()); - } // getCreditCardExp - - /** - * MICR - * @param MICR MICR - */ - public void setMicr (String MICR) - { - super.setMicr (MPaymentValidate.checkNumeric(MICR)); - } // setBankMICR - - /** - * Routing No - * @param RoutingNo Routing No - */ - public void setRoutingNo(String RoutingNo) - { - super.setRoutingNo (MPaymentValidate.checkNumeric(RoutingNo)); - } // setBankRoutingNo - - - /** - * Bank Account No - * @param AccountNo AccountNo - */ - public void setAccountNo (String AccountNo) - { - super.setAccountNo (MPaymentValidate.checkNumeric(AccountNo)); - } // setBankAccountNo - - - /** - * Check No - * @param CheckNo Check No - */ - public void setCheckNo(String CheckNo) - { - super.setCheckNo(MPaymentValidate.checkNumeric(CheckNo)); - } // setBankCheckNo - - - /** - * Set DocumentNo to Payment info. - * If there is a R_PnRef that is set automatically - */ - private void setDocumentNo() - { - // Cash Transfer - if ("X".equals(getTenderType())) - return; - // Current Document No - String documentNo = getDocumentNo(); - // Existing reversal - if (documentNo != null - && documentNo.indexOf(REVERSE_INDICATOR) >= 0) - return; - - // If external number exists - enforce it - if (getR_PnRef() != null && getR_PnRef().length() > 0) - { - if (!getR_PnRef().equals(documentNo)) - setDocumentNo(getR_PnRef()); - return; - } - - documentNo = ""; - // Credit Card - if (TENDERTYPE_CreditCard.equals(getTenderType())) - { - documentNo = getCreditCardType() - + " " + Obscure.obscure(getCreditCardNumber()) - + " " + getCreditCardExpMM() - + "/" + getCreditCardExpYY(); - } - // Own Check No - else if (TENDERTYPE_Check.equals(getTenderType()) - && !isReceipt() - && getCheckNo() != null && getCheckNo().length() > 0) - { - documentNo = getCheckNo(); - } - // Customer Check: Routing: Account #Check - else if (TENDERTYPE_Check.equals(getTenderType()) - && isReceipt()) - { - if (getRoutingNo() != null) - documentNo = getRoutingNo() + ": "; - if (getAccountNo() != null) - documentNo += getAccountNo(); - if (getCheckNo() != null) - { - if (documentNo.length() > 0) - documentNo += " "; - documentNo += "#" + getCheckNo(); - } - } - - // Set Document No - documentNo = documentNo.trim(); - if (documentNo.length() > 0) - setDocumentNo(documentNo); - } // setDocumentNo - - /** - * Set Refernce No (and Document No) - * @param R_PnRef reference - */ - public void setR_PnRef (String R_PnRef) - { - super.setR_PnRef (R_PnRef); - if (R_PnRef != null) - setDocumentNo (R_PnRef); - } // setR_PnRef - - // --------------- - - /** - * Set Payment Amount - * @param PayAmt Pay Amt - */ - public void setPayAmt (BigDecimal PayAmt) - { - super.setPayAmt(PayAmt == null ? Env.ZERO : PayAmt); - } // setPayAmt - - /** - * Set Payment Amount - * - * @param C_Currency_ID currency - * @param payAmt amount - */ - public void setAmount (int C_Currency_ID, BigDecimal payAmt) - { - if (C_Currency_ID == 0) - C_Currency_ID = MClient.get(getCtx()).getC_Currency_ID(); - setC_Currency_ID(C_Currency_ID); - setPayAmt(payAmt); - } // setAmount - - /** - * Discount Amt - * @param DiscountAmt Discount - */ - public void setDiscountAmt (BigDecimal DiscountAmt) - { - super.setDiscountAmt (DiscountAmt == null ? Env.ZERO : DiscountAmt); - } // setDiscountAmt - - /** - * WriteOff Amt - * @param WriteOffAmt WriteOff - */ - public void setWriteOffAmt (BigDecimal WriteOffAmt) - { - super.setWriteOffAmt (WriteOffAmt == null ? Env.ZERO : WriteOffAmt); - } // setWriteOffAmt - - /** - * OverUnder Amt - * @param OverUnderAmt OverUnder - */ - public void setOverUnderAmt (BigDecimal OverUnderAmt) - { - super.setOverUnderAmt (OverUnderAmt == null ? Env.ZERO : OverUnderAmt); - setIsOverUnderPayment(getOverUnderAmt().compareTo(Env.ZERO) != 0); - } // setOverUnderAmt - - /** - * Tax Amt - * @param TaxAmt Tax - */ - public void setTaxAmt (BigDecimal TaxAmt) - { - super.setTaxAmt (TaxAmt == null ? Env.ZERO : TaxAmt); - } // setTaxAmt - - /** - * Set Info from BP Bank Account - * @param ba BP bank account - */ - public void setBP_BankAccount (MBPBankAccount ba) - { - log.fine("" + ba); - if (ba == null) - return; - setC_BPartner_ID(ba.getC_BPartner_ID()); - setAccountAddress(ba.getA_Name(), ba.getA_Street(), ba.getA_City(), - ba.getA_State(), ba.getA_Zip(), ba.getA_Country()); - setA_EMail(ba.getA_EMail()); - setA_Ident_DL(ba.getA_Ident_DL()); - setA_Ident_SSN(ba.getA_Ident_SSN()); - // CC - if (ba.getCreditCardType() != null) - setCreditCardType(ba.getCreditCardType()); - if (ba.getCreditCardNumber() != null) - setCreditCardNumber(ba.getCreditCardNumber()); - if (ba.getCreditCardExpMM() != 0) - setCreditCardExpMM(ba.getCreditCardExpMM()); - if (ba.getCreditCardExpYY() != 0) - setCreditCardExpYY(ba.getCreditCardExpYY()); - if (ba.getCreditCardVV() != null) - setCreditCardVV(ba.getCreditCardVV()); - // Bank - if (ba.getAccountNo() != null) - setAccountNo(ba.getAccountNo()); - if (ba.getRoutingNo() != null) - setRoutingNo(ba.getRoutingNo()); - } // setBP_BankAccount - - /** - * Save Info from BP Bank Account - * @param ba BP bank account - * @return true if saved - */ - public boolean saveToBP_BankAccount (MBPBankAccount ba) - { - if (ba == null) - return false; - ba.setA_Name(getA_Name()); - ba.setA_Street(getA_Street()); - ba.setA_City(getA_City()); - ba.setA_State(getA_State()); - ba.setA_Zip(getA_Zip()); - ba.setA_Country(getA_Country()); - ba.setA_EMail(getA_EMail()); - ba.setA_Ident_DL(getA_Ident_DL()); - ba.setA_Ident_SSN(getA_Ident_SSN()); - // CC - ba.setCreditCardType(getCreditCardType()); - ba.setCreditCardNumber(getCreditCardNumber()); - ba.setCreditCardExpMM(getCreditCardExpMM()); - ba.setCreditCardExpYY(getCreditCardExpYY()); - ba.setCreditCardVV(getCreditCardVV()); - // Bank - if (getAccountNo() != null) - ba.setAccountNo(getAccountNo()); - if (getRoutingNo() != null) - ba.setRoutingNo(getRoutingNo()); - // Trx - ba.setR_AvsAddr(getR_AvsAddr()); - ba.setR_AvsZip(getR_AvsZip()); - // - boolean ok = ba.save(get_TrxName()); - log.fine("saveToBP_BankAccount - " + ba); - return ok; - } // setBP_BankAccount - - /** - * Set Doc Type bases on IsReceipt - */ - private void setC_DocType_ID () - { - setC_DocType_ID(isReceipt()); - } // setC_DocType_ID - - /** - * Set Doc Type - * @param isReceipt is receipt - */ - public void setC_DocType_ID (boolean isReceipt) - { - setIsReceipt(isReceipt); - String sql = "SELECT C_DocType_ID FROM C_DocType WHERE AD_Client_ID=? AND DocBaseType=? ORDER BY IsDefault DESC"; - try - { + return check == 0; + } // setBankACH + + /** + * Set ACH BankAccount Info + * + * @param C_BankAccount_ID bank account + * @param isReceipt true if receipt + * @param tenderType - Direct Debit or Direct Deposit + * @param routingNo routing + * @param accountNo account + * @return true if valid + */ + public boolean setBankACH (int C_BankAccount_ID, boolean isReceipt, String tenderType, + String routingNo, String accountNo) + { + setTenderType (tenderType); + setIsReceipt (isReceipt); + // + if (C_BankAccount_ID > 0 + && (routingNo == null || routingNo.length() == 0 || accountNo == null || accountNo.length() == 0)) + setBankAccountDetails(C_BankAccount_ID); + else + { + setC_BankAccount_ID(C_BankAccount_ID); + setRoutingNo (routingNo); + setAccountNo (accountNo); + } + setCheckNo (""); + // + int check = MPaymentValidate.validateRoutingNo(routingNo).length() + + MPaymentValidate.validateAccountNo(accountNo).length(); + return check == 0; + } // setBankACH + + /** + * Set Check BankAccount Info + * + * @param C_BankAccount_ID bank account + * @param isReceipt true if receipt + * @param checkNo chack no + * @return true if valid + */ + public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, String checkNo) + { + return setBankCheck (C_BankAccount_ID, isReceipt, null, null, checkNo); + } // setBankCheck + + /** + * Set Check BankAccount Info + * + * @param C_BankAccount_ID bank account + * @param isReceipt true if receipt + * @param routingNo routing no + * @param accountNo account no + * @param checkNo chack no + * @return true if valid + */ + public boolean setBankCheck (int C_BankAccount_ID, boolean isReceipt, + String routingNo, String accountNo, String checkNo) + { + setTenderType (TENDERTYPE_Check); + setIsReceipt (isReceipt); + // + if (C_BankAccount_ID > 0 + && (routingNo == null || routingNo.length() == 0 + || accountNo == null || accountNo.length() == 0)) + setBankAccountDetails(C_BankAccount_ID); + else + { + setC_BankAccount_ID(C_BankAccount_ID); + setRoutingNo (routingNo); + setAccountNo (accountNo); + } + setCheckNo (checkNo); + // + int check = MPaymentValidate.validateRoutingNo(routingNo).length() + + MPaymentValidate.validateAccountNo(accountNo).length() + + MPaymentValidate.validateCheckNo(checkNo).length(); + return check == 0; // no error message + } // setBankCheck + + /** + * Set Bank Account Details. + * Look up Routing No & Bank Acct No + * @param C_BankAccount_ID bank account + */ + public void setBankAccountDetails (int C_BankAccount_ID) + { + if (C_BankAccount_ID == 0) + return; + setC_BankAccount_ID(C_BankAccount_ID); + // + String sql = "SELECT b.RoutingNo, ba.AccountNo " + + "FROM C_BankAccount ba" + + " INNER JOIN C_Bank b ON (ba.C_Bank_ID=b.C_Bank_ID) " + + "WHERE C_BankAccount_ID=?"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, C_BankAccount_ID); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + { + setRoutingNo (rs.getString(1)); + setAccountNo (rs.getString(2)); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + } // setBankAccountDetails + + /** + * Set Account Address + * + * @param name name + * @param street street + * @param city city + * @param state state + * @param zip zip + * @param country country + */ + public void setAccountAddress (String name, String street, + String city, String state, String zip, String country) + { + setA_Name (name); + setA_Street (street); + setA_City (city); + setA_State (state); + setA_Zip (zip); + setA_Country(country); + } // setAccountAddress + + + /************************************************************************** + * Process Payment + * @return true if approved + */ + public boolean processOnline() + { + log.info ("Amt=" + getPayAmt()); + // + setIsOnline(true); + setErrorMessage(null); + // prevent charging twice + if (isApproved()) + { + log.info("Already processed - " + getR_Result() + " - " + getR_RespMsg()); + setErrorMessage("Payment already Processed"); + return true; + } + + if (m_mPaymentProcessor == null) + setPaymentProcessor(); + if (m_mPaymentProcessor == null) + { + log.log(Level.WARNING, "No Payment Processor Model"); + setErrorMessage("No Payment Processor Model"); + return false; + } + + boolean approved = false; + /** Process Payment on Server */ + if (DB.isRemoteObjects()) + { + Server server = CConnection.get().getServer(); + try + { + if (server != null) + { // See ServerBean + String trxName = null; // unconditionally save + save(trxName); // server reads from disk + approved = server.paymentOnline (getCtx(), getC_Payment_ID(), + m_mPaymentProcessor.getC_PaymentProcessor_ID(), trxName); + if (CLogMgt.isLevelFinest()) + s_log.fine("server => " + approved); + load(trxName); // server saves to disk + setIsApproved(approved); + return approved; + } + log.log(Level.WARNING, "AppsServer not found"); + } + catch (RemoteException ex) + { + log.log(Level.SEVERE, "AppsServer error", ex); + } + } + /** **/ + + // Try locally + try + { + PaymentProcessor pp = PaymentProcessor.create(m_mPaymentProcessor, this); + if (pp == null) + setErrorMessage("No Payment Processor"); + else + { + approved = pp.processCC (); + if (approved) + setErrorMessage(null); + else + setErrorMessage("From " + getCreditCardName() + ": " + getR_RespMsg()); + } + } + catch (Exception e) + { + log.log(Level.SEVERE, "processOnline", e); + setErrorMessage("Payment Processor Error"); + } + setIsApproved(approved); + return approved; + } // processOnline + + /** + * Process Online Payment. + * implements ProcessCall after standard constructor + * Called when pressing the Process_Online button in C_Payment + * + * @param ctx Context + * @param pi Process Info + * @param trx transaction + * @return true if the next process should be performed + */ + public boolean startProcess (Properties ctx, ProcessInfo pi, Trx trx) + { + log.info("startProcess - " + pi.getRecord_ID()); + boolean retValue = false; + // + if (pi.getRecord_ID() != get_ID()) + { + log.log(Level.SEVERE, "startProcess - Not same Payment - " + pi.getRecord_ID()); + return false; + } + // Process it + retValue = processOnline(); + save(); + return retValue; // Payment processed + } // startProcess + + + /** + * Before Save + * @param newRecord new + * @return save + */ + protected boolean beforeSave (boolean newRecord) + { + // We have a charge + if (getC_Charge_ID() != 0) + { + if (newRecord || is_ValueChanged("C_Charge_ID")) + { + setC_Order_ID(0); + setC_Invoice_ID(0); + setWriteOffAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setIsOverUnderPayment(false); + setOverUnderAmt(Env.ZERO); + setIsPrepayment(false); + } + } + // We need a BPartner + else if (getC_BPartner_ID() == 0 && !isCashTrx()) + { + if (getC_Invoice_ID() != 0) + ; + else if (getC_Order_ID() != 0) + ; + else + { + log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@: @C_BPartner_ID@")); + return false; + } + } + // Prepayment: No charge and order or project (not as acct dimension) + if (newRecord + || is_ValueChanged("C_Charge_ID") || is_ValueChanged("C_Invoice_ID") + || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) + setIsPrepayment (getC_Charge_ID() == 0 + && getC_BPartner_ID() != 0 + && (getC_Order_ID() != 0 + || (getC_Project_ID() != 0 && getC_Invoice_ID() == 0))); + if (isPrepayment()) + { + if (newRecord + || is_ValueChanged("C_Order_ID") || is_ValueChanged("C_Project_ID")) + { + setWriteOffAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setIsOverUnderPayment(false); + setOverUnderAmt(Env.ZERO); + } + } + + // Document Type/Receipt + if (getC_DocType_ID() == 0) + setC_DocType_ID(); + else + { + MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + setIsReceipt(dt.isSOTrx()); + } + setDocumentNo(); + // + if (getDateAcct() == null) + setDateAcct(getDateTrx()); + // + if (!isOverUnderPayment()) + setOverUnderAmt(Env.ZERO); + + // Organization + if ((newRecord || is_ValueChanged("C_BankAccount_ID")) + && getC_Charge_ID() == 0) // allow different org for charge + { + MBankAccount ba = MBankAccount.get(getCtx(), getC_BankAccount_ID()); + if (ba.getAD_Org_ID() != 0) + setAD_Org_ID(ba.getAD_Org_ID()); + } + + return true; + } // beforeSave + + /** + * Get Allocated Amt in Payment Currency + * @return amount or null + */ + public BigDecimal getAllocatedAmt () + { + BigDecimal retValue = null; + if (getC_Charge_ID() != 0) + return getPayAmt(); + // + String sql = "SELECT SUM(currencyConvert(al.Amount," + + "ah.C_Currency_ID, p.C_Currency_ID,ah.DateTrx,p.C_ConversionType_ID, al.AD_Client_ID,al.AD_Org_ID)) " + + "FROM C_AllocationLine al" + + " INNER JOIN C_AllocationHdr ah ON (al.C_AllocationHdr_ID=ah.C_AllocationHdr_ID) " + + " INNER JOIN C_Payment p ON (al.C_Payment_ID=p.C_Payment_ID) " + + "WHERE al.C_Payment_ID=?" + + " AND ah.IsActive='Y' AND al.IsActive='Y'"; + // + " AND al.C_Invoice_ID IS NOT NULL"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_Payment_ID()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + retValue = rs.getBigDecimal(1); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, "getAllocatedAmt", e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // log.fine("getAllocatedAmt - " + retValue); + // ? ROUND(NVL(v_AllocatedAmt,0), 2); + return retValue; + } // getAllocatedAmt + + /** + * Test Allocation (and set allocated flag) + * @return true if updated + */ + public boolean testAllocation() + { + // Cash Trx always allocated + if (isCashTrx()) + { + if (!isAllocated()) + { + setIsAllocated(true); + return true; + } + return false; + } + // + BigDecimal alloc = getAllocatedAmt(); + if (alloc == null) + alloc = Env.ZERO; + BigDecimal total = getPayAmt(); + if (!isReceipt()) + total = total.negate(); + boolean test = total.compareTo(alloc) == 0; + boolean change = test != isAllocated(); + if (change) + setIsAllocated(test); + log.fine("Allocated=" + test + + " (" + alloc + "=" + total + ")"); + return change; + } // testAllocation + + /** + * Set Allocated Flag for payments + * @param ctx context + * @param C_BPartner_ID if 0 all + * @param trxName trx + */ + public static void setIsAllocated (Properties ctx, int C_BPartner_ID, String trxName) + { + int counter = 0; + String sql = "SELECT * FROM C_Payment " + + "WHERE IsAllocated='N' AND DocStatus IN ('CO','CL')"; + if (C_BPartner_ID > 1) + sql += " AND C_BPartner_ID=?"; + else + sql += " AND AD_Client_ID=" + Env.getAD_Client_ID(ctx); + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, trxName); + if (C_BPartner_ID > 1) + pstmt.setInt (1, C_BPartner_ID); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + MPayment pay = new MPayment (ctx, rs, trxName); + if (pay.testAllocation()) + if (pay.save()) + counter++; + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + s_log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + s_log.config("#" + counter); + } // setIsAllocated + + /************************************************************************** + * Set Error Message + * @param errorMessage error message + */ + public void setErrorMessage(String errorMessage) + { + m_errorMessage = errorMessage; + } // setErrorMessage + + /** + * Get Error Message + * @return error message + */ + public String getErrorMessage() + { + return m_errorMessage; + } // getErrorMessage + + + /** + * Set Bank Account for Payment. + * @param C_BankAccount_ID C_BankAccount_ID + */ + public void setC_BankAccount_ID (int C_BankAccount_ID) + { + if (C_BankAccount_ID == 0) + { + setPaymentProcessor(); + if (getC_BankAccount_ID() == 0) + throw new IllegalArgumentException("Can't find Bank Account"); + } + else + super.setC_BankAccount_ID(C_BankAccount_ID); + } // setC_BankAccount_ID + + /** + * Set BankAccount and PaymentProcessor + * @return true if found + */ + public boolean setPaymentProcessor () + { + return setPaymentProcessor (getTenderType(), getCreditCardType()); + } // setPaymentProcessor + + /** + * Set BankAccount and PaymentProcessor + * @param tender TenderType see TENDER_ + * @param CCType CC Type see CC_ + * @return true if found + */ + public boolean setPaymentProcessor (String tender, String CCType) + { + m_mPaymentProcessor = null; + // Get Processor List + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), + getC_Currency_ID(), getPayAmt(), get_TrxName()); + // Relax Amount + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + m_mPaymentProcessors = MPaymentProcessor.find (getCtx(), tender, CCType, getAD_Client_ID(), + getC_Currency_ID(), Env.ZERO, get_TrxName()); + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + return false; + + // Find the first right one + for (int i = 0; i < m_mPaymentProcessors.length; i++) + { + if (m_mPaymentProcessors[i].accepts (tender, CCType)) + { + m_mPaymentProcessor = m_mPaymentProcessors[i]; + } + } + if (m_mPaymentProcessor != null) + setC_BankAccount_ID (m_mPaymentProcessor.getC_BankAccount_ID()); + // + return m_mPaymentProcessor != null; + } // setPaymentProcessor + + + /** + * Get Accepted Credit Cards for PayAmt (default 0) + * @return credit cards + */ + public ValueNamePair[] getCreditCards () + { + return getCreditCards(getPayAmt()); + } // getCreditCards + + + /** + * Get Accepted Credit Cards for amount + * @param amt trx amount + * @return credit cards + */ + public ValueNamePair[] getCreditCards (BigDecimal amt) + { + try + { + if (m_mPaymentProcessors == null || m_mPaymentProcessors.length == 0) + m_mPaymentProcessors = MPaymentProcessor.find (getCtx (), null, null, + getAD_Client_ID (), getC_Currency_ID (), amt, get_TrxName()); + // + HashMap map = new HashMap(); // to eliminate duplicates + for (int i = 0; i < m_mPaymentProcessors.length; i++) + { + if (m_mPaymentProcessors[i].isAcceptAMEX ()) + map.put (CREDITCARDTYPE_Amex, getCreditCardPair (CREDITCARDTYPE_Amex)); + if (m_mPaymentProcessors[i].isAcceptDiners ()) + map.put (CREDITCARDTYPE_Diners, getCreditCardPair (CREDITCARDTYPE_Diners)); + if (m_mPaymentProcessors[i].isAcceptDiscover ()) + map.put (CREDITCARDTYPE_Discover, getCreditCardPair (CREDITCARDTYPE_Discover)); + if (m_mPaymentProcessors[i].isAcceptMC ()) + map.put (CREDITCARDTYPE_MasterCard, getCreditCardPair (CREDITCARDTYPE_MasterCard)); + if (m_mPaymentProcessors[i].isAcceptCorporate ()) + map.put (CREDITCARDTYPE_PurchaseCard, getCreditCardPair (CREDITCARDTYPE_PurchaseCard)); + if (m_mPaymentProcessors[i].isAcceptVisa ()) + map.put (CREDITCARDTYPE_Visa, getCreditCardPair (CREDITCARDTYPE_Visa)); + } // for all payment processors + // + ValueNamePair[] retValue = new ValueNamePair[map.size ()]; + map.values ().toArray (retValue); + log.fine("getCreditCards - #" + retValue.length + " - Processors=" + m_mPaymentProcessors.length); + return retValue; + } + catch (Exception ex) + { + ex.printStackTrace(); + return null; + } + } // getCreditCards + + /** + * Get Type and name pair + * @param CreditCardType credit card Type + * @return pair + */ + private ValueNamePair getCreditCardPair (String CreditCardType) + { + return new ValueNamePair (CreditCardType, getCreditCardName(CreditCardType)); + } // getCreditCardPair + + + /************************************************************************** + * Credit Card Number + * @param CreditCardNumber CreditCard Number + */ + public void setCreditCardNumber (String CreditCardNumber) + { + super.setCreditCardNumber (MPaymentValidate.checkNumeric(CreditCardNumber)); + } // setCreditCardNumber + + /** + * Verification Code + * @param newCreditCardVV CC verification + */ + public void setCreditCardVV(String newCreditCardVV) + { + super.setCreditCardVV (MPaymentValidate.checkNumeric(newCreditCardVV)); + } // setCreditCardVV + + /** + * Two Digit CreditCard MM + * @param CreditCardExpMM Exp month + */ + public void setCreditCardExpMM (int CreditCardExpMM) + { + if (CreditCardExpMM < 1 || CreditCardExpMM > 12) + ; + else + super.setCreditCardExpMM (CreditCardExpMM); + } // setCreditCardExpMM + + /** + * Two digit CreditCard YY (til 2020) + * @param newCreditCardExpYY 2 or 4 digit year + */ + public void setCreditCardExpYY (int newCreditCardExpYY) + { + int CreditCardExpYY = newCreditCardExpYY; + if (newCreditCardExpYY > 1999) + CreditCardExpYY = newCreditCardExpYY-2000; + super.setCreditCardExpYY(CreditCardExpYY); + } // setCreditCardExpYY + + /** + * CreditCard Exp MMYY + * @param mmyy Exp in form of mmyy + * @return true if valid + */ + public boolean setCreditCardExp (String mmyy) + { + if (MPaymentValidate.validateCreditCardExp(mmyy).length() != 0) + return false; + // + String exp = MPaymentValidate.checkNumeric(mmyy); + String mmStr = exp.substring(0,2); + String yyStr = exp.substring(2,4); + setCreditCardExpMM (Integer.parseInt(mmStr)); + setCreditCardExpYY (Integer.parseInt(yyStr)); + return true; + } // setCreditCardExp + + + /** + * CreditCard Exp MMYY + * @param delimiter / - or null + * @return Exp + */ + public String getCreditCardExp(String delimiter) + { + String mm = String.valueOf(getCreditCardExpMM()); + String yy = String.valueOf(getCreditCardExpYY()); + + StringBuffer retValue = new StringBuffer(); + if (mm.length() == 1) + retValue.append("0"); + retValue.append(mm); + // + if (delimiter != null) + retValue.append(delimiter); + // + if (yy.length() == 1) + retValue.append("0"); + retValue.append(yy); + // + return (retValue.toString()); + } // getCreditCardExp + + /** + * MICR + * @param MICR MICR + */ + public void setMicr (String MICR) + { + super.setMicr (MPaymentValidate.checkNumeric(MICR)); + } // setBankMICR + + /** + * Routing No + * @param RoutingNo Routing No + */ + public void setRoutingNo(String RoutingNo) + { + super.setRoutingNo (MPaymentValidate.checkNumeric(RoutingNo)); + } // setBankRoutingNo + + + /** + * Bank Account No + * @param AccountNo AccountNo + */ + public void setAccountNo (String AccountNo) + { + super.setAccountNo (MPaymentValidate.checkNumeric(AccountNo)); + } // setBankAccountNo + + + /** + * Check No + * @param CheckNo Check No + */ + public void setCheckNo(String CheckNo) + { + super.setCheckNo(MPaymentValidate.checkNumeric(CheckNo)); + } // setBankCheckNo + + + /** + * Set DocumentNo to Payment info. + * If there is a R_PnRef that is set automatically + */ + private void setDocumentNo() + { + // Cash Transfer + if ("X".equals(getTenderType())) + return; + // Current Document No + String documentNo = getDocumentNo(); + // Existing reversal + if (documentNo != null + && documentNo.indexOf(REVERSE_INDICATOR) >= 0) + return; + + // If external number exists - enforce it + if (getR_PnRef() != null && getR_PnRef().length() > 0) + { + if (!getR_PnRef().equals(documentNo)) + setDocumentNo(getR_PnRef()); + return; + } + + documentNo = ""; + // Credit Card + if (TENDERTYPE_CreditCard.equals(getTenderType())) + { + documentNo = getCreditCardType() + + " " + Obscure.obscure(getCreditCardNumber()) + + " " + getCreditCardExpMM() + + "/" + getCreditCardExpYY(); + } + // Own Check No + else if (TENDERTYPE_Check.equals(getTenderType()) + && !isReceipt() + && getCheckNo() != null && getCheckNo().length() > 0) + { + documentNo = getCheckNo(); + } + // Customer Check: Routing: Account #Check + else if (TENDERTYPE_Check.equals(getTenderType()) + && isReceipt()) + { + if (getRoutingNo() != null) + documentNo = getRoutingNo() + ": "; + if (getAccountNo() != null) + documentNo += getAccountNo(); + if (getCheckNo() != null) + { + if (documentNo.length() > 0) + documentNo += " "; + documentNo += "#" + getCheckNo(); + } + } + + // Set Document No + documentNo = documentNo.trim(); + if (documentNo.length() > 0) + setDocumentNo(documentNo); + } // setDocumentNo + + /** + * Set Refernce No (and Document No) + * @param R_PnRef reference + */ + public void setR_PnRef (String R_PnRef) + { + super.setR_PnRef (R_PnRef); + if (R_PnRef != null) + setDocumentNo (R_PnRef); + } // setR_PnRef + + // --------------- + + /** + * Set Payment Amount + * @param PayAmt Pay Amt + */ + public void setPayAmt (BigDecimal PayAmt) + { + super.setPayAmt(PayAmt == null ? Env.ZERO : PayAmt); + } // setPayAmt + + /** + * Set Payment Amount + * + * @param C_Currency_ID currency + * @param payAmt amount + */ + public void setAmount (int C_Currency_ID, BigDecimal payAmt) + { + if (C_Currency_ID == 0) + C_Currency_ID = MClient.get(getCtx()).getC_Currency_ID(); + setC_Currency_ID(C_Currency_ID); + setPayAmt(payAmt); + } // setAmount + + /** + * Discount Amt + * @param DiscountAmt Discount + */ + public void setDiscountAmt (BigDecimal DiscountAmt) + { + super.setDiscountAmt (DiscountAmt == null ? Env.ZERO : DiscountAmt); + } // setDiscountAmt + + /** + * WriteOff Amt + * @param WriteOffAmt WriteOff + */ + public void setWriteOffAmt (BigDecimal WriteOffAmt) + { + super.setWriteOffAmt (WriteOffAmt == null ? Env.ZERO : WriteOffAmt); + } // setWriteOffAmt + + /** + * OverUnder Amt + * @param OverUnderAmt OverUnder + */ + public void setOverUnderAmt (BigDecimal OverUnderAmt) + { + super.setOverUnderAmt (OverUnderAmt == null ? Env.ZERO : OverUnderAmt); + setIsOverUnderPayment(getOverUnderAmt().compareTo(Env.ZERO) != 0); + } // setOverUnderAmt + + /** + * Tax Amt + * @param TaxAmt Tax + */ + public void setTaxAmt (BigDecimal TaxAmt) + { + super.setTaxAmt (TaxAmt == null ? Env.ZERO : TaxAmt); + } // setTaxAmt + + /** + * Set Info from BP Bank Account + * @param ba BP bank account + */ + public void setBP_BankAccount (MBPBankAccount ba) + { + log.fine("" + ba); + if (ba == null) + return; + setC_BPartner_ID(ba.getC_BPartner_ID()); + setAccountAddress(ba.getA_Name(), ba.getA_Street(), ba.getA_City(), + ba.getA_State(), ba.getA_Zip(), ba.getA_Country()); + setA_EMail(ba.getA_EMail()); + setA_Ident_DL(ba.getA_Ident_DL()); + setA_Ident_SSN(ba.getA_Ident_SSN()); + // CC + if (ba.getCreditCardType() != null) + setCreditCardType(ba.getCreditCardType()); + if (ba.getCreditCardNumber() != null) + setCreditCardNumber(ba.getCreditCardNumber()); + if (ba.getCreditCardExpMM() != 0) + setCreditCardExpMM(ba.getCreditCardExpMM()); + if (ba.getCreditCardExpYY() != 0) + setCreditCardExpYY(ba.getCreditCardExpYY()); + if (ba.getCreditCardVV() != null) + setCreditCardVV(ba.getCreditCardVV()); + // Bank + if (ba.getAccountNo() != null) + setAccountNo(ba.getAccountNo()); + if (ba.getRoutingNo() != null) + setRoutingNo(ba.getRoutingNo()); + } // setBP_BankAccount + + /** + * Save Info from BP Bank Account + * @param ba BP bank account + * @return true if saved + */ + public boolean saveToBP_BankAccount (MBPBankAccount ba) + { + if (ba == null) + return false; + ba.setA_Name(getA_Name()); + ba.setA_Street(getA_Street()); + ba.setA_City(getA_City()); + ba.setA_State(getA_State()); + ba.setA_Zip(getA_Zip()); + ba.setA_Country(getA_Country()); + ba.setA_EMail(getA_EMail()); + ba.setA_Ident_DL(getA_Ident_DL()); + ba.setA_Ident_SSN(getA_Ident_SSN()); + // CC + ba.setCreditCardType(getCreditCardType()); + ba.setCreditCardNumber(getCreditCardNumber()); + ba.setCreditCardExpMM(getCreditCardExpMM()); + ba.setCreditCardExpYY(getCreditCardExpYY()); + ba.setCreditCardVV(getCreditCardVV()); + // Bank + if (getAccountNo() != null) + ba.setAccountNo(getAccountNo()); + if (getRoutingNo() != null) + ba.setRoutingNo(getRoutingNo()); + // Trx + ba.setR_AvsAddr(getR_AvsAddr()); + ba.setR_AvsZip(getR_AvsZip()); + // + boolean ok = ba.save(get_TrxName()); + log.fine("saveToBP_BankAccount - " + ba); + return ok; + } // setBP_BankAccount + + /** + * Set Doc Type bases on IsReceipt + */ + private void setC_DocType_ID () + { + setC_DocType_ID(isReceipt()); + } // setC_DocType_ID + + /** + * Set Doc Type + * @param isReceipt is receipt + */ + public void setC_DocType_ID (boolean isReceipt) + { + setIsReceipt(isReceipt); + String sql = "SELECT C_DocType_ID FROM C_DocType WHERE AD_Client_ID=? AND DocBaseType=? ORDER BY IsDefault DESC"; + try + { PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName()); pstmt.setInt(1, getAD_Client_ID()); if (isReceipt) @@ -1229,228 +1229,228 @@ public final class MPayment extends X_C_Payment ResultSet rs = pstmt.executeQuery(); if (rs.next()) setC_DocType_ID(rs.getInt(1)); - else - log.warning ("setDocType - NOT found - isReceipt=" + isReceipt); - rs.close(); - pstmt.close(); - } - catch (SQLException e) - { - log.log(Level.SEVERE, sql, e); - } - } // setC_DocType_ID - - - /** - * Set Document Type - * @param C_DocType_ID doc type - */ - public void setC_DocType_ID (int C_DocType_ID) - { - // if (getDocumentNo() != null && getC_DocType_ID() != C_DocType_ID) - // setDocumentNo(null); - super.setC_DocType_ID(C_DocType_ID); - } // setC_DocType_ID - - /** - * Verify Document Type with Invoice - * @return true if ok - */ - private boolean verifyDocType() - { - if (getC_DocType_ID() == 0) - return false; - // - Boolean invoiceSO = null; - // Check Invoice First - if (getC_Invoice_ID() > 0) - { - String sql = "SELECT idt.IsSOTrx " - + "FROM C_Invoice i" - + " INNER JOIN C_DocType idt ON (i.C_DocType_ID=idt.C_DocType_ID) " - + "WHERE i.C_Invoice_ID=?"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_Invoice_ID()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - invoiceSO = new Boolean ("Y".equals(rs.getString(1))); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - } // Invoice - - // DocumentType - Boolean paymentSO = null; - PreparedStatement pstmt = null; - String sql = "SELECT IsSOTrx " - + "FROM C_DocType " - + "WHERE C_DocType_ID=?"; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_DocType_ID()); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - paymentSO = new Boolean ("Y".equals(rs.getString(1))); - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, sql, e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - // No Payment info - if (paymentSO == null) - return false; - setIsReceipt(paymentSO.booleanValue()); - - // We have an Invoice .. and it does not match - if (invoiceSO != null - && invoiceSO.booleanValue() != paymentSO.booleanValue()) - return false; - // OK - return true; - } // verifyDocType - - - /** - * Get ISO Code of Currency - * @return Currency ISO - */ - public String getCurrencyISO() - { - return MCurrency.getISO_Code (getCtx(), getC_Currency_ID()); - } // getCurrencyISO - - /** - * Get Document Status - * @return Document Status Clear Text - */ - public String getDocStatusName() - { - return MRefList.getListName(getCtx(), 131, getDocStatus()); - } // getDocStatusName - - /** - * Get Name of Credit Card - * @return Name - */ - public String getCreditCardName() - { - return getCreditCardName(getCreditCardType()); - } // getCreditCardName - - /** - * Get Name of Credit Card - * @param CreditCardType credit card type - * @return Name - */ - public String getCreditCardName(String CreditCardType) - { - if (CreditCardType == null) - return "--"; - else if (CREDITCARDTYPE_MasterCard.equals(CreditCardType)) - return "MasterCard"; - else if (CREDITCARDTYPE_Visa.equals(CreditCardType)) - return "Visa"; - else if (CREDITCARDTYPE_Amex.equals(CreditCardType)) - return "Amex"; - else if (CREDITCARDTYPE_ATM.equals(CreditCardType)) - return "ATM"; - else if (CREDITCARDTYPE_Diners.equals(CreditCardType)) - return "Diners"; - else if (CREDITCARDTYPE_Discover.equals(CreditCardType)) - return "Discover"; - else if (CREDITCARDTYPE_PurchaseCard.equals(CreditCardType)) - return "PurchaseCard"; - return "?" + CreditCardType + "?"; - } // getCreditCardName - - /** - * Add to Description - * @param description text - */ - public void addDescription (String description) - { - String desc = getDescription(); - if (desc == null) - setDescription(description); - else - setDescription(desc + " | " + description); - } // addDescription - - - /** - * Get Pay Amt - * @param absolute if true the absolute amount (i.e. negative if payment) - * @return amount - */ - public BigDecimal getPayAmt (boolean absolute) - { - if (isReceipt()) - return super.getPayAmt(); - return super.getPayAmt().negate(); - } // getPayAmt - - /** - * Get Pay Amt in cents - * @return amount in cents - */ - public int getPayAmtInCents () - { - BigDecimal bd = super.getPayAmt().multiply(Env.ONEHUNDRED); - return bd.intValue(); - } // getPayAmtInCents - - /************************************************************************** - * Process document - * @param processAction document action - * @return true if performed - */ - public boolean processIt (String processAction) - { - m_processMsg = null; - DocumentEngine engine = new DocumentEngine (this, getDocStatus()); - return engine.processIt (processAction, getDocAction()); - } // process - - /** Process Message */ - private String m_processMsg = null; - /** Just Prepared Flag */ - private boolean m_justPrepared = false; - - /** - * Unlock Document. - * @return true if success + else + log.warning ("setDocType - NOT found - isReceipt=" + isReceipt); + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + } // setC_DocType_ID + + + /** + * Set Document Type + * @param C_DocType_ID doc type + */ + public void setC_DocType_ID (int C_DocType_ID) + { + // if (getDocumentNo() != null && getC_DocType_ID() != C_DocType_ID) + // setDocumentNo(null); + super.setC_DocType_ID(C_DocType_ID); + } // setC_DocType_ID + + /** + * Verify Document Type with Invoice + * @return true if ok + */ + private boolean verifyDocType() + { + if (getC_DocType_ID() == 0) + return false; + // + Boolean invoiceSO = null; + // Check Invoice First + if (getC_Invoice_ID() > 0) + { + String sql = "SELECT idt.IsSOTrx " + + "FROM C_Invoice i" + + " INNER JOIN C_DocType idt ON (i.C_DocType_ID=idt.C_DocType_ID) " + + "WHERE i.C_Invoice_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_Invoice_ID()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + invoiceSO = new Boolean ("Y".equals(rs.getString(1))); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + } // Invoice + + // DocumentType + Boolean paymentSO = null; + PreparedStatement pstmt = null; + String sql = "SELECT IsSOTrx " + + "FROM C_DocType " + + "WHERE C_DocType_ID=?"; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_DocType_ID()); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) + paymentSO = new Boolean ("Y".equals(rs.getString(1))); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + // No Payment info + if (paymentSO == null) + return false; + setIsReceipt(paymentSO.booleanValue()); + + // We have an Invoice .. and it does not match + if (invoiceSO != null + && invoiceSO.booleanValue() != paymentSO.booleanValue()) + return false; + // OK + return true; + } // verifyDocType + + + /** + * Get ISO Code of Currency + * @return Currency ISO + */ + public String getCurrencyISO() + { + return MCurrency.getISO_Code (getCtx(), getC_Currency_ID()); + } // getCurrencyISO + + /** + * Get Document Status + * @return Document Status Clear Text + */ + public String getDocStatusName() + { + return MRefList.getListName(getCtx(), 131, getDocStatus()); + } // getDocStatusName + + /** + * Get Name of Credit Card + * @return Name + */ + public String getCreditCardName() + { + return getCreditCardName(getCreditCardType()); + } // getCreditCardName + + /** + * Get Name of Credit Card + * @param CreditCardType credit card type + * @return Name + */ + public String getCreditCardName(String CreditCardType) + { + if (CreditCardType == null) + return "--"; + else if (CREDITCARDTYPE_MasterCard.equals(CreditCardType)) + return "MasterCard"; + else if (CREDITCARDTYPE_Visa.equals(CreditCardType)) + return "Visa"; + else if (CREDITCARDTYPE_Amex.equals(CreditCardType)) + return "Amex"; + else if (CREDITCARDTYPE_ATM.equals(CreditCardType)) + return "ATM"; + else if (CREDITCARDTYPE_Diners.equals(CreditCardType)) + return "Diners"; + else if (CREDITCARDTYPE_Discover.equals(CreditCardType)) + return "Discover"; + else if (CREDITCARDTYPE_PurchaseCard.equals(CreditCardType)) + return "PurchaseCard"; + return "?" + CreditCardType + "?"; + } // getCreditCardName + + /** + * Add to Description + * @param description text + */ + public void addDescription (String description) + { + String desc = getDescription(); + if (desc == null) + setDescription(description); + else + setDescription(desc + " | " + description); + } // addDescription + + + /** + * Get Pay Amt + * @param absolute if true the absolute amount (i.e. negative if payment) + * @return amount + */ + public BigDecimal getPayAmt (boolean absolute) + { + if (isReceipt()) + return super.getPayAmt(); + return super.getPayAmt().negate(); + } // getPayAmt + + /** + * Get Pay Amt in cents + * @return amount in cents + */ + public int getPayAmtInCents () + { + BigDecimal bd = super.getPayAmt().multiply(Env.ONEHUNDRED); + return bd.intValue(); + } // getPayAmtInCents + + /************************************************************************** + * Process document + * @param processAction document action + * @return true if performed + */ + public boolean processIt (String processAction) + { + m_processMsg = null; + DocumentEngine engine = new DocumentEngine (this, getDocStatus()); + return engine.processIt (processAction, getDocAction()); + } // process + + /** Process Message */ + private String m_processMsg = null; + /** Just Prepared Flag */ + private boolean m_justPrepared = false; + + /** + * Unlock Document. + * @return true if success */ public boolean unlockIt() { @@ -1458,10 +1458,10 @@ public final class MPayment extends X_C_Payment setProcessing(false); return true; } // unlockIt - - /** - * Invalidate Document - * @return true if success + + /** + * Invalidate Document + * @return true if success */ public boolean invalidateIt() { @@ -1469,18 +1469,18 @@ public final class MPayment extends X_C_Payment setDocAction(DOCACTION_Prepare); return true; } // invalidateIt - - - /************************************************************************** - * Prepare Document - * @return new status (In Progress or Invalid) - */ - public String prepareIt() - { - log.info(toString()); - m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); - if (m_processMsg != null) - return DocAction.STATUS_Invalid; + + + /************************************************************************** + * Prepare Document + * @return new status (In Progress or Invalid) + */ + public String prepareIt() + { + log.info(toString()); + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); + if (m_processMsg != null) + return DocAction.STATUS_Invalid; // Std Period open? if (!MPeriod.isOpen(getCtx(), getDateAcct(), @@ -1488,22 +1488,22 @@ public final class MPayment extends X_C_Payment { m_processMsg = "@PeriodClosed@"; return DocAction.STATUS_Invalid; - } - - // Unsuccessful Online Payment - if (isOnline() && !isApproved()) - { - if (getR_Result() != null) - m_processMsg = "@OnlinePaymentFailed@"; - else - m_processMsg = "@PaymentNotProcessed@"; - return DocAction.STATUS_Invalid; - } - - // Waiting Payment - Need to create Invoice & Shipment - if (getC_Order_ID() != 0 && getC_Invoice_ID() == 0) - { // see WebOrder.process - MOrder order = new MOrder (getCtx(), getC_Order_ID(), get_TrxName()); + } + + // Unsuccessful Online Payment + if (isOnline() && !isApproved()) + { + if (getR_Result() != null) + m_processMsg = "@OnlinePaymentFailed@"; + else + m_processMsg = "@PaymentNotProcessed@"; + return DocAction.STATUS_Invalid; + } + + // Waiting Payment - Need to create Invoice & Shipment + if (getC_Order_ID() != 0 && getC_Invoice_ID() == 0) + { // see WebOrder.process + MOrder order = new MOrder (getCtx(), getC_Order_ID(), get_TrxName()); if (DOCSTATUS_WaitingPayment.equals(order.getDocStatus())) { order.setC_Payment_ID(getC_Payment_ID()); @@ -1514,27 +1514,27 @@ public final class MPayment extends X_C_Payment m_processMsg = order.getProcessMsg(); order.save(get_TrxName()); // Set Invoice - MInvoice[] invoices = order.getInvoices(); - int length = invoices.length; - if (length > 0) // get last invoice - setC_Invoice_ID (invoices[length-1].getC_Invoice_ID()); - // - if (getC_Invoice_ID() == 0) - { - m_processMsg = "@NotFound@ @C_Invoice_ID@"; - return DocAction.STATUS_Invalid; - } - } // WaitingPayment - } - - // Consistency of Invoice / Document Type and IsReceipt - if (!verifyDocType()) - { - m_processMsg = "@PaymentDocTypeInvoiceInconsistent@"; - return DocAction.STATUS_Invalid; - } - - // Do not pay when Credit Stop/Hold + MInvoice[] invoices = order.getInvoices(); + int length = invoices.length; + if (length > 0) // get last invoice + setC_Invoice_ID (invoices[length-1].getC_Invoice_ID()); + // + if (getC_Invoice_ID() == 0) + { + m_processMsg = "@NotFound@ @C_Invoice_ID@"; + return DocAction.STATUS_Invalid; + } + } // WaitingPayment + } + + // Consistency of Invoice / Document Type and IsReceipt + if (!verifyDocType()) + { + m_processMsg = "@PaymentDocTypeInvoiceInconsistent@"; + return DocAction.STATUS_Invalid; + } + + // Do not pay when Credit Stop/Hold if (!isReceipt()) { MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); @@ -1549,128 +1549,128 @@ public final class MPayment extends X_C_Payment { m_processMsg = "@BPartnerCreditHold@ - @TotalOpenBalance@=" + bp.getTotalOpenBalance() - + ", @SO_CreditLimit@=" + bp.getSO_CreditLimit(); - return DocAction.STATUS_Invalid; - } - } - + + ", @SO_CreditLimit@=" + bp.getSO_CreditLimit(); + return DocAction.STATUS_Invalid; + } + } + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_PREPARE); if (m_processMsg != null) return DocAction.STATUS_Invalid; - m_justPrepared = true; - if (!DOCACTION_Complete.equals(getDocAction())) - setDocAction(DOCACTION_Complete); - return DocAction.STATUS_InProgress; - } // prepareIt - - /** - * Approve Document - * @return true if success - */ - public boolean approveIt() - { - log.info(toString()); - setIsApproved(true); - return true; - } // approveIt - - /** - * Reject Approval - * @return true if success - */ - public boolean rejectIt() - { - log.info(toString()); - setIsApproved(false); - return true; - } // rejectIt - - - /************************************************************************** - * Complete Document - * @return new status (Complete, In Progress, Invalid, Waiting ..) - */ - public String completeIt() - { - // Re-Check - if (!m_justPrepared) - { - String status = prepareIt(); - if (!DocAction.STATUS_InProgress.equals(status)) - return status; + m_justPrepared = true; + if (!DOCACTION_Complete.equals(getDocAction())) + setDocAction(DOCACTION_Complete); + return DocAction.STATUS_InProgress; + } // prepareIt + + /** + * Approve Document + * @return true if success + */ + public boolean approveIt() + { + log.info(toString()); + setIsApproved(true); + return true; + } // approveIt + + /** + * Reject Approval + * @return true if success + */ + public boolean rejectIt() + { + log.info(toString()); + setIsApproved(false); + return true; + } // rejectIt + + + /************************************************************************** + * Complete Document + * @return new status (Complete, In Progress, Invalid, Waiting ..) + */ + public String completeIt() + { + // Re-Check + if (!m_justPrepared) + { + String status = prepareIt(); + if (!DocAction.STATUS_InProgress.equals(status)) + return status; } m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE); if (m_processMsg != null) return DocAction.STATUS_Invalid; - // Implicit Approval - if (!isApproved()) - approveIt(); - log.info(toString()); - - // Charge Handling - if (getC_Charge_ID() != 0) - { - setIsAllocated(true); - } - else - { - allocateIt(); // Create Allocation Records - testAllocation(); - } - - // Project update - if (getC_Project_ID() != 0) - { - // MProject project = new MProject(getCtx(), getC_Project_ID()); - } - // Update BP for Prepayments - if (getC_BPartner_ID() != 0 && getC_Invoice_ID() == 0) - { - MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); - bp.setTotalOpenBalance(); - bp.save(); - } - - // Counter Doc - MPayment counter = createCounterDoc(); - if (counter != null) - m_processMsg += " @CounterDoc@: @C_Payment_ID@=" + counter.getDocumentNo(); - - // User Validation - String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); - if (valid != null) - { - m_processMsg = valid; - return DocAction.STATUS_Invalid; - } - // - setProcessed(true); - setDocAction(DOCACTION_Close); - return DocAction.STATUS_Completed; - } // completeIt - - /** - * Create Counter Document - * @return payment - */ - private MPayment createCounterDoc() - { - // Is this a counter doc ? - if (getRef_Payment_ID() != 0) - return null; - - // Org Must be linked to BPartner - MOrg org = MOrg.get(getCtx(), getAD_Org_ID()); - int counterC_BPartner_ID = org.getLinkedC_BPartner_ID(get_TrxName()); - if (counterC_BPartner_ID == 0) - return null; - // Business Partner needs to be linked to Org - MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); - int counterAD_Org_ID = bp.getAD_OrgBP_ID_Int(); - if (counterAD_Org_ID == 0) + // Implicit Approval + if (!isApproved()) + approveIt(); + log.info(toString()); + + // Charge Handling + if (getC_Charge_ID() != 0) + { + setIsAllocated(true); + } + else + { + allocateIt(); // Create Allocation Records + testAllocation(); + } + + // Project update + if (getC_Project_ID() != 0) + { + // MProject project = new MProject(getCtx(), getC_Project_ID()); + } + // Update BP for Prepayments + if (getC_BPartner_ID() != 0 && getC_Invoice_ID() == 0) + { + MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); + bp.setTotalOpenBalance(); + bp.save(); + } + + // Counter Doc + MPayment counter = createCounterDoc(); + if (counter != null) + m_processMsg += " @CounterDoc@: @C_Payment_ID@=" + counter.getDocumentNo(); + + // User Validation + String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); + if (valid != null) + { + m_processMsg = valid; + return DocAction.STATUS_Invalid; + } + // + setProcessed(true); + setDocAction(DOCACTION_Close); + return DocAction.STATUS_Completed; + } // completeIt + + /** + * Create Counter Document + * @return payment + */ + private MPayment createCounterDoc() + { + // Is this a counter doc ? + if (getRef_Payment_ID() != 0) + return null; + + // Org Must be linked to BPartner + MOrg org = MOrg.get(getCtx(), getAD_Org_ID()); + int counterC_BPartner_ID = org.getLinkedC_BPartner_ID(get_TrxName()); + if (counterC_BPartner_ID == 0) + return null; + // Business Partner needs to be linked to Org + MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); + int counterAD_Org_ID = bp.getAD_OrgBP_ID_Int(); + if (counterAD_Org_ID == 0) return null; MBPartner counterBP = new MBPartner (getCtx(), counterC_BPartner_ID, get_TrxName()); @@ -1678,385 +1678,385 @@ public final class MPayment extends X_C_Payment log.info("Counter BP=" + counterBP.getName()); // Document Type - int C_DocTypeTarget_ID = 0; - MDocTypeCounter counterDT = MDocTypeCounter.getCounterDocType(getCtx(), getC_DocType_ID()); - if (counterDT != null) - { - log.fine(counterDT.toString()); - if (!counterDT.isCreateCounter() || !counterDT.isValid()) - return null; - C_DocTypeTarget_ID = counterDT.getCounter_C_DocType_ID(); - } - else // indirect - { - C_DocTypeTarget_ID = MDocTypeCounter.getCounterDocType_ID(getCtx(), getC_DocType_ID()); - log.fine("Indirect C_DocTypeTarget_ID=" + C_DocTypeTarget_ID); - if (C_DocTypeTarget_ID <= 0) - return null; - } - - // Deep Copy - MPayment counter = new MPayment (getCtx(), 0, get_TrxName()); - counter.setAD_Org_ID(counterAD_Org_ID); - counter.setC_BPartner_ID(counterBP.getC_BPartner_ID()); - counter.setIsReceipt(!isReceipt()); - counter.setC_DocType_ID(C_DocTypeTarget_ID); - counter.setTrxType(getTrxType()); - counter.setTenderType(getTenderType()); - // - counter.setPayAmt(getPayAmt()); - counter.setDiscountAmt(getDiscountAmt()); - counter.setTaxAmt(getTaxAmt()); - counter.setWriteOffAmt(getWriteOffAmt()); - counter.setIsOverUnderPayment (isOverUnderPayment()); - counter.setOverUnderAmt(getOverUnderAmt()); - counter.setC_Currency_ID(getC_Currency_ID()); - counter.setC_ConversionType_ID(getC_ConversionType_ID()); - // - counter.setDateTrx (getDateTrx()); - counter.setDateAcct (getDateAcct()); - counter.setRef_Payment_ID(getC_Payment_ID()); - // - String sql = "SELECT C_BankAccount_ID FROM C_BankAccount " - + "WHERE C_Currency_ID=? AND AD_Org_ID IN (0,?) AND IsActive='Y' " - + "ORDER BY IsDefault DESC"; - int C_BankAccount_ID = DB.getSQLValue(get_TrxName(), sql, getC_Currency_ID(), counterAD_Org_ID); - counter.setC_BankAccount_ID(C_BankAccount_ID); - - // Refernces - counter.setC_Activity_ID(getC_Activity_ID()); - counter.setC_Campaign_ID(getC_Campaign_ID()); - counter.setC_Project_ID(getC_Project_ID()); - counter.setUser1_ID(getUser1_ID()); - counter.setUser2_ID(getUser2_ID()); - counter.save(get_TrxName()); - log.fine(counter.toString()); - setRef_Payment_ID(counter.getC_Payment_ID()); - - // Document Action - if (counterDT != null) - { - if (counterDT.getDocAction() != null) - { - counter.setDocAction(counterDT.getDocAction()); - counter.processIt(counterDT.getDocAction()); - counter.save(get_TrxName()); - } - } - return counter; - } // createCounterDoc - - /** - * Allocate It. - * Only call when there is NO allocation as it will create duplicates. - * If an invoice exists, it allocates that - * otherwise it allocates Payment Selection. - * @return true if allocated - */ - public boolean allocateIt() - { - // Create invoice Allocation - See also MCash.completeIt - if (getC_Invoice_ID() != 0) - return allocateInvoice(); - // Invoices of a AP Payment Selection - if (allocatePaySelection()) - return true; - - if (getC_Order_ID() != 0) - return false; - - // Allocate to multiple Payments based on entry - MPaymentAllocate[] pAllocs = MPaymentAllocate.get(this); - if (pAllocs.length == 0) - return false; - - MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo(), - get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - if (!alloc.save()) - { - log.severe("P.Allocations not created"); - return false; - } - // Lines - for (int i = 0; i < pAllocs.length; i++) - { - MPaymentAllocate pa = pAllocs[i]; - MAllocationLine aLine = null; - if (isReceipt()) - aLine = new MAllocationLine (alloc, pa.getAmount(), - pa.getDiscountAmt(), pa.getWriteOffAmt(), pa.getOverUnderAmt()); - else - aLine = new MAllocationLine (alloc, pa.getAmount().negate(), - pa.getDiscountAmt().negate(), pa.getWriteOffAmt().negate(), pa.getOverUnderAmt().negate()); - aLine.setDocInfo(pa.getC_BPartner_ID(), 0, pa.getC_Invoice_ID()); - aLine.setPaymentInfo(getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("P.Allocations - line not saved"); - else - { - pa.setC_AllocationLine_ID(aLine.getC_AllocationLine_ID()); - pa.save(); - } - } - // Should start WF - alloc.processIt(DocAction.ACTION_Complete); - m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); - return alloc.save(get_TrxName()); - } // allocateIt - - /** - * Allocate single AP/AR Invoice - * @return true if allocated - */ - private boolean allocateInvoice() - { - // calculate actual allocation - BigDecimal allocationAmt = getPayAmt(); // underpayment - if (getOverUnderAmt().signum() < 0 && getPayAmt().signum() > 0) - allocationAmt = allocationAmt.add(getOverUnderAmt()); // overpayment (negative) - - MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [1]", get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - if (!alloc.save()) - { - log.log(Level.SEVERE, "Could not create Allocation Hdr"); - return false; - } - MAllocationLine aLine = null; - if (isReceipt()) - aLine = new MAllocationLine (alloc, allocationAmt, - getDiscountAmt(), getWriteOffAmt(), getOverUnderAmt()); - else - aLine = new MAllocationLine (alloc, allocationAmt.negate(), - getDiscountAmt().negate(), getWriteOffAmt().negate(), getOverUnderAmt().negate()); - aLine.setDocInfo(getC_BPartner_ID(), 0, getC_Invoice_ID()); - aLine.setC_Payment_ID(getC_Payment_ID()); - if (!aLine.save(get_TrxName())) - { - log.log(Level.SEVERE, "Could not create Allocation Line"); - return false; - } - // Should start WF - alloc.processIt(DocAction.ACTION_Complete); - alloc.save(get_TrxName()); - m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); - - // Get Project from Invoice - int C_Project_ID = DB.getSQLValue(get_TrxName(), - "SELECT MAX(C_Project_ID) FROM C_Invoice WHERE C_Invoice_ID=?", getC_Invoice_ID()); - if (C_Project_ID > 0 && getC_Project_ID() == 0) - setC_Project_ID(C_Project_ID); - else if (C_Project_ID > 0 && getC_Project_ID() > 0 && C_Project_ID != getC_Project_ID()) - log.warning("Invoice C_Project_ID=" + C_Project_ID - + " <> Payment C_Project_ID=" + getC_Project_ID()); - return true; - } // allocateInvoice - - /** - * Allocate Payment Selection - * @return true if allocated - */ - private boolean allocatePaySelection() - { - MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [n]", get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - - String sql = "SELECT psc.C_BPartner_ID, psl.C_Invoice_ID, psl.IsSOTrx, " // 1..3 - + " psl.PayAmt, psl.DiscountAmt, psl.DifferenceAmt, psl.OpenAmt " - + "FROM C_PaySelectionLine psl" - + " INNER JOIN C_PaySelectionCheck psc ON (psl.C_PaySelectionCheck_ID=psc.C_PaySelectionCheck_ID) " - + "WHERE psc.C_Payment_ID=?"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql, get_TrxName()); - pstmt.setInt(1, getC_Payment_ID()); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) - { - int C_BPartner_ID = rs.getInt(1); - int C_Invoice_ID = rs.getInt(2); - if (C_BPartner_ID == 0 && C_Invoice_ID == 0) - continue; - boolean isSOTrx = "Y".equals(rs.getString(3)); - BigDecimal PayAmt = rs.getBigDecimal(4); - BigDecimal DiscountAmt = rs.getBigDecimal(5); - BigDecimal WriteOffAmt = rs.getBigDecimal(6); - BigDecimal OpenAmt = rs.getBigDecimal(7); - BigDecimal OverUnderAmt = OpenAmt.subtract(PayAmt) - .subtract(DiscountAmt).subtract(WriteOffAmt); - // - if (alloc.get_ID() == 0 && !alloc.save(get_TrxName())) - { - log.log(Level.SEVERE, "Could not create Allocation Hdr"); - rs.close(); - pstmt.close(); - return false; - } - MAllocationLine aLine = null; - if (isSOTrx) - aLine = new MAllocationLine (alloc, PayAmt, - DiscountAmt, WriteOffAmt, OverUnderAmt); - else - aLine = new MAllocationLine (alloc, PayAmt.negate(), - DiscountAmt.negate(), WriteOffAmt.negate(), OverUnderAmt.negate()); - aLine.setDocInfo(C_BPartner_ID, 0, C_Invoice_ID); - aLine.setC_Payment_ID(getC_Payment_ID()); - if (!aLine.save(get_TrxName())) - log.log(Level.SEVERE, "Could not create Allocation Line"); - } - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.log(Level.SEVERE, "allocatePaySelection", e); - } - try - { - if (pstmt != null) - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - pstmt = null; - } - - // Should start WF - boolean ok = true; - if (alloc.get_ID() == 0) - { - log.fine("No Allocation created - C_Payment_ID=" - + getC_Payment_ID()); - ok = false; - } - else - { - alloc.processIt(DocAction.ACTION_Complete); - ok = alloc.save(get_TrxName()); - m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); - } - return ok; - } // allocatePaySelection - - /** - * De-allocate Payment. - * Unkink Invoices and Orders and delete Allocations - */ - private void deAllocate() - { - if (getC_Order_ID() != 0) - setC_Order_ID(0); - // if (getC_Invoice_ID() == 0) - // return; - // De-Allocate all - MAllocationHdr[] allocations = MAllocationHdr.getOfPayment(getCtx(), - getC_Payment_ID(), get_TrxName()); - log.fine("#" + allocations.length); - for (int i = 0; i < allocations.length; i++) - { - allocations[i].set_TrxName(get_TrxName()); - allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); - allocations[i].processIt(DocAction.ACTION_Reverse_Correct); - allocations[i].save(); - } - - // Unlink (in case allocation did not get it) - if (getC_Invoice_ID() != 0) - { - // Invoice - String sql = "UPDATE C_Invoice " - + "SET C_Payment_ID = NULL, IsPaid='N' " - + "WHERE C_Invoice_ID=" + getC_Invoice_ID() - + " AND C_Payment_ID=" + getC_Payment_ID(); - int no = DB.executeUpdate(sql, get_TrxName()); - if (no != 0) - log.fine("Unlink Invoice #" + no); - // Order - sql = "UPDATE C_Order o " - + "SET C_Payment_ID = NULL " - + "WHERE EXISTS (SELECT * FROM C_Invoice i " - + "WHERE o.C_Order_ID=i.C_Order_ID AND i.C_Invoice_ID=" + getC_Invoice_ID() + ")" - + " AND C_Payment_ID=" + getC_Payment_ID(); - no = DB.executeUpdate(sql, get_TrxName()); - if (no != 0) - log.fine("Unlink Order #" + no); - } - // - setC_Invoice_ID(0); - setIsAllocated(false); - } // deallocate - - /** - * Void Document. - * @return true if success - */ - public boolean voidIt() - { - log.info(toString()); + int C_DocTypeTarget_ID = 0; + MDocTypeCounter counterDT = MDocTypeCounter.getCounterDocType(getCtx(), getC_DocType_ID()); + if (counterDT != null) + { + log.fine(counterDT.toString()); + if (!counterDT.isCreateCounter() || !counterDT.isValid()) + return null; + C_DocTypeTarget_ID = counterDT.getCounter_C_DocType_ID(); + } + else // indirect + { + C_DocTypeTarget_ID = MDocTypeCounter.getCounterDocType_ID(getCtx(), getC_DocType_ID()); + log.fine("Indirect C_DocTypeTarget_ID=" + C_DocTypeTarget_ID); + if (C_DocTypeTarget_ID <= 0) + return null; + } + + // Deep Copy + MPayment counter = new MPayment (getCtx(), 0, get_TrxName()); + counter.setAD_Org_ID(counterAD_Org_ID); + counter.setC_BPartner_ID(counterBP.getC_BPartner_ID()); + counter.setIsReceipt(!isReceipt()); + counter.setC_DocType_ID(C_DocTypeTarget_ID); + counter.setTrxType(getTrxType()); + counter.setTenderType(getTenderType()); + // + counter.setPayAmt(getPayAmt()); + counter.setDiscountAmt(getDiscountAmt()); + counter.setTaxAmt(getTaxAmt()); + counter.setWriteOffAmt(getWriteOffAmt()); + counter.setIsOverUnderPayment (isOverUnderPayment()); + counter.setOverUnderAmt(getOverUnderAmt()); + counter.setC_Currency_ID(getC_Currency_ID()); + counter.setC_ConversionType_ID(getC_ConversionType_ID()); + // + counter.setDateTrx (getDateTrx()); + counter.setDateAcct (getDateAcct()); + counter.setRef_Payment_ID(getC_Payment_ID()); + // + String sql = "SELECT C_BankAccount_ID FROM C_BankAccount " + + "WHERE C_Currency_ID=? AND AD_Org_ID IN (0,?) AND IsActive='Y' " + + "ORDER BY IsDefault DESC"; + int C_BankAccount_ID = DB.getSQLValue(get_TrxName(), sql, getC_Currency_ID(), counterAD_Org_ID); + counter.setC_BankAccount_ID(C_BankAccount_ID); + + // Refernces + counter.setC_Activity_ID(getC_Activity_ID()); + counter.setC_Campaign_ID(getC_Campaign_ID()); + counter.setC_Project_ID(getC_Project_ID()); + counter.setUser1_ID(getUser1_ID()); + counter.setUser2_ID(getUser2_ID()); + counter.save(get_TrxName()); + log.fine(counter.toString()); + setRef_Payment_ID(counter.getC_Payment_ID()); + + // Document Action + if (counterDT != null) + { + if (counterDT.getDocAction() != null) + { + counter.setDocAction(counterDT.getDocAction()); + counter.processIt(counterDT.getDocAction()); + counter.save(get_TrxName()); + } + } + return counter; + } // createCounterDoc + + /** + * Allocate It. + * Only call when there is NO allocation as it will create duplicates. + * If an invoice exists, it allocates that + * otherwise it allocates Payment Selection. + * @return true if allocated + */ + public boolean allocateIt() + { + // Create invoice Allocation - See also MCash.completeIt + if (getC_Invoice_ID() != 0) + return allocateInvoice(); + // Invoices of a AP Payment Selection + if (allocatePaySelection()) + return true; + + if (getC_Order_ID() != 0) + return false; + + // Allocate to multiple Payments based on entry + MPaymentAllocate[] pAllocs = MPaymentAllocate.get(this); + if (pAllocs.length == 0) + return false; + + MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo(), + get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + if (!alloc.save()) + { + log.severe("P.Allocations not created"); + return false; + } + // Lines + for (int i = 0; i < pAllocs.length; i++) + { + MPaymentAllocate pa = pAllocs[i]; + MAllocationLine aLine = null; + if (isReceipt()) + aLine = new MAllocationLine (alloc, pa.getAmount(), + pa.getDiscountAmt(), pa.getWriteOffAmt(), pa.getOverUnderAmt()); + else + aLine = new MAllocationLine (alloc, pa.getAmount().negate(), + pa.getDiscountAmt().negate(), pa.getWriteOffAmt().negate(), pa.getOverUnderAmt().negate()); + aLine.setDocInfo(pa.getC_BPartner_ID(), 0, pa.getC_Invoice_ID()); + aLine.setPaymentInfo(getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("P.Allocations - line not saved"); + else + { + pa.setC_AllocationLine_ID(aLine.getC_AllocationLine_ID()); + pa.save(); + } + } + // Should start WF + alloc.processIt(DocAction.ACTION_Complete); + m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); + return alloc.save(get_TrxName()); + } // allocateIt + + /** + * Allocate single AP/AR Invoice + * @return true if allocated + */ + private boolean allocateInvoice() + { + // calculate actual allocation + BigDecimal allocationAmt = getPayAmt(); // underpayment + if (getOverUnderAmt().signum() < 0 && getPayAmt().signum() > 0) + allocationAmt = allocationAmt.add(getOverUnderAmt()); // overpayment (negative) + + MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [1]", get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + if (!alloc.save()) + { + log.log(Level.SEVERE, "Could not create Allocation Hdr"); + return false; + } + MAllocationLine aLine = null; + if (isReceipt()) + aLine = new MAllocationLine (alloc, allocationAmt, + getDiscountAmt(), getWriteOffAmt(), getOverUnderAmt()); + else + aLine = new MAllocationLine (alloc, allocationAmt.negate(), + getDiscountAmt().negate(), getWriteOffAmt().negate(), getOverUnderAmt().negate()); + aLine.setDocInfo(getC_BPartner_ID(), 0, getC_Invoice_ID()); + aLine.setC_Payment_ID(getC_Payment_ID()); + if (!aLine.save(get_TrxName())) + { + log.log(Level.SEVERE, "Could not create Allocation Line"); + return false; + } + // Should start WF + alloc.processIt(DocAction.ACTION_Complete); + alloc.save(get_TrxName()); + m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); + + // Get Project from Invoice + int C_Project_ID = DB.getSQLValue(get_TrxName(), + "SELECT MAX(C_Project_ID) FROM C_Invoice WHERE C_Invoice_ID=?", getC_Invoice_ID()); + if (C_Project_ID > 0 && getC_Project_ID() == 0) + setC_Project_ID(C_Project_ID); + else if (C_Project_ID > 0 && getC_Project_ID() > 0 && C_Project_ID != getC_Project_ID()) + log.warning("Invoice C_Project_ID=" + C_Project_ID + + " <> Payment C_Project_ID=" + getC_Project_ID()); + return true; + } // allocateInvoice + + /** + * Allocate Payment Selection + * @return true if allocated + */ + private boolean allocatePaySelection() + { + MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + getDocumentNo() + " [n]", get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + + String sql = "SELECT psc.C_BPartner_ID, psl.C_Invoice_ID, psl.IsSOTrx, " // 1..3 + + " psl.PayAmt, psl.DiscountAmt, psl.DifferenceAmt, psl.OpenAmt " + + "FROM C_PaySelectionLine psl" + + " INNER JOIN C_PaySelectionCheck psc ON (psl.C_PaySelectionCheck_ID=psc.C_PaySelectionCheck_ID) " + + "WHERE psc.C_Payment_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, getC_Payment_ID()); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + int C_BPartner_ID = rs.getInt(1); + int C_Invoice_ID = rs.getInt(2); + if (C_BPartner_ID == 0 && C_Invoice_ID == 0) + continue; + boolean isSOTrx = "Y".equals(rs.getString(3)); + BigDecimal PayAmt = rs.getBigDecimal(4); + BigDecimal DiscountAmt = rs.getBigDecimal(5); + BigDecimal WriteOffAmt = rs.getBigDecimal(6); + BigDecimal OpenAmt = rs.getBigDecimal(7); + BigDecimal OverUnderAmt = OpenAmt.subtract(PayAmt) + .subtract(DiscountAmt).subtract(WriteOffAmt); + // + if (alloc.get_ID() == 0 && !alloc.save(get_TrxName())) + { + log.log(Level.SEVERE, "Could not create Allocation Hdr"); + rs.close(); + pstmt.close(); + return false; + } + MAllocationLine aLine = null; + if (isSOTrx) + aLine = new MAllocationLine (alloc, PayAmt, + DiscountAmt, WriteOffAmt, OverUnderAmt); + else + aLine = new MAllocationLine (alloc, PayAmt.negate(), + DiscountAmt.negate(), WriteOffAmt.negate(), OverUnderAmt.negate()); + aLine.setDocInfo(C_BPartner_ID, 0, C_Invoice_ID); + aLine.setC_Payment_ID(getC_Payment_ID()); + if (!aLine.save(get_TrxName())) + log.log(Level.SEVERE, "Could not create Allocation Line"); + } + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, "allocatePaySelection", e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + + // Should start WF + boolean ok = true; + if (alloc.get_ID() == 0) + { + log.fine("No Allocation created - C_Payment_ID=" + + getC_Payment_ID()); + ok = false; + } + else + { + alloc.processIt(DocAction.ACTION_Complete); + ok = alloc.save(get_TrxName()); + m_processMsg = "@C_AllocationHdr_ID@: " + alloc.getDocumentNo(); + } + return ok; + } // allocatePaySelection + + /** + * De-allocate Payment. + * Unkink Invoices and Orders and delete Allocations + */ + private void deAllocate() + { + if (getC_Order_ID() != 0) + setC_Order_ID(0); + // if (getC_Invoice_ID() == 0) + // return; + // De-Allocate all + MAllocationHdr[] allocations = MAllocationHdr.getOfPayment(getCtx(), + getC_Payment_ID(), get_TrxName()); + log.fine("#" + allocations.length); + for (int i = 0; i < allocations.length; i++) + { + allocations[i].set_TrxName(get_TrxName()); + allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); + allocations[i].processIt(DocAction.ACTION_Reverse_Correct); + allocations[i].save(); + } + + // Unlink (in case allocation did not get it) + if (getC_Invoice_ID() != 0) + { + // Invoice + String sql = "UPDATE C_Invoice " + + "SET C_Payment_ID = NULL, IsPaid='N' " + + "WHERE C_Invoice_ID=" + getC_Invoice_ID() + + " AND C_Payment_ID=" + getC_Payment_ID(); + int no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Unlink Invoice #" + no); + // Order + sql = "UPDATE C_Order o " + + "SET C_Payment_ID = NULL " + + "WHERE EXISTS (SELECT * FROM C_Invoice i " + + "WHERE o.C_Order_ID=i.C_Order_ID AND i.C_Invoice_ID=" + getC_Invoice_ID() + ")" + + " AND C_Payment_ID=" + getC_Payment_ID(); + no = DB.executeUpdate(sql, get_TrxName()); + if (no != 0) + log.fine("Unlink Order #" + no); + } + // + setC_Invoice_ID(0); + setIsAllocated(false); + } // deallocate + + /** + * Void Document. + * @return true if success + */ + public boolean voidIt() + { + log.info(toString()); // Before Void m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID); if (m_processMsg != null) return false; - if (DOCSTATUS_Closed.equals(getDocStatus()) - || DOCSTATUS_Reversed.equals(getDocStatus()) - || DOCSTATUS_Voided.equals(getDocStatus())) - { - m_processMsg = "Document Closed: " + getDocStatus(); - setDocAction(DOCACTION_None); - return false; - } - // If on Bank Statement, don't void it - reverse it - if (getC_BankStatementLine_ID() > 0) - return reverseCorrectIt(); - - // Not Processed - if (DOCSTATUS_Drafted.equals(getDocStatus()) - || DOCSTATUS_Invalid.equals(getDocStatus()) - || DOCSTATUS_InProgress.equals(getDocStatus()) - || DOCSTATUS_Approved.equals(getDocStatus()) - || DOCSTATUS_NotApproved.equals(getDocStatus()) ) - { - addDescription(Msg.getMsg(getCtx(), "Voided") + " (" + getPayAmt() + ")"); - setPayAmt(Env.ZERO); - setDiscountAmt(Env.ZERO); - setWriteOffAmt(Env.ZERO); - setOverUnderAmt(Env.ZERO); - setIsAllocated(false); - // Unlink & De-Allocate - deAllocate(); - } - else - return reverseCorrectIt(); - - // + if (DOCSTATUS_Closed.equals(getDocStatus()) + || DOCSTATUS_Reversed.equals(getDocStatus()) + || DOCSTATUS_Voided.equals(getDocStatus())) + { + m_processMsg = "Document Closed: " + getDocStatus(); + setDocAction(DOCACTION_None); + return false; + } + // If on Bank Statement, don't void it - reverse it + if (getC_BankStatementLine_ID() > 0) + return reverseCorrectIt(); + + // Not Processed + if (DOCSTATUS_Drafted.equals(getDocStatus()) + || DOCSTATUS_Invalid.equals(getDocStatus()) + || DOCSTATUS_InProgress.equals(getDocStatus()) + || DOCSTATUS_Approved.equals(getDocStatus()) + || DOCSTATUS_NotApproved.equals(getDocStatus()) ) + { + addDescription(Msg.getMsg(getCtx(), "Voided") + " (" + getPayAmt() + ")"); + setPayAmt(Env.ZERO); + setDiscountAmt(Env.ZERO); + setWriteOffAmt(Env.ZERO); + setOverUnderAmt(Env.ZERO); + setIsAllocated(false); + // Unlink & De-Allocate + deAllocate(); + } + else + return reverseCorrectIt(); + + // // After Void m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID); if (m_processMsg != null) return false; - setProcessed(true); - setDocAction(DOCACTION_None); - return true; - } // voidIt - - /** - * Close Document. - * @return true if success - */ - public boolean closeIt() - { - log.info(toString()); + setProcessed(true); + setDocAction(DOCACTION_None); + return true; + } // voidIt + + /** + * Close Document. + * @return true if success + */ + public boolean closeIt() + { + log.info(toString()); // Before Close m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE); if (m_processMsg != null) @@ -2065,151 +2065,151 @@ public final class MPayment extends X_C_Payment m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE); if (m_processMsg != null) return false; - setDocAction(DOCACTION_None); - return true; - } // closeIt - - /** - * Reverse Correction - * @return true if success - */ - public boolean reverseCorrectIt() - { - log.info(toString()); + setDocAction(DOCACTION_None); + return true; + } // closeIt + + /** + * Reverse Correction + * @return true if success + */ + public boolean reverseCorrectIt() + { + log.info(toString()); // Before reverseCorrect m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSECORRECT); if (m_processMsg != null) return false; - + // Std Period open? Timestamp dateAcct = getDateAcct(); if (!MPeriod.isOpen(getCtx(), dateAcct, isReceipt() ? X_C_DocType.DOCBASETYPE_ARReceipt : X_C_DocType.DOCBASETYPE_APPayment)) dateAcct = new Timestamp(System.currentTimeMillis()); - // Auto Reconcile if not on Bank Statement - boolean reconciled = false; // getC_BankStatementLine_ID() == 0; - - // Create Reversal - MPayment reversal = new MPayment (getCtx(), 0, get_TrxName()); - copyValues(this, reversal); - reversal.setClientOrg(this); - reversal.setC_Order_ID(0); - reversal.setC_Invoice_ID(0); - reversal.setDateAcct(dateAcct); - // - reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals - reversal.setDocStatus(DOCSTATUS_Drafted); - reversal.setDocAction(DOCACTION_Complete); - // - reversal.setPayAmt(getPayAmt().negate()); - reversal.setDiscountAmt(getDiscountAmt().negate()); - reversal.setWriteOffAmt(getWriteOffAmt().negate()); - reversal.setOverUnderAmt(getOverUnderAmt().negate()); - // - reversal.setIsAllocated(true); - reversal.setIsReconciled(reconciled); // to put on bank statement - reversal.setIsOnline(false); - reversal.setIsApproved(true); - reversal.setR_PnRef(null); - reversal.setR_Result(null); - reversal.setR_RespMsg(null); - reversal.setR_AuthCode(null); - reversal.setR_Info(null); - reversal.setProcessing(false); - reversal.setOProcessing("N"); - reversal.setProcessed(false); - reversal.setPosted(false); - reversal.setDescription(getDescription()); - reversal.addDescription("{->" + getDocumentNo() + ")"); - reversal.save(get_TrxName()); - // Post Reversal - if (!reversal.processIt(DocAction.ACTION_Complete)) - { - m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); - return false; - } - reversal.closeIt(); - reversal.setDocStatus(DOCSTATUS_Reversed); - reversal.setDocAction(DOCACTION_None); - reversal.save(get_TrxName()); - - // Unlink & De-Allocate - deAllocate(); - setIsReconciled (reconciled); - setIsAllocated (true); // the allocation below is overwritten - // Set Status - addDescription("(" + reversal.getDocumentNo() + "<-)"); - setDocStatus(DOCSTATUS_Reversed); - setDocAction(DOCACTION_None); - setProcessed(true); - - // Create automatic Allocation - MAllocationHdr alloc = new MAllocationHdr (getCtx(), false, - getDateTrx(), getC_Currency_ID(), - Msg.translate(getCtx(), "C_Payment_ID") + ": " + reversal.getDocumentNo(), get_TrxName()); - alloc.setAD_Org_ID(getAD_Org_ID()); - if (!alloc.save()) - log.warning("Automatic allocation - hdr not saved"); - else - { - // Original Allocation - MAllocationLine aLine = new MAllocationLine (alloc, getPayAmt(true), - Env.ZERO, Env.ZERO, Env.ZERO); - aLine.setDocInfo(getC_BPartner_ID(), 0, 0); - aLine.setPaymentInfo(getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("Automatic allocation - line not saved"); - // Reversal Allocation - aLine = new MAllocationLine (alloc, reversal.getPayAmt(true), - Env.ZERO, Env.ZERO, Env.ZERO); - aLine.setDocInfo(reversal.getC_BPartner_ID(), 0, 0); - aLine.setPaymentInfo(reversal.getC_Payment_ID(), 0); - if (!aLine.save(get_TrxName())) - log.warning("Automatic allocation - reversal line not saved"); - } - alloc.processIt(DocAction.ACTION_Complete); - alloc.save(get_TrxName()); - // - StringBuffer info = new StringBuffer (reversal.getDocumentNo()); - info.append(" - @C_AllocationHdr_ID@: ").append(alloc.getDocumentNo()); - - // Update BPartner - if (getC_BPartner_ID() != 0) - { - MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); - bp.setTotalOpenBalance(); - bp.save(get_TrxName()); - } + // Auto Reconcile if not on Bank Statement + boolean reconciled = getC_BankStatementLine_ID() == 0; //AZ Goodwill + + // Create Reversal + MPayment reversal = new MPayment (getCtx(), 0, get_TrxName()); + copyValues(this, reversal); + reversal.setClientOrg(this); + reversal.setC_Order_ID(0); + reversal.setC_Invoice_ID(0); + reversal.setDateAcct(dateAcct); + // + reversal.setDocumentNo(getDocumentNo() + REVERSE_INDICATOR); // indicate reversals + reversal.setDocStatus(DOCSTATUS_Drafted); + reversal.setDocAction(DOCACTION_Complete); + // + reversal.setPayAmt(getPayAmt().negate()); + reversal.setDiscountAmt(getDiscountAmt().negate()); + reversal.setWriteOffAmt(getWriteOffAmt().negate()); + reversal.setOverUnderAmt(getOverUnderAmt().negate()); + // + reversal.setIsAllocated(true); + reversal.setIsReconciled(reconciled); // to put on bank statement + reversal.setIsOnline(false); + reversal.setIsApproved(true); + reversal.setR_PnRef(null); + reversal.setR_Result(null); + reversal.setR_RespMsg(null); + reversal.setR_AuthCode(null); + reversal.setR_Info(null); + reversal.setProcessing(false); + reversal.setOProcessing("N"); + reversal.setProcessed(false); + reversal.setPosted(false); + reversal.setDescription(getDescription()); + reversal.addDescription("{->" + getDocumentNo() + ")"); + reversal.save(get_TrxName()); + // Post Reversal + if (!reversal.processIt(DocAction.ACTION_Complete)) + { + m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); + return false; + } + reversal.closeIt(); + reversal.setDocStatus(DOCSTATUS_Reversed); + reversal.setDocAction(DOCACTION_None); + reversal.save(get_TrxName()); + + // Unlink & De-Allocate + deAllocate(); + setIsReconciled (reconciled); + setIsAllocated (true); // the allocation below is overwritten + // Set Status + addDescription("(" + reversal.getDocumentNo() + "<-)"); + setDocStatus(DOCSTATUS_Reversed); + setDocAction(DOCACTION_None); + setProcessed(true); + + // Create automatic Allocation + MAllocationHdr alloc = new MAllocationHdr (getCtx(), false, + getDateTrx(), getC_Currency_ID(), + Msg.translate(getCtx(), "C_Payment_ID") + ": " + reversal.getDocumentNo(), get_TrxName()); + alloc.setAD_Org_ID(getAD_Org_ID()); + if (!alloc.save()) + log.warning("Automatic allocation - hdr not saved"); + else + { + // Original Allocation + MAllocationLine aLine = new MAllocationLine (alloc, getPayAmt(true), + Env.ZERO, Env.ZERO, Env.ZERO); + aLine.setDocInfo(getC_BPartner_ID(), 0, 0); + aLine.setPaymentInfo(getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("Automatic allocation - line not saved"); + // Reversal Allocation + aLine = new MAllocationLine (alloc, reversal.getPayAmt(true), + Env.ZERO, Env.ZERO, Env.ZERO); + aLine.setDocInfo(reversal.getC_BPartner_ID(), 0, 0); + aLine.setPaymentInfo(reversal.getC_Payment_ID(), 0); + if (!aLine.save(get_TrxName())) + log.warning("Automatic allocation - reversal line not saved"); + } + alloc.processIt(DocAction.ACTION_Complete); + alloc.save(get_TrxName()); + // + StringBuffer info = new StringBuffer (reversal.getDocumentNo()); + info.append(" - @C_AllocationHdr_ID@: ").append(alloc.getDocumentNo()); + + // Update BPartner + if (getC_BPartner_ID() != 0) + { + MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); + bp.setTotalOpenBalance(); + bp.save(get_TrxName()); + } // After reverseCorrect m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); if (m_processMsg != null) return false; - - m_processMsg = info.toString(); - return true; - } // reverseCorrectionIt - - /** - * Get Bank Statement Line of payment or 0 - * @return id or 0 - */ - private int getC_BankStatementLine_ID() - { - String sql = "SELECT C_BankStatementLine_ID FROM C_BankStatementLine WHERE C_Payment_ID=?"; - int id = DB.getSQLValue(get_TrxName(), sql, getC_Payment_ID()); - if (id < 0) - return 0; - return id; - } // getC_BankStatementLine_ID - - /** - * Reverse Accrual - none - * @return true if success - */ - public boolean reverseAccrualIt() - { - log.info(toString()); + + m_processMsg = info.toString(); + return true; + } // reverseCorrectionIt + + /** + * Get Bank Statement Line of payment or 0 + * @return id or 0 + */ + private int getC_BankStatementLine_ID() + { + String sql = "SELECT C_BankStatementLine_ID FROM C_BankStatementLine WHERE C_Payment_ID=?"; + int id = DB.getSQLValue(get_TrxName(), sql, getC_Payment_ID()); + if (id < 0) + return 0; + return id; + } // getC_BankStatementLine_ID + + /** + * Reverse Accrual - none + * @return true if success + */ + public boolean reverseAccrualIt() + { + log.info(toString()); // Before reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSEACCRUAL); @@ -2221,135 +2221,135 @@ public final class MPayment extends X_C_Payment if (m_processMsg != null) return false; - return false; - } // reverseAccrualIt - - /** - * Re-activate - * @return true if success - */ - public boolean reActivateIt() - { - log.info(toString()); + return false; + } // reverseAccrualIt + + /** + * Re-activate + * @return true if success + */ + public boolean reActivateIt() + { + log.info(toString()); // Before reActivate m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE); if (m_processMsg != null) return false; - if (! reverseCorrectIt()) - return false; + if (! reverseCorrectIt()) + return false; // After reActivate m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE); if (m_processMsg != null) return false; - return true; - } // reActivateIt - - /** - * String Representation - * @return info - */ - public String toString () - { - StringBuffer sb = new StringBuffer ("MPayment["); - sb.append(get_ID()).append("-").append(getDocumentNo()) - .append(",Receipt=").append(isReceipt()) - .append(",PayAmt=").append(getPayAmt()) - .append(",Discount=").append(getDiscountAmt()) - .append(",WriteOff=").append(getWriteOffAmt()) - .append(",OverUnder=").append(getOverUnderAmt()); - return sb.toString (); - } // toString - - /** - * Get Document Info - * @return document info (untranslated) - */ - public String getDocumentInfo() - { - MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); - return dt.getName() + " " + getDocumentNo(); - } // getDocumentInfo - - /** - * Create PDF - * @return File or null - */ - public File createPDF () - { - try - { - File temp = File.createTempFile(get_TableName()+get_ID()+"_", ".pdf"); - return createPDF (temp); - } - catch (Exception e) - { - log.severe("Could not create PDF - " + e.getMessage()); - } - return null; - } // getPDF - - /** - * Create PDF file - * @param file output file - * @return file if success - */ - public File createPDF (File file) - { - // ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.PAYMENT, getC_Payment_ID()); - // if (re == null) - return null; - // return re.getPDF(file); - } // createPDF - - - /************************************************************************* - * Get Summary - * @return Summary of Document - */ - public String getSummary() - { - StringBuffer sb = new StringBuffer(); - sb.append(getDocumentNo()); - // : Total Lines = 123.00 (#1) - sb.append(": ") - .append(Msg.translate(getCtx(),"PayAmt")).append("=").append(getPayAmt()) - .append(",").append(Msg.translate(getCtx(),"WriteOffAmt")).append("=").append(getWriteOffAmt()); - // - Description - if (getDescription() != null && getDescription().length() > 0) - sb.append(" - ").append(getDescription()); - return sb.toString(); - } // getSummary - - /** - * Get Process Message - * @return clear text error message - */ - public String getProcessMsg() - { - return m_processMsg; - } // getProcessMsg - - /** - * Get Document Owner (Responsible) - * @return AD_User_ID - */ - public int getDoc_User_ID() - { - return getCreatedBy(); - } // getDoc_User_ID - - /** - * Get Document Approval Amount - * @return amount payment(AP) or write-off(AR) - */ - public BigDecimal getApprovalAmt() - { - if (isReceipt()) - return getWriteOffAmt(); - return getPayAmt(); - } // getApprovalAmt - -} // MPayment + return true; + } // reActivateIt + + /** + * String Representation + * @return info + */ + public String toString () + { + StringBuffer sb = new StringBuffer ("MPayment["); + sb.append(get_ID()).append("-").append(getDocumentNo()) + .append(",Receipt=").append(isReceipt()) + .append(",PayAmt=").append(getPayAmt()) + .append(",Discount=").append(getDiscountAmt()) + .append(",WriteOff=").append(getWriteOffAmt()) + .append(",OverUnder=").append(getOverUnderAmt()); + return sb.toString (); + } // toString + + /** + * Get Document Info + * @return document info (untranslated) + */ + public String getDocumentInfo() + { + MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); + return dt.getName() + " " + getDocumentNo(); + } // getDocumentInfo + + /** + * Create PDF + * @return File or null + */ + public File createPDF () + { + try + { + File temp = File.createTempFile(get_TableName()+get_ID()+"_", ".pdf"); + return createPDF (temp); + } + catch (Exception e) + { + log.severe("Could not create PDF - " + e.getMessage()); + } + return null; + } // getPDF + + /** + * Create PDF file + * @param file output file + * @return file if success + */ + public File createPDF (File file) + { + // ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.PAYMENT, getC_Payment_ID()); + // if (re == null) + return null; + // return re.getPDF(file); + } // createPDF + + + /************************************************************************* + * Get Summary + * @return Summary of Document + */ + public String getSummary() + { + StringBuffer sb = new StringBuffer(); + sb.append(getDocumentNo()); + // : Total Lines = 123.00 (#1) + sb.append(": ") + .append(Msg.translate(getCtx(),"PayAmt")).append("=").append(getPayAmt()) + .append(",").append(Msg.translate(getCtx(),"WriteOffAmt")).append("=").append(getWriteOffAmt()); + // - Description + if (getDescription() != null && getDescription().length() > 0) + sb.append(" - ").append(getDescription()); + return sb.toString(); + } // getSummary + + /** + * Get Process Message + * @return clear text error message + */ + public String getProcessMsg() + { + return m_processMsg; + } // getProcessMsg + + /** + * Get Document Owner (Responsible) + * @return AD_User_ID + */ + public int getDoc_User_ID() + { + return getCreatedBy(); + } // getDoc_User_ID + + /** + * Get Document Approval Amount + * @return amount payment(AP) or write-off(AR) + */ + public BigDecimal getApprovalAmt() + { + if (isReceipt()) + return getWriteOffAmt(); + return getPayAmt(); + } // getApprovalAmt + +} // MPayment