/*********************************************************************** * 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 java.math.BigDecimal; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import java.util.Vector; import org.compiere.apps.form.FactReconcile; import org.compiere.minigrid.MiniTableImpl; import org.compiere.model.MBankStatement; import org.compiere.model.MBankStatementLine; import org.compiere.model.MClientInfo; import org.compiere.model.MFactAcct; import org.compiere.model.MFactReconciliation; import org.compiere.model.MPayment; import org.compiere.model.Query; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.process.ProcessInfo; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; 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 FactReconcileFormTest extends AbstractTestCase { public FactReconcileFormTest() { } @Test public void testReconcileForm() { MPayment payment = new MPayment(Env.getCtx(), 0, getTrxName()); payment.setC_BankAccount_ID(DictionaryIDs.C_BankAccount.ACCOUNT_1234.id); payment.setIsReceipt(true); payment.setPayAmt(new BigDecimal("9.99")); payment.setC_BPartner_ID(DictionaryIDs.C_BPartner.SEED_FARM.id); payment.setC_DocType_ID(true); payment.setC_Currency_ID(DictionaryIDs.C_Currency.USD.id); payment.saveEx(); ProcessInfo pi = MWorkflow.runDocumentActionWorkflow(payment, DocAction.ACTION_Complete); assertFalse(pi.isError(), pi.getSummary()); payment.load(getTrxName()); if (!payment.isPosted()) { String error = DocumentEngine.postImmediate(Env.getCtx(), payment.getAD_Client_ID(), MPayment.Table_ID, payment.get_ID(), true, getTrxName()); assertTrue(Util.isEmpty(error, true), error); } Query query = new Query(Env.getCtx(), MFactAcct.Table_Name, "AD_Table_ID=? AND Record_ID=? AND Account_ID=? AND C_AcctSchema_ID=?", getTrxName()); MFactAcct paymentFact = query.setParameters(MPayment.Table_ID, payment.get_ID(), DictionaryIDs.C_ElementValue.CHECKING_IN_TRANSFER.id, MClientInfo.get(getAD_Client_ID()).getC_AcctSchema1_ID()).first(); assertNotNull(paymentFact, "Faild to retrieve MFactAcct checking in transfer record for payment"); MBankStatement stmt = new MBankStatement(Env.getCtx(), 0, getTrxName()); stmt.setC_BankAccount_ID(DictionaryIDs.C_BankAccount.ACCOUNT_1234.id); stmt.setName("testReconcileForm"); stmt.setDateAcct(payment.getDateAcct()); stmt.saveEx(); MBankStatementLine line = new MBankStatementLine(stmt); line.setC_Payment_ID(payment.get_ID()); line.setStmtAmt(payment.getPayAmt()); line.setTrxAmt(line.getStmtAmt()); line.setC_Currency_ID(payment.getC_Currency_ID()); line.saveEx(); pi = MWorkflow.runDocumentActionWorkflow(stmt, DocAction.ACTION_Complete); assertFalse(pi.isError(), pi.getSummary()); stmt.load(getTrxName()); if (!stmt.isPosted()) { String error = DocumentEngine.postImmediate(Env.getCtx(), stmt.getAD_Client_ID(), MBankStatement.Table_ID, stmt.get_ID(), true, getTrxName()); assertTrue(Util.isEmpty(error, true), error); } MFactAcct statementFact = query.setParameters(MBankStatement.Table_ID, stmt.get_ID(), DictionaryIDs.C_ElementValue.CHECKING_IN_TRANSFER.id, MClientInfo.get(getAD_Client_ID()).getC_AcctSchema1_ID()).first(); assertNotNull(statementFact, "Faild to retrieve MFactAcct checking in transfer record for bank statement"); FactReconcileImpl fri = new FactReconcileImpl(); Vector accounts = fri.getAccount(); assertTrue(accounts.size() > 0, "Failed to retrieve account elements"); KeyNamePair checkingInTransfer = null; for(KeyNamePair account : accounts) { if (account.getKey() == DictionaryIDs.C_ElementValue.CHECKING_IN_TRANSFER.id) { checkingInTransfer = account; break; } } assertNotNull(checkingInTransfer, "Can't find Checking In Transfer account element"); //load not reconciled fact records fri.setParameters(payment.getC_BPartner_ID(), payment.getDateAcct(), checkingInTransfer, false); fri.loadData(); assertTrue(fri.miniTable.getRowCount() >= 2, "Failed to load not reconciled fact account records"); for(int i = 0; i < fri.miniTable.getRowCount(); i++) { KeyNamePair knp = (KeyNamePair) fri.miniTable.getValueAt(i, fri.getIdColumnIndex()); if (knp.getKey() == paymentFact.get_ID() || knp.getKey() == statementFact.get_ID()) { fri.miniTable.setValueAt(Boolean.TRUE, i, fri.getSelectedColumnIndex()); } } //select and generate reconciliation fri.calculateSelection(fri.miniTable); assertEquals(2, fri.getSelectedCount(), "Failed to locate not reconciled payment and bank statement fact records in mini table"); List generated = new ArrayList<>(); fri.generate(fri.miniTable, generated); assertEquals(2, generated.size(), "Failed to generate " + MFactReconciliation.Table_Name + " records"); //reload not reconciled fact records after generate fri.setParameters(payment.getC_BPartner_ID(), payment.getDateAcct(), checkingInTransfer, false); fri.loadData(); for(int i = 0; i < fri.miniTable.getRowCount(); i++) { KeyNamePair knp = (KeyNamePair) fri.miniTable.getValueAt(i, fri.getIdColumnIndex()); if (knp.getKey() == paymentFact.get_ID() || knp.getKey() == statementFact.get_ID()) { fri.miniTable.setValueAt(Boolean.TRUE, i, fri.getSelectedColumnIndex()); } } //should select 0 after generate fri.calculateSelection(fri.miniTable); assertEquals(0, fri.getSelectedCount(), "Payment and bank statement line not reconcilled"); //load reconciled fact records fri.setParameters(payment.getC_BPartner_ID(), payment.getDateAcct(), checkingInTransfer, true); fri.loadData(); for(int i = 0; i < fri.miniTable.getRowCount(); i++) { KeyNamePair knp = (KeyNamePair) fri.miniTable.getValueAt(i, fri.getIdColumnIndex()); if (knp.getKey() == paymentFact.get_ID() || knp.getKey() == statementFact.get_ID()) { fri.miniTable.setValueAt(Boolean.TRUE, i, fri.getSelectedColumnIndex()); } } fri.calculateSelection(fri.miniTable); assertEquals(2, fri.getSelectedCount(), "Failed to locate reconcilled payment and statement fact record in mini table"); //select and reset List reseted = new ArrayList<>(); fri.reset(fri.miniTable, reseted); assertEquals(2, reseted.size(), "Failed to reset " + MFactReconciliation.Table_Name + " records"); //reload not reconciled fact records after reset fri.setParameters(payment.getC_BPartner_ID(), payment.getDateAcct(), checkingInTransfer, false); fri.loadData(); assertTrue(fri.miniTable.getRowCount() >= 2, "Failed to load fact account records"); for(int i = 0; i < fri.miniTable.getRowCount(); i++) { KeyNamePair knp = (KeyNamePair) fri.miniTable.getValueAt(i, fri.getIdColumnIndex()); if (knp.getKey() == paymentFact.get_ID() || knp.getKey() == statementFact.get_ID()) { fri.miniTable.setValueAt(Boolean.TRUE, i, fri.getSelectedColumnIndex()); } } //should select 2 again after reset fri.calculateSelection(fri.miniTable); assertEquals(2, fri.getSelectedCount(), "Failed to locate payment and statement fact record in mini table"); } private class FactReconcileImpl extends FactReconcile { protected MiniTableImpl miniTable = null; protected FactReconcileImpl() { m_trxName = getTrxName(); m_C_AcctSchema_ID = MClientInfo.get(getAD_Client_ID()).getC_AcctSchema1_ID(); m_AD_Client_ID = Env.getAD_Client_ID(Env.getCtx()); } public void loadData() { miniTable = new MiniTableImpl(); Vector headers = getColumnNames(); for(String header : headers) { miniTable.addColumn(header); } setColumnClass(miniTable); Vector> datas = super.getData(); for (Vector data : datas) { int row = miniTable.getRowCount(); miniTable.setRowCount(row+1); for(int column = 0; column < data.size(); column++) { Object value = data.get(column); miniTable.setValueAt(value, row, column); } } } protected void setParameters(int C_BPartner_ID, Timestamp dateAcct, KeyNamePair checkingInTransfer, boolean isReconciled) { m_C_BPartner_ID = C_BPartner_ID; m_DateAcct = dateAcct; m_Account_ID = checkingInTransfer.getKey(); m_isReconciled = isReconciled; } protected Vector getAccount() { return super.getAccount(); } protected int getSelectedCount() { return m_noSelected; } protected int getIdColumnIndex() { return idColIndex; } protected int getSelectedColumnIndex() { return selectedColIndex; } } }