diff --git a/org.adempiere.payment.processor/plugin.xml b/org.adempiere.payment.processor/plugin.xml
index 82ff8777a2..ce5783b0a8 100644
--- a/org.adempiere.payment.processor/plugin.xml
+++ b/org.adempiere.payment.processor/plugin.xml
@@ -46,5 +46,13 @@
priority="0">
+
+
+
+
diff --git a/org.adempiere.payment.processor/src/org/compiere/model/PP_Dummy.java b/org.adempiere.payment.processor/src/org/compiere/model/PP_Dummy.java
new file mode 100644
index 0000000000..8ce6cce9f5
--- /dev/null
+++ b/org.adempiere.payment.processor/src/org/compiere/model/PP_Dummy.java
@@ -0,0 +1,75 @@
+/***********************************************************************
+ * This file is part of iDempiere ERP Open Source *
+ * http://www.idempiere.org *
+ * *
+ * Copyright (C) Contributors *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301, USA. *
+ * *
+ * Contributors: *
+ * - hengsin *
+ **********************************************************************/
+package org.compiere.model;
+
+/**
+ * dummy cc payment processor, for testing only
+ * @author hengsin
+ *
+ */
+public class PP_Dummy extends PaymentProcessor {
+
+ @Override
+ public boolean processCC() throws IllegalArgumentException {
+ //Clear CVV value and encrypt the CC# even if the transaction has not been approved
+ if (p_mp.getTrxType().equals(MPayment.TRXTYPE_Authorization)) {
+ //need to store following data as TrxType is now Authorization only
+ p_mp.setCreditCardVV(p_mp.getCreditCardVV());
+ p_mp.setCreditCardNumber(p_mp.getCreditCardNumber());
+ } else {
+ p_mp.setCreditCardVV(null);
+ p_mp.setCreditCardNumber(encrpytCreditCard(p_mp
+ .getCreditCardNumber()));
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isProcessedOK() {
+ return true;
+ }
+
+ //Encrypt credit card - leave 4 last numbers
+ private String encrpytCreditCard(String value) {
+ if (value == null)
+ return "";
+ else
+
+ if (value.length() <= 4)
+ return value;
+
+ Integer valueLength = value.length();
+
+ StringBuffer encryptedCC = new StringBuffer();
+
+ for (int i = 0; i < (valueLength - 4); i++) {
+ encryptedCC.append("0");
+ }
+
+ encryptedCC.append(value.substring(valueLength - 4, valueLength));
+
+ return encryptedCC.toString();
+ }
+}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCash.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCash.java
index ad5240c48f..23b2808329 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCash.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCash.java
@@ -16,7 +16,6 @@ package org.adempiere.webui.apps.form;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
-import java.util.Enumeration;
import org.adempiere.webui.component.Column;
import org.adempiere.webui.component.Columns;
@@ -34,19 +33,16 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog;
import org.compiere.grid.PaymentFormCash;
import org.compiere.model.GridTab;
-import org.compiere.model.MConversionRate;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
-import org.zkoss.zk.ui.event.Event;
-import org.zkoss.zk.ui.event.EventListener;
/**
*
* @author Elaine
*
*/
-public class WPaymentFormCash extends PaymentFormCash implements EventListener {
+public class WPaymentFormCash extends PaymentFormCash {
private WPaymentFormWindow window;
@@ -54,8 +50,6 @@ public class WPaymentFormCash extends PaymentFormCash implements EventListener en = s_Currencies.keys();
- while (en.hasMoreElements()) {
- Object key = en.nextElement();
- bCurrencyCombo.addItem(s_Currencies.get(key));
- }
- bCurrencyCombo.addActionListener(this);
- bCurrencyCombo.setSelectedKeyNamePair(s_Currencies.get(C_Currency_ID));
- }
- else // No EMU Currency
- {
- bCurrencyLabel.setVisible(false); // Cash
- bCurrencyCombo.setVisible(false);
- }
-
ArrayList list = getBankAccountList();
for (KeyNamePair pp : list)
bBankAccountCombo.addItem(pp);
@@ -168,16 +140,6 @@ public class WPaymentFormCash extends PaymentFormCash implements EventListener en = s_Currencies.keys();
- while (en.hasMoreElements())
- {
- Object key = en.nextElement();
- sCurrencyCombo.addItem(s_Currencies.get(key));
- }
- sCurrencyCombo.addActionListener(this);
- sCurrencyCombo.setSelectedKeyNamePair(s_Currencies.get(C_Currency_ID));
- }
- else // No EMU Currency
- {
- sCurrencyLabel.setVisible(false); // Check
- sCurrencyCombo.setVisible(false);
- sCurrencySpace.setVisible(false);
- }
-
ArrayList list = getBankAccountList();
for (KeyNamePair pp : list)
sBankAccountCombo.addItem(pp);
@@ -186,30 +160,14 @@ public class WPaymentFormCheck extends PaymentFormCheck implements EventListener
// Set Selection
if (selectedBankAccount != null)
sBankAccountCombo.setSelectedKeyNamePair(selectedBankAccount);
-
- boolean exist = isBankAccountProcessorExist(m_C_Currency_ID, (BigDecimal) sAmountField.getValue());
- sOnline.setVisible(exist);
-
- if (exist)
- updateOnlineButton();
+
+ updateOnlineButton();
}
public void onEvent(Event e)
{
- if (e.getTarget() == sCurrencyCombo || e.getTarget() == sAmountField)
+ if (e.getTarget() == sAmountField)
{
- int C_Currency_ID = 0;
- KeyNamePair pp = sCurrencyCombo.getSelectedItem().toKeyNamePair();
- if (pp != null)
- C_Currency_ID = pp.getKey();
-
- if (e.getTarget() == sCurrencyCombo)
- {
- BigDecimal amt = MConversionRate.convert(Env.getCtx(),
- m_Amount, m_C_Currency_ID, C_Currency_ID, m_AD_Client_ID, m_AD_Org_ID);
- sAmountField.setValue(amt);
- }
-
updateOnlineButton();
}
else if (e.getTarget() == sOnline)
@@ -221,26 +179,10 @@ public class WPaymentFormCheck extends PaymentFormCheck implements EventListener
private void updateOnlineButton()
{
- int C_Currency_ID = 0;
- KeyNamePair pp = sCurrencyCombo.getSelectedItem().toKeyNamePair();
- if (pp != null)
- C_Currency_ID = pp.getKey();
-
- BigDecimal PayAmt = (BigDecimal) sAmountField.getValue();
-
- if (C_Currency_ID > 0 && PayAmt != null)
- {
- MBankAccountProcessor bankAccountProcessor = getBankAccountProcessor(C_Currency_ID, PayAmt);
- sOnline.setEnabled(bankAccountProcessor != null);
- setBankAccountProcessor(bankAccountProcessor);
- }
- else
- {
- sOnline.setEnabled(false);
- setBankAccountProcessor(null);
- }
+ boolean exist = isBankAccountProcessorExist(m_C_Currency_ID, (BigDecimal) sAmountField.getValue());
+ sOnline.setVisible(exist);
}
-
+
@Override
public boolean checkMandatory() {
int C_BankAccount_ID = 0;
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCreditCard.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCreditCard.java
index f64303e769..fb5ef79a81 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCreditCard.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormCreditCard.java
@@ -68,13 +68,18 @@ public class WPaymentFormCreditCard extends PaymentFormCreditCard implements Eve
private Button kOnline = ButtonFactory.createNamedButton("Online");
private Label kStatus = new Label();
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public WPaymentFormCreditCard(int windowNo, GridTab mTab) {
super(windowNo, mTab);
window = new WPaymentFormWindow(this, windowNo);
init();
}
- public void init() {
+ protected void init() {
Grid kLayout = GridFactory.newGridLayout();
window.getPanel().appendChild(kLayout);
kNumberField.setMaxlength(16);
@@ -226,6 +231,7 @@ public class WPaymentFormCreditCard extends PaymentFormCreditCard implements Eve
}
}
+ @Override
public void onEvent(Event e)
{
if (e.getTarget() == kOnline) {
@@ -296,7 +302,7 @@ public class WPaymentFormCreditCard extends PaymentFormCreditCard implements Eve
ValueNamePair vp = kTypeCombo.getSelectedItem().toValueNamePair();
String CCType = vp.getValue();
- boolean ok = processOnline(CCType, kNumberField.getText(), kApprovalField.getText(), kExpField.getText());
+ boolean ok = processOnline(CCType, kNumberField.getText(), kApprovalField.getValue(), kExpField.getText());
if (!ok)
Dialog.error(getWindowNo(), "PaymentNotProcessed", processMsg);
else
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirect.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirect.java
index 77aad8f032..aed8c28337 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirect.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirect.java
@@ -33,6 +33,7 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog;
import org.compiere.grid.PaymentFormDirect;
import org.compiere.model.GridTab;
+import org.compiere.model.MBankAccount;
import org.compiere.model.MBankAccountProcessor;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
@@ -61,16 +62,22 @@ public abstract class WPaymentFormDirect extends PaymentFormDirect implements Ev
private Label tRoutingText = new Label();
private Label tNumberText = new Label();
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ * @param isDebit
+ */
public WPaymentFormDirect(int windowNo, GridTab mTab, boolean isDebit) {
super(windowNo, mTab, isDebit);
window = new WPaymentFormWindow(this, windowNo);
init();
}
- public void init() {
+ protected void init() {
Grid tPanelLayout = GridFactory.newGridLayout();
window.getPanel().appendChild(tPanelLayout);
- tAccountLabel.setText(Msg.translate(Env.getCtx(), "C_BP_BankAccount_ID"));
+ tAccountLabel.setText(Msg.translate(Env.getCtx(), "C_BankAccount_ID"));
tRoutingField.setCols(8);
tNumberField.setCols(10);
tRoutingText.setText(Msg.translate(Env.getCtx(), "RoutingNo"));
@@ -114,6 +121,8 @@ public abstract class WPaymentFormDirect extends PaymentFormDirect implements Ev
@Override
public void loadData() {
+ super.loadData();
+
if (m_C_Payment_ID != 0)
{
tRoutingField.setText(m_mPayment.getRoutingNo());
@@ -121,7 +130,7 @@ public abstract class WPaymentFormDirect extends PaymentFormDirect implements Ev
tStatus.setText(m_mPayment.getR_PnRef());
}
- ArrayList list = getBPBankAccountList();
+ ArrayList list = getBankAccountList();
for (KeyNamePair pp : list)
tAccountCombo.addItem(pp);
@@ -132,6 +141,7 @@ public abstract class WPaymentFormDirect extends PaymentFormDirect implements Ev
setBankAccountProcessor(bankAccountProcessor);
}
+ @Override
public void onEvent(Event e)
{
if (e.getTarget() == tOnline)
@@ -148,10 +158,10 @@ public abstract class WPaymentFormDirect extends PaymentFormDirect implements Ev
*/
boolean dataOK = true;
ListItem selected = tAccountCombo.getSelectedItem();
- KeyNamePair bpba = selected != null ? selected.toKeyNamePair() : null;
- if (bpba == null)
+ KeyNamePair ba = selected != null ? selected.toKeyNamePair() : null;
+ if (ba == null)
{
- Dialog.error(getWindowNo(), "PaymentBPBankNotFound");
+ Dialog.error(getWindowNo(), "FillMandatory", Msg.translate(Env.getCtx(), MBankAccount.COLUMNNAME_C_BankAccount_ID));
dataOK = false;
}
//
@@ -161,10 +171,13 @@ public abstract class WPaymentFormDirect extends PaymentFormDirect implements Ev
@Override
public boolean saveChangesInTrx(final String trxName) {
- boolean ok = save(0, tRoutingField.getText(), tNumberField.getText(), trxName);
+ ListItem selected = tAccountCombo.getSelectedItem();
+ KeyNamePair ba = selected != null ? selected.toKeyNamePair() : null;
+ int C_BankAccount_ID = ba != null ? ba.getKey() : 0;
+ boolean ok = save(C_BankAccount_ID, tRoutingField.getText(), tNumberField.getText(), trxName);
if (!ok)
Dialog.error(getWindowNo(), "PaymentError", processMsg);
- else if (processMsg != null)
+ else
Dialog.info(getWindowNo(), "PaymentCreated", m_mPayment.getDocumentNo());
return ok;
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDebit.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDebit.java
index 3c6f1b2e25..7be3361bff 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDebit.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDebit.java
@@ -23,6 +23,11 @@ import org.compiere.model.GridTab;
*/
public class WPaymentFormDirectDebit extends WPaymentFormDirect {
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public WPaymentFormDirectDebit(int windowNo, GridTab mTab) {
super(windowNo, mTab, true);
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDeposit.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDeposit.java
index a3fef1149a..bcc339f1ab 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDeposit.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormDirectDeposit.java
@@ -23,6 +23,11 @@ import org.compiere.model.GridTab;
*/
public class WPaymentFormDirectDeposit extends WPaymentFormDirect {
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public WPaymentFormDirectDeposit(int windowNo, GridTab mTab) {
super(windowNo, mTab, false);
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormMixedPOS.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormMixedPOS.java
index fafcd5d55a..51cd45f23d 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormMixedPOS.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormMixedPOS.java
@@ -58,4 +58,8 @@ public class WPaymentFormMixedPOS extends PaymentFormMixedPOS {
public Object getWindow() {
return window;
}
+
+ @Override
+ protected void afterSave(boolean success) {
+ }
}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormOnCredit.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormOnCredit.java
index c13eccb211..be8440fb2d 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormOnCredit.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormOnCredit.java
@@ -44,13 +44,18 @@ public class WPaymentFormOnCredit extends PaymentFormOnCredit {
private Label pTermLabel = new Label();
private Listbox pTermCombo = ListboxFactory.newDropdownListbox();
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public WPaymentFormOnCredit(int windowNo, GridTab mTab) {
super(windowNo, mTab);
window = new WPaymentFormWindow(this, windowNo);
init();
}
- public void init() {
+ protected void init() {
Grid pPanelLayout = GridFactory.newGridLayout();
window.getPanel().appendChild(pPanelLayout);
pTermLabel.setText(Msg.translate(Env.getCtx(), "C_PaymentTerm_ID"));
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java
index 014e6e2c73..7b303e610a 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java
@@ -44,7 +44,7 @@ public class WPaymentFormWindow extends Window implements EventListener,
private static final long serialVersionUID = 2710316463655831868L;
private PaymentForm paymentForm;
-// private int windowNo;
+ private int windowNo;
private Panel mainPanel = new Panel();
private Panel centerPanel = new Panel();
@@ -60,7 +60,7 @@ public class WPaymentFormWindow extends Window implements EventListener,
super();
this.paymentForm = paymentForm;
-// this.windowNo = windowNo;
+ this.windowNo = windowNo;
try {
zkInit();
@@ -79,6 +79,10 @@ public class WPaymentFormWindow extends Window implements EventListener,
this.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
}
+ protected int getWindowNo() {
+ return this.windowNo;
+ }
+
private void zkInit() throws Exception {
this.appendChild(mainPanel);
mainPanel.appendChild(mainLayout);
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/Dialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/Dialog.java
index d831ce6a07..b6a45ddf8e 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/Dialog.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/Dialog.java
@@ -510,7 +510,7 @@ public final class Dialog {
}
String dialogTitle = getDialogTitle(title, windowNo);
- String message = constructMessage(adMessage, null);
+ String message = constructMessage(adMessage, additionalMessage);
message = formatDialogMessage(message);
Messagebox.showDialog(message, dialogTitle, Messagebox.OK, Messagebox.INFORMATION);
diff --git a/org.adempiere.ui/src/org/compiere/grid/IPaymentForm.java b/org.adempiere.ui/src/org/compiere/grid/IPaymentForm.java
index 09bd591ff9..bcb1bf5abe 100644
--- a/org.adempiere.ui/src/org/compiere/grid/IPaymentForm.java
+++ b/org.adempiere.ui/src/org/compiere/grid/IPaymentForm.java
@@ -16,39 +16,92 @@ package org.compiere.grid;
import org.compiere.model.MBankAccountProcessor;
import org.compiere.model.PO;
+/**
+ *
+ * Interface for payment form for different payment mode (cash, credit card, etc)
+ *
+ */
public interface IPaymentForm {
+ /**
+ * dynamic initialization
+ * @return false if there are errors, true otherwise
+ * @throws Exception
+ */
public boolean dynInit() throws Exception;
+ /**
+ * Load payment and related transaction records. Usually call from dynInit()
+ */
public void loadData();
+ /**
+ * mandatory field validations
+ * @return true if all mandatory field have been populated
+ */
public boolean checkMandatory();
+ /**
+ *
+ * @return true if only show payment rule and doesn't save changes to DB
+ */
+ public boolean isOnlyRule();
+
/**************************************************************************
* Save Changes
* @return true, if Window can exit
*/
public boolean saveChanges();
- public boolean saveChangesInTrx(final String trxName);
-
/**
- * Need Save record (payment with waiting order)
- * @return true if payment with waiting order
+ * Save changes to DB
+ * @param trxName
+ * @return true if save successfully
+ */
+ public boolean saveChangesInTrx(final String trxName);
+
+ /**
+ * Need to save the calling window (order, invoice)
+ * @return true if changes have been to the calling window
*/
public boolean needSave();
+ /**
+ * online payment processing (for e.g credit card)
+ */
public void processOnline();
+ /**
+ *
+ * @return true if payment transaction have been approved by payment gateway
+ */
public boolean isApproved();
+ /**
+ * show form
+ */
public void showWindow();
+ /**
+ * close form
+ */
public void closeWindow();
+ /**
+ *
+ * @return instance of UI form
+ */
public Object getWindow();
+ /**
+ * Make additional changes to PO before write to DB
+ * @param po
+ */
public void setCustomizeValues(PO po);
+ /**
+ * Set online payment processor configuration
+ * @param bankAccountProcessor
+ */
public void setBankAccountProcessor(MBankAccountProcessor bankAccountProcessor);
}
\ No newline at end of file
diff --git a/org.adempiere.ui/src/org/compiere/grid/IPaymentFormFactory.java b/org.adempiere.ui/src/org/compiere/grid/IPaymentFormFactory.java
index ca60a76679..82241c85bf 100644
--- a/org.adempiere.ui/src/org/compiere/grid/IPaymentFormFactory.java
+++ b/org.adempiere.ui/src/org/compiere/grid/IPaymentFormFactory.java
@@ -22,6 +22,13 @@ import org.compiere.model.GridTab;
*/
public interface IPaymentFormFactory {
+ /**
+ * Create payment form instance by paymentRule
+ * @param windowNo
+ * @param mTab
+ * @param paymentRule
+ * @return {@link IPaymentForm} instance
+ */
public IPaymentForm create(int windowNo, GridTab mTab, String paymentRule);
}
diff --git a/org.adempiere.ui/src/org/compiere/grid/PaymentForm.java b/org.adempiere.ui/src/org/compiere/grid/PaymentForm.java
index 04525f17f6..34e50c6232 100644
--- a/org.adempiere.ui/src/org/compiere/grid/PaymentForm.java
+++ b/org.adempiere.ui/src/org/compiere/grid/PaymentForm.java
@@ -18,7 +18,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
-import java.util.Hashtable;
import java.util.Properties;
import java.util.logging.Level;
@@ -30,7 +29,6 @@ import org.compiere.model.PO;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
-import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
import org.compiere.util.TrxRunnable;
@@ -51,32 +49,31 @@ public abstract class PaymentForm implements IPaymentForm {
private GridTab m_mTab;
// Data from Order/Invoice
- public String m_DocStatus = null;
+ protected String m_DocStatus = null;
/** Start Payment Rule */
- public String m_PaymentRule = "";
+ protected String m_PaymentRule = "";
/** Start Acct Date */
- public Timestamp m_DateAcct = null;
- /** Start Payment */
-// public int m_C_Payment_ID = 0;
-// public MPayment m_mPayment = null;
-// public MPayment m_mPaymentOriginal = null;
+ protected Timestamp m_DateAcct = null;
/** Invoice Currency */
- public int m_C_Currency_ID = 0;
- public int m_AD_Client_ID = 0;
- public boolean m_Cash_As_Payment = true;
- public int m_AD_Org_ID = 0;
- public int m_C_BPartner_ID = 0;
- public BigDecimal m_Amount = Env.ZERO; // Payment Amount
+ protected int m_C_Currency_ID = 0;
+ protected int m_AD_Client_ID = 0;
+ protected boolean m_Cash_As_Payment = true;
+ protected int m_AD_Org_ID = 0;
+ protected int m_C_BPartner_ID = 0;
+ protected BigDecimal m_Amount = Env.ZERO; // Payment Amount
- public boolean m_needSave = false;
+ protected boolean m_needSave = false;
/** Only allow changing Rule */
- public boolean m_onlyRule = false;
+ protected boolean m_onlyRule = false;
/** Is SOTrx */
- public boolean m_isSOTrx = true;
-
- public Hashtable s_Currencies = null;
+ protected boolean m_isSOTrx = true;
+ /**
+ *
+ * @param WindowNo
+ * @param mTab
+ */
public PaymentForm(int WindowNo, GridTab mTab) {
m_WindowNo = WindowNo;
m_isSOTrx = "Y".equals(Env.getContext(Env.getCtx(), WindowNo, "IsSOTrx"));
@@ -127,9 +124,6 @@ public abstract class PaymentForm implements IPaymentForm {
m_C_Currency_ID = ((Integer)m_mTab.getValue("C_Currency_ID")).intValue();
m_DateAcct = (Timestamp)m_mTab.getValue("DateAcct");
- if (s_Currencies == null)
- loadCurrencies();
-
/**
* Payment Combo
*/
@@ -146,10 +140,9 @@ public abstract class PaymentForm implements IPaymentForm {
// BF [ 1920179 ] perform the save in a trx's context.
final boolean[] success = new boolean[] { false };
final TrxRunnable r = new TrxRunnable() {
-
public void run(String trxName) {
// only Payment Rule
- if (m_onlyRule)
+ if (isOnlyRule())
success[0] = true;
else
success[0] = saveChangesInTrx(trxName);
@@ -164,42 +157,18 @@ public abstract class PaymentForm implements IPaymentForm {
success[0] = false;
throw new AdempiereException("PaymentError", e);
}
+
+ afterSave(success[0]);
+
return success[0];
- } // saveChanges
+ }
/**
- * Fill s_Currencies with EMU currencies
+ * after save and trx committed/rollback
+ * @param success
*/
- protected void loadCurrencies()
- {
- s_Currencies = new Hashtable(12); // Currenly only 10+1
- String SQL = "SELECT C_Currency_ID, ISO_Code FROM C_Currency "
- + "WHERE (IsEMUMember='Y' AND EMUEntryDate getBankAccountList() {
selectedBankAccount = null;
ArrayList list = new ArrayList();
@@ -146,7 +156,12 @@ public abstract class PaymentFormCash extends PaymentForm {
return list;
}
- public KeyNamePair selectedCashBook;
+ protected KeyNamePair selectedCashBook;
+
+ /**
+ *
+ * @return list of active cash book
+ */
public ArrayList getCashBookList() {
selectedCashBook = null;
ArrayList list = new ArrayList();
@@ -207,8 +222,20 @@ public abstract class PaymentFormCash extends PaymentForm {
return ok;
}
- public String processMsg;
- public boolean save(int newC_BankAccount_ID, int newC_CashBook_ID, Timestamp newDateAcct, BigDecimal newAmount, String trxName)
+ protected String processMsg;
+
+ private int newC_CashLine_ID;
+
+ /**
+ *
+ * @param C_BankAccount_ID
+ * @param C_CashBook_ID
+ * @param dateAcct
+ * @param amount
+ * @param trxName
+ * @return true if save successfully
+ */
+ public boolean save(int C_BankAccount_ID, int C_CashBook_ID, Timestamp dateAcct, BigDecimal amount, String trxName)
{
// set trxname for class objects
if (m_cashLine != null)
@@ -219,7 +246,7 @@ public abstract class PaymentFormCash extends PaymentForm {
m_mPaymentOriginal.set_TrxName(trxName);
processMsg = null;
- int newC_CashLine_ID = m_C_CashLine_ID;
+ newC_CashLine_ID = m_C_CashLine_ID;
/***********************
* Changed PaymentRule
@@ -259,7 +286,7 @@ public abstract class PaymentFormCash extends PaymentForm {
if (invoice == null && C_Order_ID != 0)
order = new MOrder (Env.getCtx(), C_Order_ID, null);
- BigDecimal payAmount = newAmount;
+ BigDecimal payAmount = amount;
// Info
if (log.isLoggable(Level.CONFIG)) log.config("C_Order_ID=" + C_Order_ID + ", C_Invoice_ID=" + C_Invoice_ID);
@@ -273,7 +300,7 @@ public abstract class PaymentFormCash extends PaymentForm {
if (C_Invoice_ID == 0 && order == null)
{
- log.config("No Invoice!");
+ if (log.isLoggable(Level.CONFIG)) log.config("No Invoice!");
processMsg = Msg.getMsg(Env.getCtx(), "CashNotCreated");
throw new AdempiereException(processMsg);
}
@@ -283,16 +310,16 @@ public abstract class PaymentFormCash extends PaymentForm {
if (m_cashLine != null
&& payAmount.compareTo(m_cashLine.getAmount()) != 0)
{
- log.config("Changed CashBook Amount");
- m_cashLine.setAmount(newAmount);
+ if (log.isLoggable(Level.CONFIG)) log.config("Changed CashBook Amount");
+ m_cashLine.setAmount(amount);
m_cashLine.saveEx();
}
// Different Date/CashBook
if (m_cashLine != null
- && (newC_CashBook_ID != m_C_CashBook_ID
- || !TimeUtil.isSameDay(m_cashLine.getStatementDate(), newDateAcct)))
+ && (C_CashBook_ID != m_C_CashBook_ID
+ || !TimeUtil.isSameDay(m_cashLine.getStatementDate(), dateAcct)))
{
- if (log.isLoggable(Level.CONFIG)) log.config("Changed CashBook/Date: " + m_C_CashBook_ID + "->" + newC_CashBook_ID);
+ if (log.isLoggable(Level.CONFIG)) log.config("Changed CashBook/Date: " + m_C_CashBook_ID + "->" + C_CashBook_ID);
MCashLine reverse = m_cashLine.createReversal();
reverse.saveEx();
m_cashLine = null;
@@ -301,17 +328,17 @@ public abstract class PaymentFormCash extends PaymentForm {
// Create new
if (m_cashLine == null)
{
- log.config("New CashBook");
+ if (log.isLoggable(Level.CONFIG)) log.config("New CashBook");
int C_Currency_ID = 0;
if (invoice != null)
C_Currency_ID = invoice.getC_Currency_ID();
if (C_Currency_ID == 0 && order != null)
C_Currency_ID = order.getC_Currency_ID();
MCash cash = null;
- if (newC_CashBook_ID != 0)
- cash = MCash.get (Env.getCtx(), newC_CashBook_ID, newDateAcct, null);
+ if (C_CashBook_ID != 0)
+ cash = MCash.get (Env.getCtx(), C_CashBook_ID, dateAcct, null);
else // Default
- cash = MCash.get (Env.getCtx(), m_AD_Org_ID, newDateAcct, C_Currency_ID, null);
+ cash = MCash.get (Env.getCtx(), m_AD_Org_ID, dateAcct, C_Currency_ID, null);
if (cash == null || cash.get_ID() == 0)
{
processMsg = CLogger.retrieveErrorString("CashNotCreated");
@@ -320,8 +347,6 @@ public abstract class PaymentFormCash extends PaymentForm {
else
{
MCashLine cl = new MCashLine (cash);
- // cl.setAmount(new BigDecimal(bAmountField.getText()));
- //ADialog.info(m_WindowNo, this, "m_cashLine - New Cashbook", "Amount: "+cl.getAmount());
if (invoice != null)
cl.setInvoice(invoice); // overrides amount
if (order != null)
@@ -329,9 +354,9 @@ public abstract class PaymentFormCash extends PaymentForm {
cl.setOrder(order, null); // overrides amount
m_needSave = true;
}
- cl.setAmount(newAmount);
+ cl.setAmount(amount);
cl.saveEx();
- log.config("CashCreated");
+ if (log.isLoggable(Level.CONFIG)) log.config("CashCreated");
if (invoice == null && C_Invoice_ID != 0)
{
invoice = new MInvoice (Env.getCtx(), C_Invoice_ID, null);
@@ -348,7 +373,7 @@ public abstract class PaymentFormCash extends PaymentForm {
order.setC_CashLine_ID(cl.getC_CashLine_ID());
order.saveEx(trxName);
}
- log.config("Update Order & Invoice with CashLine");
+ if (log.isLoggable(Level.CONFIG)) log.config("Update Order & Invoice with CashLine");
}
}
} // have invoice
@@ -364,16 +389,15 @@ public abstract class PaymentFormCash extends PaymentForm {
m_mPayment.setAmount(m_C_Currency_ID, payAmount);
// Get changes to cash amount
m_mPayment.setTenderType(MPayment.TENDERTYPE_Cash);
- m_mPayment.setBankCash(newC_BankAccount_ID, m_isSOTrx, MPayment.TENDERTYPE_Cash);
+ m_mPayment.setBankCash(C_BankAccount_ID, m_isSOTrx, MPayment.TENDERTYPE_Cash);
m_mPayment.setC_BPartner_ID(m_C_BPartner_ID);
m_mPayment.setC_Invoice_ID(C_Invoice_ID);
if (order != null)
{
- m_mPayment.setC_Order_ID(C_Order_ID);
- m_needSave = true;
+ m_mPayment.setC_Order_ID(C_Order_ID);
}
- m_mPayment.setDateTrx(newDateAcct);
- m_mPayment.setDateAcct(newDateAcct);
+ m_mPayment.setDateTrx(dateAcct);
+ m_mPayment.setDateAcct(dateAcct);
m_mPayment.saveEx();
// Save/Post
@@ -392,12 +416,26 @@ public abstract class PaymentFormCash extends PaymentForm {
else
if (log.isLoggable(Level.FINE)) log.fine("NotDraft " + m_mPayment);
}
+
+ return true;
+ }
+
+ @Override
+ public void afterSave(boolean success)
+ {
+ if (!success)
+ return;
/**********************
* Save Values to mTab
*/
- log.config("Saving changes");
- //
+ //refresh
+ getGridTab().dataRefresh(false);
+ Object paymentIdValue = getGridTab().getValue("C_Payment_ID");
+ if (paymentIdValue != null && paymentIdValue instanceof Number)
+ m_C_Payment_ID = ((Number)paymentIdValue).intValue();
+ else
+ m_C_Payment_ID = 0;
// Set Payment
if (m_mPayment.getC_Payment_ID() != m_C_Payment_ID)
{
@@ -405,7 +443,13 @@ public abstract class PaymentFormCash extends PaymentForm {
getGridTab().setValue("C_Payment_ID", null);
else
getGridTab().setValue("C_Payment_ID", Integer.valueOf(m_mPayment.getC_Payment_ID()));
+ m_needSave = true;
}
+ Object cashLineIdValue = getGridTab().getValue("C_CashLine_ID");
+ if (cashLineIdValue != null && cashLineIdValue instanceof Number)
+ m_C_CashLine_ID = ((Number)cashLineIdValue).intValue();
+ else
+ m_C_CashLine_ID = 0;
// Set Cash
if (newC_CashLine_ID != m_C_CashLine_ID)
{
@@ -413,7 +457,7 @@ public abstract class PaymentFormCash extends PaymentForm {
getGridTab().setValue("C_CashLine_ID", null);
else
getGridTab().setValue("C_CashLine_ID", Integer.valueOf(newC_CashLine_ID));
+ m_needSave = true;
}
- return true;
}
}
diff --git a/org.adempiere.ui/src/org/compiere/grid/PaymentFormCheck.java b/org.adempiere.ui/src/org/compiere/grid/PaymentFormCheck.java
index ec33a788c3..4648ab7e17 100644
--- a/org.adempiere.ui/src/org/compiere/grid/PaymentFormCheck.java
+++ b/org.adempiere.ui/src/org/compiere/grid/PaymentFormCheck.java
@@ -42,12 +42,17 @@ public abstract class PaymentFormCheck extends PaymentForm {
private static final String PAYMENTRULE = MInvoice.PAYMENTRULE_Check;
/** Start Payment */
- public int m_C_Payment_ID = 0;
- public MPayment m_mPayment = null;
- public MPayment m_mPaymentOriginal = null;
+ protected int m_C_Payment_ID = 0;
+ protected MPayment m_mPayment = null;
+ protected MPayment m_mPaymentOriginal = null;
/** Start Bank Account */
- public int m_C_BankAccount_ID = 0;
+ protected int m_C_BankAccount_ID = 0;
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public PaymentFormCheck(int windowNo, GridTab mTab) {
super(windowNo, mTab);
}
@@ -76,7 +81,12 @@ public abstract class PaymentFormCheck extends PaymentForm {
m_C_BankAccount_ID = m_mPayment.getC_BankAccount_ID();
}
- public KeyNamePair selectedBankAccount;
+ protected KeyNamePair selectedBankAccount;
+
+ /**
+ * set default selected bank account and return list of active bank account records
+ * @return list of active bank account
+ */
public ArrayList getBankAccountList() {
selectedBankAccount = null;
ArrayList list = new ArrayList();
@@ -132,8 +142,19 @@ public abstract class PaymentFormCheck extends PaymentForm {
return ok;
}
- public String processMsg = null;
- public boolean save(int newC_BankAccount_ID, String routing, String number, String check, BigDecimal amount, String trxName)
+ protected String processMsg = null;
+
+ /**
+ *
+ * @param C_BankAccount_ID
+ * @param routing routing number
+ * @param number account number
+ * @param check check number
+ * @param amount
+ * @param trxName
+ * @return true if save successfully
+ */
+ public boolean save(int C_BankAccount_ID, String routing, String number, String check, BigDecimal amount, String trxName)
{
// set trxname for class objects
if (m_mPayment != null)
@@ -222,14 +243,13 @@ public abstract class PaymentFormCheck extends PaymentForm {
if (log.isLoggable(Level.FINE)) log.fine("Payment - " + PAYMENTRULE);
// Set Amount
m_mPayment.setAmount(m_C_Currency_ID, payAmount);
- m_mPayment.setBankCheck(newC_BankAccount_ID, m_isSOTrx, routing,
+ m_mPayment.setBankCheck(C_BankAccount_ID, m_isSOTrx, routing,
number, check);
m_mPayment.setC_BPartner_ID(m_C_BPartner_ID);
m_mPayment.setC_Invoice_ID(C_Invoice_ID);
if (order != null)
{
- m_mPayment.setC_Order_ID(C_Order_ID);
- m_needSave = true;
+ m_mPayment.setC_Order_ID(C_Order_ID);
}
m_mPayment.setDateTrx(m_DateAcct);
m_mPayment.setDateAcct(m_DateAcct);
@@ -251,11 +271,26 @@ public abstract class PaymentFormCheck extends PaymentForm {
}
else
if (log.isLoggable(Level.FINE)) log.fine("NotDraft " + m_mPayment);
+
+ return true;
+ }
+
+ @Override
+ protected void afterSave(boolean success)
+ {
+ if (!success)
+ return;
/**********************
* Save Values to mTab
*/
- log.config("Saving changes");
+ //refresh
+ getGridTab().dataRefresh(false);
+ Object paymentIdValue = getGridTab().getValue("C_Payment_ID");
+ if (paymentIdValue != null && paymentIdValue instanceof Number)
+ m_C_Payment_ID = ((Number)paymentIdValue).intValue();
+ else
+ m_C_Payment_ID = 0;
// Set Payment
if (m_mPayment.getC_Payment_ID() != m_C_Payment_ID)
{
@@ -263,15 +298,27 @@ public abstract class PaymentFormCheck extends PaymentForm {
getGridTab().setValue("C_Payment_ID", null);
else
getGridTab().setValue("C_Payment_ID", Integer.valueOf(m_mPayment.getC_Payment_ID()));
+ m_needSave = true;
}
- return true;
}
-
+
+ /**
+ *
+ * @param C_Currency_ID
+ * @param PayAmt
+ * @return if online payment processor have been configured for tender type check
+ */
public boolean isBankAccountProcessorExist(int C_Currency_ID, BigDecimal PayAmt)
{
return isBankAccountProcessorExist(Env.getCtx(), MPayment.TENDERTYPE_Check, "", Env.getAD_Client_ID(Env.getCtx()), C_Currency_ID, PayAmt, null);
}
+ /**
+ * Get online payment processor configuration for tender type check
+ * @param C_Currency_ID
+ * @param PayAmt
+ * @return {@link MBankAccountProcessor}
+ */
public MBankAccountProcessor getBankAccountProcessor(int C_Currency_ID, BigDecimal PayAmt)
{
return getBankAccountProcessor(Env.getCtx(), MPayment.TENDERTYPE_Check, "", Env.getAD_Client_ID(Env.getCtx()), C_Currency_ID, PayAmt, null);
diff --git a/org.adempiere.ui/src/org/compiere/grid/PaymentFormCreditCard.java b/org.adempiere.ui/src/org/compiere/grid/PaymentFormCreditCard.java
index 321e72f74d..31170c5cfd 100644
--- a/org.adempiere.ui/src/org/compiere/grid/PaymentFormCreditCard.java
+++ b/org.adempiere.ui/src/org/compiere/grid/PaymentFormCreditCard.java
@@ -41,13 +41,18 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
private static final String PAYMENTRULE = MInvoice.PAYMENTRULE_CreditCard;
/** Start Payment */
- public int m_C_Payment_ID = 0;
- public MPayment m_mPayment = null;
- public MPayment m_mPaymentOriginal = null;
- public MPaymentTransaction m_mPaymentTransaction = null;
+ protected int m_C_Payment_ID = 0;
+ protected MPayment m_mPayment = null;
+ protected MPayment m_mPaymentOriginal = null;
+ protected MPaymentTransaction m_mPaymentTransaction = null;
/** Start CreditCard */
- public String m_CCType = "";
+ protected String m_CCType = "";
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public PaymentFormCreditCard(int windowNo, GridTab mTab) {
super(windowNo, mTab);
}
@@ -187,7 +192,12 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
m_CCType = m_mPaymentTransaction.getCreditCardType();
}
- public ValueNamePair selectedCreditCard;
+ protected ValueNamePair selectedCreditCard;
+
+ /**
+ *
+ * @return list of accepted credit card types
+ */
public ValueNamePair[] getCreditCardList()
{
selectedCreditCard = null;
@@ -212,8 +222,18 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
return ok;
}
- public String processMsg = null;
- public boolean save(String newCCType, String newCCNumber, String newCCExp, BigDecimal newAmount, String trxName)
+ protected String processMsg = null;
+
+ /**
+ *
+ * @param CCType credit card type
+ * @param CCNumber credit card number
+ * @param CCExp credit card expire date
+ * @param amount ignore
+ * @param trxName
+ * @return true if save successfully
+ */
+ public boolean save(String CCType, String CCNumber, String CCExp, BigDecimal amount, String trxName)
{
// set trxname for class objects
if (m_mPayment != null)
@@ -307,7 +327,7 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
if (log.isLoggable(Level.FINE)) log.fine("Payment - " + PAYMENTRULE);
// Set Amount
m_mPayment.setAmount(m_C_Currency_ID, payAmount);
- m_mPayment.setCreditCard(MPayment.TRXTYPE_Sales, newCCType, newCCNumber, "", newCCExp);
+ m_mPayment.setCreditCard(MPayment.TRXTYPE_Sales, CCType, CCNumber, "", CCExp);
m_mPayment.setPaymentProcessor();
if (isPOSOrder || isInvoice)
@@ -315,7 +335,6 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
else if (isCreditMemo)
{
m_mPayment.setTrxType(MPayment.TRXTYPE_CreditPayment);
-// m_mPayment.setOrig_TrxID(kPGOrderIDField.getValue());
}
else if (C_Invoice_ID != 0)
{
@@ -341,8 +360,7 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
order = new MOrder (Env.getCtx(), C_Order_ID, null);
if (order != null)
{
- m_mPayment.setC_Order_ID(C_Order_ID);
- m_needSave = true;
+ m_mPayment.setC_Order_ID(C_Order_ID);
}
m_mPayment.setDateTrx(m_DateAcct);
m_mPayment.setDateAcct(m_DateAcct);
@@ -377,10 +395,25 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
m_mPayment.saveEx();
}
+ return true;
+ }
+
+ @Override
+ protected void afterSave(boolean success)
+ {
+ if (!success)
+ return;
+
/**********************
* Save Values to mTab
*/
- log.config("Saving changes");
+ //refresh
+ getGridTab().dataRefresh(false);
+ Object paymentIdValue = getGridTab().getValue("C_Payment_ID");
+ if (paymentIdValue != null && paymentIdValue instanceof Number)
+ m_C_Payment_ID = ((Number)paymentIdValue).intValue();
+ else
+ m_C_Payment_ID = 0;
// Set Payment
if (m_mPayment.getC_Payment_ID() != m_C_Payment_ID)
{
@@ -388,16 +421,32 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
getGridTab().setValue("C_Payment_ID", null);
else
getGridTab().setValue("C_Payment_ID", Integer.valueOf(m_mPayment.getC_Payment_ID()));
+ m_needSave = true;
}
-
- return true;
}
+ /**
+ *
+ * @param CCType credit card type
+ * @param CCNumber credit card number
+ * @param CCVV credit card ccv
+ * @param CCExp credit card expire date
+ * @return true if process successfully
+ */
public boolean processOnline(String CCType, String CCNumber, String CCVV, String CCExp)
{
return processOnline(CCType, CCNumber, CCVV, CCExp, 0);
}
+ /**
+ *
+ * @param CCType credit card type
+ * @param CCNumber credit card number
+ * @param CCVV credit card ccv
+ * @param CCExp credit card expire date
+ * @param C_PaymentProcessor_ID optional payment processor id. use the first configure if this is 0
+ * @return true if process successfully
+ */
public boolean processOnline(String CCType, String CCNumber, String CCVV, String CCExp, int C_PaymentProcessor_ID)
{
processMsg = null;
@@ -441,7 +490,6 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
else if (isCreditMemo)
{
mpt.setTrxType(MPayment.TRXTYPE_CreditPayment);
-// mpt.setOrig_TrxID(kPGOrderIDField.getValue());
}
else if (C_Invoice_ID != 0)
{
@@ -504,11 +552,23 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
return !error;
}
+ /**
+ *
+ * @param CCType
+ * @param PayAmt
+ * @return true if online payment processor have been configured for tender type credit card
+ */
public boolean isBankAccountProcessorExist(String CCType, BigDecimal PayAmt)
{
return isBankAccountProcessorExist(Env.getCtx(), MPayment.TENDERTYPE_CreditCard, CCType, Env.getAD_Client_ID(Env.getCtx()), m_C_Currency_ID, PayAmt, null);
}
+ /**
+ * Get online payment processor configuration for tender type credit card
+ * @param CCType
+ * @param PayAmt
+ * @return {@link MBankAccountProcessor}
+ */
public MBankAccountProcessor getBankAccountProcessor(String CCType, BigDecimal PayAmt)
{
return getBankAccountProcessor(Env.getCtx(), MPayment.TENDERTYPE_CreditCard, CCType, Env.getAD_Client_ID(Env.getCtx()), m_C_Currency_ID, PayAmt, null);
@@ -519,6 +579,17 @@ public abstract class PaymentFormCreditCard extends PaymentForm {
return m_mPayment.isApproved();
}
+ /**
+ *
+ * @param CCType credit card type
+ * @param CCNumber credit card number
+ * @param CCVV credit card ccv
+ * @param CCExp credit card expire
+ * @param C_BP_BankAccount_ID
+ * @param CustomerPaymentProfileID
+ * @return error message if credit card doesn't pass validation
+ * @throws IllegalArgumentException
+ */
public String validateCreditCard(String CCType, String CCNumber, String CCVV, String CCExp, int C_BP_BankAccount_ID, String CustomerPaymentProfileID) throws IllegalArgumentException {
String msg = null;
if (C_BP_BankAccount_ID != 0 || (CustomerPaymentProfileID != null && CustomerPaymentProfileID.length() > 0))
diff --git a/org.adempiere.ui/src/org/compiere/grid/PaymentFormDirect.java b/org.adempiere.ui/src/org/compiere/grid/PaymentFormDirect.java
index 7d5b6efff8..adfe265e88 100644
--- a/org.adempiere.ui/src/org/compiere/grid/PaymentFormDirect.java
+++ b/org.adempiere.ui/src/org/compiere/grid/PaymentFormDirect.java
@@ -26,6 +26,7 @@ import org.compiere.model.MBankAccountProcessor;
import org.compiere.model.MInvoice;
import org.compiere.model.MOrder;
import org.compiere.model.MPayment;
+import org.compiere.model.MRole;
import org.compiere.process.DocAction;
import org.compiere.util.DB;
import org.compiere.util.Env;
@@ -41,10 +42,16 @@ public abstract class PaymentFormDirect extends PaymentForm {
private String PAYMENTRULE;
/** Start Payment */
- public int m_C_Payment_ID = 0;
- public MPayment m_mPayment = null;
- public MPayment m_mPaymentOriginal = null;
+ protected int m_C_Payment_ID = 0;
+ protected MPayment m_mPayment = null;
+ protected MPayment m_mPaymentOriginal = null;
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ * @param isDebit
+ */
public PaymentFormDirect(int windowNo, GridTab mTab, boolean isDebit) {
super(windowNo, mTab);
PAYMENTRULE = isDebit ? MInvoice.PAYMENTRULE_DirectDebit : MInvoice.PAYMENTRULE_DirectDeposit;
@@ -71,23 +78,27 @@ public abstract class PaymentFormDirect extends PaymentForm {
}
}
- public ArrayList getBPBankAccountList() {
+ /**
+ *
+ * @return List of active bank accounts
+ */
+ public ArrayList getBankAccountList() {
ArrayList list = new ArrayList();
/**
- * Load Accounts
+ * Load Bank Accounts
*/
- String SQL = "SELECT a.C_BP_BankAccount_ID, NVL(b.Name, ' ')||'_'||NVL(a.AccountNo, ' ') AS Acct "
- + "FROM C_BP_BankAccount a"
- + " LEFT OUTER JOIN C_Bank b ON (a.C_Bank_ID=b.C_Bank_ID) "
- + "WHERE C_BPartner_ID=?"
- + "AND a.IsActive='Y' AND a.IsACH='Y'";
+ String SQL = MRole.getDefault().addAccessSQL(
+ "SELECT C_BankAccount_ID, ba.Name || ' ' || ba.AccountNo, ba.IsDefault "
+ + "FROM C_BankAccount ba"
+ + " INNER JOIN C_Bank b ON (ba.C_Bank_ID=b.C_Bank_ID) "
+ + "WHERE b.IsActive='Y' AND ba.IsActive='Y' ORDER BY ba.IsDefault DESC ",
+ "ba", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(SQL, null);
- pstmt.setInt(1, m_C_BPartner_ID);
rs = pstmt.executeQuery();
while (rs.next())
{
@@ -121,8 +132,17 @@ public abstract class PaymentFormDirect extends PaymentForm {
return ok;
}
- public String processMsg;
- public boolean save(int newC_BankAccount_ID, String routing, String number, String trxName)
+ protected String processMsg;
+
+ /**
+ *
+ * @param C_BankAccount_ID
+ * @param routing routing number
+ * @param number account number
+ * @param trxName
+ * @return true if save successfully
+ */
+ public boolean save(int C_BankAccount_ID, String routing, String number, String trxName)
{
// set trxname for class objects
if (m_mPayment != null)
@@ -211,13 +231,12 @@ public abstract class PaymentFormDirect extends PaymentForm {
*/
// Set Amount
m_mPayment.setAmount(m_C_Currency_ID, payAmount);
- m_mPayment.setBankACH(newC_BankAccount_ID, m_isSOTrx, PAYMENTRULE, routing, number);
+ m_mPayment.setBankACH(C_BankAccount_ID, m_isSOTrx, PAYMENTRULE, routing, number);
m_mPayment.setC_BPartner_ID(m_C_BPartner_ID);
m_mPayment.setC_Invoice_ID(C_Invoice_ID);
if (order != null)
{
- m_mPayment.setC_Order_ID(C_Order_ID);
- m_needSave = true;
+ m_mPayment.setC_Order_ID(C_Order_ID);
}
m_mPayment.setDateTrx(m_DateAcct);
m_mPayment.setDateAcct(m_DateAcct);
@@ -240,10 +259,25 @@ public abstract class PaymentFormDirect extends PaymentForm {
else
if (log.isLoggable(Level.FINE)) log.fine("NotDraft " + m_mPayment);
+ return true;
+ }
+
+ @Override
+ protected void afterSave(boolean success)
+ {
+ if (!success)
+ return;
+
/**********************
* Save Values to mTab
*/
- log.config("Saving changes");
+ //refresh
+ getGridTab().dataRefresh(false);
+ Object paymentIdValue = getGridTab().getValue("C_Payment_ID");
+ if (paymentIdValue != null && paymentIdValue instanceof Number)
+ m_C_Payment_ID = ((Number)paymentIdValue).intValue();
+ else
+ m_C_Payment_ID = 0;
// Set Payment
if (m_mPayment.getC_Payment_ID() != m_C_Payment_ID)
{
@@ -251,17 +285,24 @@ public abstract class PaymentFormDirect extends PaymentForm {
getGridTab().setValue("C_Payment_ID", null);
else
getGridTab().setValue("C_Payment_ID", Integer.valueOf(m_mPayment.getC_Payment_ID()));
+ m_needSave = true;
}
-
- return true;
}
+ /**
+ *
+ * @return true if online payment processor have been configured for direct* tender type
+ */
public boolean isBankAccountProcessorExist()
{
String tender = PAYMENTRULE.equals(MInvoice.PAYMENTRULE_DirectDebit) ? MPayment.TENDERTYPE_DirectDebit : MPayment.TENDERTYPE_DirectDeposit;
return isBankAccountProcessorExist(Env.getCtx(), tender, "", Env.getAD_Client_ID(Env.getCtx()), m_C_Currency_ID, m_Amount, null);
}
+ /**
+ * Get online payment processor configured for direct* tender type
+ * @return {@link MBankAccountProcessor}
+ */
public MBankAccountProcessor getBankAccountProcessor()
{
String tender = PAYMENTRULE.equals(MInvoice.PAYMENTRULE_DirectDebit) ? MPayment.TENDERTYPE_DirectDebit : MPayment.TENDERTYPE_DirectDeposit;
diff --git a/org.adempiere.ui/src/org/compiere/grid/PaymentFormMixedPOS.java b/org.adempiere.ui/src/org/compiere/grid/PaymentFormMixedPOS.java
index 3a4c3db2fc..e14d9fa6d6 100644
--- a/org.adempiere.ui/src/org/compiere/grid/PaymentFormMixedPOS.java
+++ b/org.adempiere.ui/src/org/compiere/grid/PaymentFormMixedPOS.java
@@ -23,6 +23,11 @@ import org.compiere.model.GridTab;
*/
public abstract class PaymentFormMixedPOS extends PaymentForm {
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public PaymentFormMixedPOS(int windowNo, GridTab mTab) {
super(windowNo, mTab);
}
diff --git a/org.adempiere.ui/src/org/compiere/grid/PaymentFormOnCredit.java b/org.adempiere.ui/src/org/compiere/grid/PaymentFormOnCredit.java
index 9bcd98a42b..96005f8075 100644
--- a/org.adempiere.ui/src/org/compiere/grid/PaymentFormOnCredit.java
+++ b/org.adempiere.ui/src/org/compiere/grid/PaymentFormOnCredit.java
@@ -33,8 +33,13 @@ import org.compiere.util.Env;
public abstract class PaymentFormOnCredit extends PaymentForm {
/** Start Payment Term */
- public int m_C_PaymentTerm_ID = 0;
+ protected int m_C_PaymentTerm_ID = 0;
+ /**
+ *
+ * @param windowNo
+ * @param mTab
+ */
public PaymentFormOnCredit(int windowNo, GridTab mTab) {
super(windowNo, mTab);
}
@@ -45,7 +50,12 @@ public abstract class PaymentFormOnCredit extends PaymentForm {
m_C_PaymentTerm_ID = ((Integer)getGridTab().getValue("C_PaymentTerm_ID")).intValue();
}
- public KeyNamePair selectedPaymentTerm = null;
+ protected KeyNamePair selectedPaymentTerm = null;
+
+ /**
+ * set selected payment term and return list of payment term records
+ * @return list of active payment terms
+ */
public ArrayList getPaymentTermList() {
selectedPaymentTerm = null;
ArrayList list = new ArrayList();
@@ -98,10 +108,22 @@ public abstract class PaymentFormOnCredit extends PaymentForm {
return list;
}
- public boolean save(int newC_PaymentTerm_ID)
+ /**
+ * Update payment term of parent grid tab, doesn't create payment record
+ * @param C_PaymentTerm_ID
+ * @return true if save successfully
+ */
+ public boolean save(int C_PaymentTerm_ID)
{
- if (newC_PaymentTerm_ID != m_C_PaymentTerm_ID)
- getGridTab().setValue("C_PaymentTerm_ID", Integer.valueOf(newC_PaymentTerm_ID));
+ if (C_PaymentTerm_ID != m_C_PaymentTerm_ID)
+ {
+ getGridTab().setValue("C_PaymentTerm_ID", Integer.valueOf(C_PaymentTerm_ID));
+ m_needSave = true;
+ }
return true;
}
+
+ @Override
+ protected void afterSave(boolean success) {
+ }
}
diff --git a/org.idempiere.test/src/org/idempiere/test/form/PaymentFormTest.java b/org.idempiere.test/src/org/idempiere/test/form/PaymentFormTest.java
new file mode 100644
index 0000000000..dd52854a7f
--- /dev/null
+++ b/org.idempiere.test/src/org/idempiere/test/form/PaymentFormTest.java
@@ -0,0 +1,538 @@
+/***********************************************************************
+ * This file is part of iDempiere ERP Open Source *
+ * http://www.idempiere.org *
+ * *
+ * Copyright (C) Contributors *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, *
+ * MA 02110-1301, USA. *
+ * *
+ * Contributors: *
+ * - hengsin *
+ **********************************************************************/
+package org.idempiere.test.form;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+
+import org.compiere.grid.PaymentFormCheck;
+import org.compiere.grid.PaymentFormCreditCard;
+import org.compiere.grid.PaymentFormDirect;
+import org.compiere.grid.PaymentFormOnCredit;
+import org.compiere.model.GridTab;
+import org.compiere.model.GridWindow;
+import org.compiere.model.MBPartner;
+import org.compiere.model.MBankAccountProcessor;
+import org.compiere.model.MOrder;
+import org.compiere.model.MOrderLine;
+import org.compiere.model.MPayment;
+import org.compiere.model.MPaymentProcessor;
+import org.compiere.model.MProduct;
+import org.compiere.model.MQuery;
+import org.compiere.model.PO;
+import org.compiere.model.SystemIDs;
+import org.compiere.process.DocAction;
+import org.compiere.process.ProcessInfo;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.TimeUtil;
+import org.compiere.util.Util;
+import org.compiere.wf.MWorkflow;
+import org.idempiere.test.AbstractTestCase;
+import org.idempiere.test.DictionaryIDs;
+import org.junit.jupiter.api.Test;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public class PaymentFormTest extends AbstractTestCase {
+
+ public PaymentFormTest() {
+ }
+
+ @Test
+ public void testPaymentFormCheck() {
+ MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
+ order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id));
+ order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard);
+ order.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder);
+ order.setDocStatus(DocAction.STATUS_Drafted);
+ order.setDocAction(DocAction.ACTION_Complete);
+ order.setPaymentRule(MOrder.PAYMENTRULE_Check);
+ Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
+ order.setDateOrdered(today);
+ order.setDatePromised(today);
+ order.saveEx();
+
+ MOrderLine line1 = new MOrderLine(order);
+ line1.setLine(10);
+ //Azalea Bush
+ line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id));
+ line1.setQty(new BigDecimal("1"));
+ line1.setDatePromised(today);
+ line1.saveEx();
+
+ ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
+ assertFalse(info.isError(), info.getSummary());
+ order.load(getTrxName());
+ assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
+
+ GridWindow gridWindow = GridWindow.get(Env.getCtx(), 1, SystemIDs.WINDOW_SALES_ORDER);
+ assertNotNull(gridWindow, "Failed to load grid window of Sales Order");
+ gridWindow.initTab(0);
+ GridTab gridTab = gridWindow.getTab(0);
+ MQuery query = new MQuery(MOrder.Table_Name);
+ query.addRestriction(MOrder.COLUMNNAME_C_Order_ID,"=", order.get_ID());
+ gridTab.setQuery(query);
+ gridTab.getTableModel().setImportingMode(false, getTrxName());
+ gridTab.query(false);
+
+ assertEquals(1, gridTab.getRowCount(), "Unexpected number of row retrieve from DB");
+ assertEquals(order.get_ID(), gridTab.getRecord_ID(), "Wrong record id");
+
+ PaymentFormCheckImpl form = new PaymentFormCheckImpl(0, gridTab);
+ form.loadData();
+ ArrayList bankAccounts = form.getBankAccountList();
+ assertTrue(bankAccounts.size() > 0, "Failed to retrieve list of active bank accounts");
+ assertTrue(form.getSelectedBankAccountId() > 0, "Failed to set default selected bank account");
+ form.routingNumber = "routingNumber1";
+ form.accountNumber = "customerAccountNumber1";
+ form.checkNumber = "checkNumber1";
+ form.paymentAmount = order.getGrandTotal();
+ boolean ok = form.saveChangesInTrx(getTrxName());
+ assertTrue(ok, "Save failed: " + form.getProcessMessage());
+ assertNotNull(form.getPayment(), "Payment not created");
+ assertTrue(form.getPayment().get_ID() > 0, "Payment not save successfully");
+ }
+
+ @Test
+ public void testPaymentFormDirect() {
+ MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
+ order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id));
+ order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard);
+ order.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder);
+ order.setDocStatus(DocAction.STATUS_Drafted);
+ order.setDocAction(DocAction.ACTION_Complete);
+ order.setPaymentRule(MOrder.PAYMENTRULE_DirectDebit);
+ Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
+ order.setDateOrdered(today);
+ order.setDatePromised(today);
+ order.saveEx();
+
+ MOrderLine line1 = new MOrderLine(order);
+ line1.setLine(10);
+ //Azalea Bush
+ line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id));
+ line1.setQty(new BigDecimal("1"));
+ line1.setDatePromised(today);
+ line1.saveEx();
+
+ ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
+ assertFalse(info.isError(), info.getSummary());
+ order.load(getTrxName());
+ assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
+
+ GridWindow gridWindow = GridWindow.get(Env.getCtx(), 1, SystemIDs.WINDOW_SALES_ORDER);
+ assertNotNull(gridWindow, "Failed to load grid window of Sales Order");
+ gridWindow.initTab(0);
+ GridTab gridTab = gridWindow.getTab(0);
+ MQuery query = new MQuery(MOrder.Table_Name);
+ query.addRestriction(MOrder.COLUMNNAME_C_Order_ID,"=", order.get_ID());
+ gridTab.setQuery(query);
+ gridTab.getTableModel().setImportingMode(false, getTrxName());
+ gridTab.query(false);
+
+ assertEquals(1, gridTab.getRowCount(), "Unexpected number of row retrieve from DB");
+ assertEquals(order.get_ID(), gridTab.getRecord_ID(), "Wrong record id");
+
+ PaymentFormDirectImpl form = new PaymentFormDirectImpl(0, gridTab, true);
+ try {
+ form.dynInit();
+ } catch (Exception e) {
+ fail(e);
+ }
+ ArrayList bankAccounts = form.getBankAccountList();
+ assertTrue(bankAccounts.size() > 0, "Failed to retrieve list of active bank accounts");
+ form.C_BankAccount_ID = bankAccounts.get(0).getKey();
+ form.routingNumber = "routingNumber1";
+ form.accountNumber = "customerAccountNumber1";
+ assertEquals(order.getGrandTotal().setScale(2, RoundingMode.HALF_EVEN), form.getPaymentAmount().setScale(2, RoundingMode.HALF_EVEN), "Wrong Payment Form Amount");
+ boolean ok = form.saveChangesInTrx(getTrxName());
+ assertTrue(ok, "Save failed: " + form.getProcessMessage());
+ assertNotNull(form.getPayment(), "Payment not created");
+ assertTrue(form.getPayment().get_ID() > 0, "Payment not save successfully");
+ assertEquals(order.getGrandTotal().setScale(2, RoundingMode.HALF_EVEN), form.getPayment().getPayAmt().setScale(2, RoundingMode.HALF_EVEN), "Wrong Payment Document Amount");
+ }
+
+ @Test
+ public void testPaymentFormOnCredit() {
+ MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
+ order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id));
+ order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard);
+ order.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder);
+ order.setDocStatus(DocAction.STATUS_Drafted);
+ order.setDocAction(DocAction.ACTION_Complete);
+ order.setPaymentRule(MOrder.PAYMENTRULE_DirectDebit);
+ order.setC_PaymentTerm_ID(DictionaryIDs.C_PaymentTerm.TWO_PERCENT_10_NET_30.id);
+ Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
+ order.setDateOrdered(today);
+ order.setDatePromised(today);
+ order.saveEx();
+
+ MOrderLine line1 = new MOrderLine(order);
+ line1.setLine(10);
+ //Azalea Bush
+ line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id));
+ line1.setQty(new BigDecimal("1"));
+ line1.setDatePromised(today);
+ line1.saveEx();
+
+ ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
+ assertFalse(info.isError(), info.getSummary());
+ order.load(getTrxName());
+ assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
+
+ GridWindow gridWindow = GridWindow.get(Env.getCtx(), 1, SystemIDs.WINDOW_SALES_ORDER);
+ assertNotNull(gridWindow, "Failed to load grid window of Sales Order");
+ gridWindow.initTab(0);
+ GridTab gridTab = gridWindow.getTab(0);
+ MQuery query = new MQuery(MOrder.Table_Name);
+ query.addRestriction(MOrder.COLUMNNAME_C_Order_ID,"=", order.get_ID());
+ gridTab.setQuery(query);
+ gridTab.getTableModel().setImportingMode(false, getTrxName());
+ gridTab.query(false);
+
+ assertEquals(1, gridTab.getRowCount(), "Unexpected number of row retrieve from DB");
+ assertEquals(order.get_ID(), gridTab.getRecord_ID(), "Wrong record id");
+
+ PaymentFormOnCreditImpl form = new PaymentFormOnCreditImpl(0, gridTab);
+ try {
+ form.dynInit();
+ } catch (Exception e) {
+ fail(e);
+ }
+ ArrayList terms = form.getPaymentTermList();
+ assertTrue(terms.size() > 0, "Failed to retrieve list of active payment terms");
+ for(KeyNamePair term : terms) {
+ if (term.getKey() == DictionaryIDs.C_PaymentTerm.NET_30.id) {
+ form.setPaymentTerm(term.getKey());
+ }
+ }
+ form.saveChangesInTrx(getTrxName());
+ assertEquals(((Number)gridTab.getValue("C_PaymentTerm_ID")).intValue(), form.getPaymentTerm(), "Wrong Payment Term");
+ }
+
+ @Test
+ public void testPaymentFormCreditCard() {
+ MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
+ order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id));
+ order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard);
+ order.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder);
+ order.setDocStatus(DocAction.STATUS_Drafted);
+ order.setDocAction(DocAction.ACTION_Complete);
+ order.setPaymentRule(MOrder.PAYMENTRULE_CreditCard);
+ Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
+ order.setDateOrdered(today);
+ order.setDatePromised(today);
+ order.saveEx();
+
+ MOrderLine line1 = new MOrderLine(order);
+ line1.setLine(10);
+ //Azalea Bush
+ line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id));
+ line1.setQty(new BigDecimal("1"));
+ line1.setDatePromised(today);
+ line1.saveEx();
+
+ ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
+ assertFalse(info.isError(), info.getSummary());
+ order.load(getTrxName());
+ assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
+
+ GridWindow gridWindow = GridWindow.get(Env.getCtx(), 1, SystemIDs.WINDOW_SALES_ORDER);
+ assertNotNull(gridWindow, "Failed to load grid window of Sales Order");
+ gridWindow.initTab(0);
+ GridTab gridTab = gridWindow.getTab(0);
+ MQuery query = new MQuery(MOrder.Table_Name);
+ query.addRestriction(MOrder.COLUMNNAME_C_Order_ID,"=", order.get_ID());
+ gridTab.setQuery(query);
+ gridTab.getTableModel().setImportingMode(false, getTrxName());
+ gridTab.query(false);
+
+ assertEquals(1, gridTab.getRowCount(), "Unexpected number of row retrieve from DB");
+ assertEquals(order.get_ID(), gridTab.getRecord_ID(), "Wrong record id");
+
+
+ PaymentFormCreditCardImpl form = new PaymentFormCreditCardImpl(0, gridTab);
+ try {
+ form.dynInit();
+ } catch (Exception e) {
+ fail(e);
+ }
+ assertEquals(order.getGrandTotal().setScale(2, RoundingMode.HALF_EVEN), form.getPaymentAmount().setScale(2, RoundingMode.HALF_EVEN), "Wrong Payment Form Amount");
+ form.setCCType(MPayment.CREDITCARDTYPE_MasterCard);
+ form.CCNumber = "5555555555554444";
+ form.CCVV = "123";
+ form.CCExp = "1199";
+
+ MBankAccountProcessor[] processors = MBankAccountProcessor.find(Env.getCtx(), MPayment.TENDERTYPE_CreditCard, form.getCCType(), getAD_Client_ID(), order.getC_Currency_ID(), form.getPaymentAmount(), getTrxName());
+ assertTrue(processors.length > 0, "Fail to retrieve default bank account processor for credit card");
+ MPaymentProcessor mpp = null;
+ String payProcessorClass = null;
+ for(MBankAccountProcessor processor : processors) {
+ if (processor.accepts(MPayment.TENDERTYPE_CreditCard, form.getCCType())) {
+ mpp = new MPaymentProcessor(Env.getCtx(), processor.getC_PaymentProcessor_ID(), null);
+ break;
+ }
+ }
+
+ assertNotNull(mpp, "Failed to find default payment processor for credit card");
+ try {
+ payProcessorClass = mpp.getPayProcessorClass();
+ mpp.setPayProcessorClass("org.compiere.model.PP_Dummy");
+ try {
+ PO.setCrossTenantSafe();
+ mpp.saveEx();
+ } finally {
+ PO.clearCrossTenantSafe();
+ }
+ boolean ok = form.saveChangesInTrx(getTrxName());
+ assertTrue(ok, "Save failed: " + form.getProcessMessage());
+ assertNotNull(form.getPayment(), "Payment not created");
+ assertTrue(form.getPayment().get_ID() > 0, "Payment not save successfully");
+ assertEquals(order.getGrandTotal().setScale(2, RoundingMode.HALF_EVEN), form.getPayment().getPayAmt().setScale(2, RoundingMode.HALF_EVEN), "Wrong Payment Document Amount");
+ } finally {
+ mpp.setPayProcessorClass(payProcessorClass);
+ try {
+ PO.setCrossTenantSafe();
+ mpp.saveEx();
+ } finally {
+ PO.clearCrossTenantSafe();
+ }
+ }
+ }
+
+ private class PaymentFormCheckImpl extends PaymentFormCheck {
+
+ private String routingNumber;
+ private String accountNumber;
+ private String checkNumber;
+ private BigDecimal paymentAmount;
+
+ public PaymentFormCheckImpl(int windowNo, GridTab mTab) {
+ super(windowNo, mTab);
+ try {
+ dynInit();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean checkMandatory() {
+ return true;
+ }
+
+ public int getSelectedBankAccountId() {
+ if (selectedBankAccount != null) {
+ return selectedBankAccount.getKey();
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean saveChangesInTrx(String trxName) {
+ return save(getSelectedBankAccountId(), routingNumber, accountNumber,
+ checkNumber, paymentAmount, trxName);
+ }
+
+ public String getProcessMessage() {
+ return processMsg;
+ }
+
+ public MPayment getPayment() {
+ return m_mPayment;
+ }
+
+ @Override
+ public void showWindow() {
+ }
+
+ @Override
+ public void closeWindow() {
+ }
+
+ @Override
+ public Object getWindow() {
+ return null;
+ }
+
+ }
+
+ private class PaymentFormDirectImpl extends PaymentFormDirect {
+
+ private String routingNumber;
+ private String accountNumber;
+ private int C_BankAccount_ID;
+
+ public PaymentFormDirectImpl(int windowNo, GridTab mTab, boolean isDebit) {
+ super(windowNo, mTab, isDebit);
+ }
+
+ @Override
+ public boolean checkMandatory() {
+ return true;
+ }
+
+ @Override
+ public boolean saveChangesInTrx(String trxName) {
+ return save(C_BankAccount_ID, routingNumber, accountNumber, trxName);
+ }
+
+ @Override
+ public void showWindow() {
+ }
+
+ @Override
+ public void closeWindow() {
+ }
+
+ @Override
+ public Object getWindow() {
+ return null;
+ }
+
+ public BigDecimal getPaymentAmount() {
+ return m_Amount;
+ }
+
+ public String getProcessMessage() {
+ return processMsg;
+ }
+
+ public MPayment getPayment() {
+ return m_mPayment;
+ }
+ }
+
+ private class PaymentFormOnCreditImpl extends PaymentFormOnCredit {
+
+ public PaymentFormOnCreditImpl(int windowNo, GridTab mTab) {
+ super(windowNo, mTab);
+ }
+
+ public int getPaymentTerm() {
+ return m_C_PaymentTerm_ID;
+ }
+
+ public void setPaymentTerm(int key) {
+ m_C_PaymentTerm_ID = key;
+ }
+
+ @Override
+ public boolean checkMandatory() {
+ return true;
+ }
+
+ @Override
+ public boolean saveChangesInTrx(String trxName) {
+ return save(m_C_PaymentTerm_ID);
+ }
+
+ @Override
+ public void showWindow() {
+ }
+
+ @Override
+ public void closeWindow() {
+ }
+
+ @Override
+ public Object getWindow() {
+ return null;
+ }
+ }
+
+ private class PaymentFormCreditCardImpl extends PaymentFormCreditCard {
+
+ private String CCNumber;
+ private String CCExp;
+ private String CCVV;
+
+ public PaymentFormCreditCardImpl(int windowNo, GridTab mTab) {
+ super(windowNo, mTab);
+ }
+
+ public MPayment getPayment() {
+ return m_mPayment;
+ }
+
+ public String getProcessMessage() {
+ return processMsg;
+ }
+
+ public BigDecimal getPaymentAmount() {
+ return m_Amount;
+ }
+
+ public void setCCType(String cctype) {
+ m_CCType = cctype;
+ }
+
+ public String getCCType() {
+ return m_CCType;
+ }
+
+ @Override
+ public boolean checkMandatory() {
+ return true;
+ }
+
+ @Override
+ public boolean saveChangesInTrx(String trxName) {
+ String msg = validateCreditCard(m_CCType, CCNumber, CCVV, CCExp, 0, null);
+ if (!Util.isEmpty(msg, true)) {
+ processMsg = msg;
+ return false;
+ }
+ if (!processOnline(m_CCType, CCNumber, CCVV, CCExp))
+ return false;
+ return save(m_CCType, CCNumber, CCExp, m_Amount, trxName);
+ }
+
+ @Override
+ public void showWindow() {
+ }
+
+ @Override
+ public void closeWindow() {
+ }
+
+ @Override
+ public Object getWindow() {
+ return null;
+ }
+ }
+}