IDEMPIERE-5447 Add unit test for Merge form (#1523)
* IDEMPIERE-5447 Add unit test for Merge form * IDEMPIERE-5447 Add unit test for Merge form - Merge patch from Carlos
This commit is contained in:
parent
62bbb83cb2
commit
e6eb86a1c5
|
@ -0,0 +1,10 @@
|
|||
-- IDEMPIERE-5447 Add unit test for Merge form
|
||||
SELECT register_migration_script('202210111536_IDEMPIERE-5447.sql') FROM dual;
|
||||
|
||||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- Oct 11, 2022, 3:36:36 PM CEST
|
||||
UPDATE AD_Menu SET PredefinedContextVariables='IgnoreIsSOTrxInBPInfo=Y',Updated=TO_TIMESTAMP('2022-10-11 15:36:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=397
|
||||
;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
-- IDEMPIERE-5447 Add unit test for Merge form
|
||||
SELECT register_migration_script('202210111536_IDEMPIERE-5447.sql') FROM dual;
|
||||
|
||||
-- Oct 11, 2022, 3:36:36 PM CEST
|
||||
UPDATE AD_Menu SET PredefinedContextVariables='IgnoreIsSOTrxInBPInfo=Y',Updated=TO_TIMESTAMP('2022-10-11 15:36:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=397
|
||||
;
|
||||
|
|
@ -625,7 +625,7 @@ public class MBPartner extends X_C_BPartner implements ImmutablePOSupport
|
|||
} // getAD_OrgBP_ID_Int
|
||||
|
||||
/**
|
||||
* Get Primary C_BPartner_Location_ID
|
||||
* Get Primary C_BPartner_Location_ID (BillTo or First)
|
||||
* @return C_BPartner_Location_ID
|
||||
*/
|
||||
public int getPrimaryC_BPartner_Location_ID()
|
||||
|
@ -651,7 +651,7 @@ public class MBPartner extends X_C_BPartner implements ImmutablePOSupport
|
|||
} // getPrimaryC_BPartner_Location_ID
|
||||
|
||||
/**
|
||||
* Get Primary C_BPartner_Location
|
||||
* Get Primary C_BPartner_Location (BillTo or First)
|
||||
* @return C_BPartner_Location
|
||||
*/
|
||||
public MBPartnerLocation getPrimaryC_BPartner_Location()
|
||||
|
|
|
@ -235,8 +235,9 @@ public class WMerge extends Merge implements IFormController, EventListener<Even
|
|||
to_Info = m_to[i].getDisplay ();
|
||||
}
|
||||
}
|
||||
} // get first merge pair
|
||||
}
|
||||
|
||||
//process first merge pair, ignore the rest
|
||||
if (from_ID == 0 || from_ID == to_ID)
|
||||
return;
|
||||
|
||||
|
@ -253,8 +254,6 @@ public class WMerge extends Merge implements IFormController, EventListener<Even
|
|||
{
|
||||
if (result)
|
||||
{
|
||||
updateDeleteTable(columnNameRef);
|
||||
|
||||
Clients.showBusy("");
|
||||
runnable = new MergeRunnable(columnNameRef, fromIdRef, toIdRef);
|
||||
Clients.response(new AuEcho(form, "runProcess", null));
|
||||
|
@ -264,7 +263,7 @@ public class WMerge extends Merge implements IFormController, EventListener<Even
|
|||
});
|
||||
} // actionPerformed
|
||||
|
||||
class MergeRunnable implements Runnable {
|
||||
private class MergeRunnable implements Runnable {
|
||||
private int to_ID;
|
||||
private int from_ID;
|
||||
private String columnName;
|
||||
|
@ -285,11 +284,17 @@ public class WMerge extends Merge implements IFormController, EventListener<Even
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* execute merge, call from echo event
|
||||
*/
|
||||
public void runProcess()
|
||||
{
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up, call form echo event
|
||||
*/
|
||||
public void onAfterProcess()
|
||||
{
|
||||
if (m_success)
|
||||
|
@ -306,8 +311,9 @@ public class WMerge extends Merge implements IFormController, EventListener<Even
|
|||
dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ADForm getForm()
|
||||
{
|
||||
return form;
|
||||
}
|
||||
} // VMerge
|
||||
}
|
||||
|
|
|
@ -29,16 +29,14 @@ import org.compiere.util.Trx;
|
|||
public class Merge
|
||||
{
|
||||
/** Window No */
|
||||
public int m_WindowNo = 0;
|
||||
protected int m_WindowNo = 0;
|
||||
/** Total Count */
|
||||
public int m_totalCount = 0;
|
||||
protected int m_totalCount = 0;
|
||||
/** Error Log */
|
||||
public StringBuffer m_errorLog = new StringBuffer();
|
||||
/** Connection */
|
||||
//private Connection m_con = null;
|
||||
protected StringBuffer m_errorLog = new StringBuffer();
|
||||
private Trx m_trx = null;
|
||||
/** Logger */
|
||||
public static final CLogger log = CLogger.getCLogger(Merge.class);
|
||||
protected static final CLogger log = CLogger.getCLogger(Merge.class);
|
||||
|
||||
public static String AD_ORG_ID = "AD_Org_ID";
|
||||
public static String C_BPARTNER_ID = "C_BPartner_ID";
|
||||
|
@ -46,26 +44,30 @@ public class Merge
|
|||
public static String M_PRODUCT_ID = "M_Product_ID";
|
||||
|
||||
/** Tables to delete (not update) for AD_Org */
|
||||
public static String[] s_delete_Org = new String[]
|
||||
protected static String[] s_delete_Org = new String[]
|
||||
{"AD_OrgInfo", "AD_Role_OrgAccess"};
|
||||
/** Tables to delete (not update) for AD_User */
|
||||
public static String[] s_delete_User = new String[]
|
||||
protected static String[] s_delete_User = new String[]
|
||||
{"AD_User_Roles"};
|
||||
/** Tables to delete (not update) for C_BPartner */
|
||||
public static String[] s_delete_BPartner = new String[]
|
||||
protected static String[] s_delete_BPartner = new String[]
|
||||
{"C_BP_Employee_Acct", "C_BP_Vendor_Acct", "C_BP_Customer_Acct",
|
||||
"T_Aging"};
|
||||
/** Tables to delete (not update) for M_Product */
|
||||
public static String[] s_delete_Product = new String[]
|
||||
protected static String[] s_delete_Product = new String[]
|
||||
{"M_Product_PO", "M_Replenish", "T_Replenish",
|
||||
"M_ProductPrice",
|
||||
"M_Cost", // teo_sarca [ 1704554 ]
|
||||
"M_Product_Trl", "M_Product_Acct"}; // M_Storage
|
||||
"M_Product_Trl", "M_Product_Acct"};
|
||||
|
||||
public String[] m_columnName = null;
|
||||
public String[] m_deleteTables = null;
|
||||
protected String[] m_columnName = null;
|
||||
protected String[] m_deleteTables = null;
|
||||
|
||||
public void updateDeleteTable(String columnName)
|
||||
/**
|
||||
* Determine the list of tables to delete records from columnName
|
||||
* @param columnName
|
||||
*/
|
||||
protected void updateDeleteTable(String columnName)
|
||||
{
|
||||
// ** Update **
|
||||
if (columnName.equals(AD_ORG_ID))
|
||||
|
@ -81,7 +83,7 @@ public class Merge
|
|||
|
||||
/**
|
||||
* Merge.
|
||||
* @param ColumnName column
|
||||
* @param ColumnName ID column (M_Product_ID, AD_Org_ID, C_BPartner_ID or AD_User_ID)
|
||||
* @param from_ID from
|
||||
* @param to_ID to
|
||||
* @return true if merged
|
||||
|
@ -92,6 +94,8 @@ public class Merge
|
|||
if (log.isLoggable(Level.CONFIG)) log.config(ColumnName
|
||||
+ " - From=" + from_ID + ",To=" + to_ID);
|
||||
|
||||
updateDeleteTable(ColumnName);
|
||||
|
||||
boolean success = true;
|
||||
m_totalCount = 0;
|
||||
m_errorLog = new StringBuffer();
|
||||
|
@ -140,7 +144,7 @@ public class Merge
|
|||
{
|
||||
sql = "DELETE FROM " + TableName + " WHERE " + ColumnName + "=" + from_ID;
|
||||
|
||||
if ( DB.executeUpdate(sql, m_trx.getTrxName()) < 0 )
|
||||
if ( DB.executeUpdateEx(sql, m_trx.getTrxName()) < 0 )
|
||||
{
|
||||
m_errorLog.append(Env.NL).append("DELETE FROM ").append(TableName)
|
||||
.append(" - ");
|
||||
|
@ -184,7 +188,7 @@ public class Merge
|
|||
* @param to_ID to
|
||||
* @return -1 for error or number of changes
|
||||
*/
|
||||
public int mergeTable (String TableName, String ColumnName, int from_ID, int to_ID)
|
||||
protected int mergeTable (String TableName, String ColumnName, int from_ID, int to_ID)
|
||||
{
|
||||
if (log.isLoggable(Level.FINE)) log.fine(TableName + "." + ColumnName + " - From=" + from_ID + ",To=" + to_ID);
|
||||
String sql = "UPDATE " + TableName
|
||||
|
@ -208,7 +212,7 @@ public class Merge
|
|||
+ " AND " + X_M_Cost.COLUMNNAME_CumulatedQty + "=0";
|
||||
}
|
||||
|
||||
int count = DB.executeUpdate(sql, m_trx.getTrxName());
|
||||
int count = DB.executeUpdateEx(sql, m_trx.getTrxName());
|
||||
if (count < 0)
|
||||
{
|
||||
count = -1;
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
/***********************************************************************
|
||||
* 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.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.compiere.apps.form.Merge;
|
||||
import org.compiere.model.MBPartner;
|
||||
import org.compiere.model.MBPartnerLocation;
|
||||
import org.compiere.model.MLocation;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MPriceList;
|
||||
import org.compiere.model.MPriceListVersion;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MProductPrice;
|
||||
import org.compiere.model.MUser;
|
||||
import org.compiere.model.MUserDefWin;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.SystemIDs;
|
||||
import org.compiere.util.Env;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.idempiere.test.DictionaryIDs;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class MergeFormTest extends AbstractTestCase {
|
||||
|
||||
public MergeFormTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeProduct() {
|
||||
|
||||
MProduct p1 = null;
|
||||
MProduct p2 = null;
|
||||
MProductPrice pp1 = null;
|
||||
MProductPrice pp2 = null;
|
||||
MOrder order1 = null;
|
||||
MOrderLine ol1 = null;
|
||||
MOrder order2 = null;
|
||||
MOrderLine ol2 = null;
|
||||
|
||||
try {
|
||||
|
||||
p1 = new MProduct(Env.getCtx(), 0, null);
|
||||
p1.setName("testMergeProduct1");
|
||||
p1.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.STANDARD.id);
|
||||
p1.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
p1.setIsStocked(false);
|
||||
p1.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
p1.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
p1.saveEx();
|
||||
|
||||
p2 = new MProduct(Env.getCtx(), 0, null);
|
||||
p2.setName("testMergeProduct2");
|
||||
p2.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.STANDARD.id);
|
||||
p2.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||
p2.setIsStocked(false);
|
||||
p2.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id);
|
||||
p2.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id);
|
||||
p2.saveEx();
|
||||
|
||||
MPriceList pl = MPriceList.get(DictionaryIDs.M_PriceList.STANDARD.id);
|
||||
MPriceListVersion plv = pl.getPriceListVersion(null);
|
||||
pp1 = new MProductPrice(Env.getCtx(), 0, null);
|
||||
pp1.setM_PriceList_Version_ID(plv.get_ID());
|
||||
pp1.setM_Product_ID(p1.getM_Product_ID());
|
||||
pp1.setPrices(new BigDecimal("1"), new BigDecimal("1"), new BigDecimal("1"));
|
||||
pp1.saveEx();
|
||||
|
||||
pp2 = new MProductPrice(Env.getCtx(), 0, null);
|
||||
pp2.setM_PriceList_Version_ID(plv.get_ID());
|
||||
pp2.setM_Product_ID(p2.getM_Product_ID());
|
||||
pp2.setPrices(new BigDecimal("1"), new BigDecimal("1"), new BigDecimal("1"));
|
||||
pp2.saveEx();
|
||||
|
||||
order1 = new MOrder(Env.getCtx(), 0, null);
|
||||
order1.setIsSOTrx(true);
|
||||
order1.setC_DocTypeTarget_ID();
|
||||
order1.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id));
|
||||
order1.saveEx();
|
||||
|
||||
ol1 = new MOrderLine(order1);
|
||||
ol1.setM_Product_ID(p1.get_ID());
|
||||
ol1.setQty(new BigDecimal("1"));
|
||||
ol1.saveEx();
|
||||
|
||||
order2 = new MOrder(Env.getCtx(), 0, null);
|
||||
order2.setIsSOTrx(true);
|
||||
order2.setC_DocTypeTarget_ID();
|
||||
order2.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id));
|
||||
order2.saveEx();
|
||||
|
||||
ol2 = new MOrderLine(order1);
|
||||
ol2.setM_Product_ID(p2.get_ID());
|
||||
ol2.setQty(new BigDecimal("1"));
|
||||
ol2.saveEx();
|
||||
|
||||
Merge merge = new Merge();
|
||||
boolean ok = merge.merge(Merge.M_PRODUCT_ID, p1.get_ID(), p2.get_ID());
|
||||
assertTrue(ok, "Merge fail");
|
||||
ol1.load(null);
|
||||
assertEquals(p2.get_ID(), ol1.getM_Product_ID(), "Unexpected order line M_Product_ID after merge");
|
||||
ol2.load(null);
|
||||
assertEquals(p2.get_ID(), ol2.getM_Product_ID(), "Unexpected order line M_Product_ID after merge");
|
||||
pp1.load(null);
|
||||
assertEquals(0, pp1.get_ID(), "Product Price not deleted after merge");
|
||||
p1.load(null);
|
||||
assertEquals(0, p1.get_ID(), "Product not deleted after merge");
|
||||
} finally {
|
||||
if (pp1 != null && pp1.get_ID() > 0)
|
||||
pp1.deleteEx(true);
|
||||
if (pp2 != null && pp2.get_ID() > 0)
|
||||
pp2.deleteEx(true);
|
||||
if (ol1 != null && ol1.get_ID() > 0)
|
||||
ol1.deleteEx(true);
|
||||
if (ol2 != null && ol2.get_ID() > 0)
|
||||
ol2.deleteEx(true);
|
||||
if (order1 != null && order1.get_ID() > 0)
|
||||
order1.deleteEx(true);
|
||||
if (order2 != null && order2.get_ID() > 0)
|
||||
order2.deleteEx(true);
|
||||
if (p1 != null && p1.get_ID() > 0)
|
||||
p1.deleteEx(true);
|
||||
if (p2 != null && p2.get_ID() > 0)
|
||||
p2.deleteEx(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeBPartner() {
|
||||
MBPartner bp1 = null;
|
||||
MBPartner bp2 = null;
|
||||
MOrder o1 = null;
|
||||
MOrder o2 = null;
|
||||
try {
|
||||
MBPartner jb = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id);
|
||||
MBPartnerLocation bpl = jb.getPrimaryC_BPartner_Location();
|
||||
MLocation loc = new MLocation(Env.getCtx(), bpl.getC_Location_ID(), null);
|
||||
|
||||
bp1 = new MBPartner(Env.getCtx(), 0, null);
|
||||
bp1.setName("testMergeBPartner1");
|
||||
bp1.setIsCustomer(true);
|
||||
bp1.setC_BP_Group_ID(jb.getC_BP_Group_ID());
|
||||
bp1.saveEx();
|
||||
MLocation loc1 = new MLocation(Env.getCtx(), 0, null);
|
||||
PO.copyValues(loc, loc1);
|
||||
loc1.saveEx();
|
||||
MBPartnerLocation bpl1 = new MBPartnerLocation(bp1);
|
||||
bpl1.setC_Location_ID(loc1.get_ID());
|
||||
bpl1.setIsShipTo(true);
|
||||
bpl1.setIsBillTo(true);
|
||||
bpl1.saveEx();
|
||||
|
||||
bp2 = new MBPartner(Env.getCtx(), 0, null);
|
||||
bp2.setName("testMergeBPartner2");
|
||||
bp2.setIsCustomer(true);
|
||||
bp2.setC_BP_Group_ID(bp1.getC_BP_Group_ID());
|
||||
bp2.saveEx();
|
||||
MLocation loc2 = new MLocation(Env.getCtx(), 0, null);
|
||||
PO.copyValues(loc, loc2);
|
||||
loc2.saveEx();
|
||||
MBPartnerLocation bpl2 = new MBPartnerLocation(bp2);
|
||||
bpl2.setC_Location_ID(loc2.get_ID());
|
||||
bpl2.setIsShipTo(true);
|
||||
bpl2.setIsBillTo(true);
|
||||
bpl2.saveEx();
|
||||
|
||||
o1 = new MOrder(Env.getCtx(), 0, null);
|
||||
o1.setIsSOTrx(true);
|
||||
o1.setC_DocTypeTarget_ID();
|
||||
o1.setBPartner(bp1);
|
||||
o1.saveEx();
|
||||
|
||||
o2 = new MOrder(Env.getCtx(), 0, null);
|
||||
o2.setIsSOTrx(true);
|
||||
o2.setC_DocTypeTarget_ID();
|
||||
o2.setBPartner(bp2);
|
||||
o2.saveEx();
|
||||
|
||||
Merge merge = new Merge();
|
||||
boolean ok = merge.merge(Merge.C_BPARTNER_ID, bp1.get_ID(), bp2.get_ID());
|
||||
assertTrue(ok, "Merge fail");
|
||||
o1.load(null);
|
||||
assertEquals(bp2.get_ID(), o1.getC_BPartner_ID(), "Unexpected order line C_BPartner_ID after merge");
|
||||
o2.load(null);
|
||||
assertEquals(bp2.get_ID(), o2.getC_BPartner_ID(), "Unexpected order line C_BPartner_ID after merge");
|
||||
bp1.load(null);
|
||||
assertEquals(0, bp1.get_ID(), "BPartner not deleted after merge");
|
||||
} finally {
|
||||
if (o1 != null && o1.get_ID() > 0)
|
||||
o1.deleteEx(true);
|
||||
if (o2 != null && o2.get_ID() > 0)
|
||||
o2.deleteEx(true);
|
||||
if (bp1 != null && bp1.get_ID() > 0)
|
||||
bp1.deleteEx(true);
|
||||
if (bp2 != null && bp2.get_ID() > 0)
|
||||
bp2.deleteEx(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeUser() {
|
||||
MUser u1 = null;
|
||||
MUser u2 = null;
|
||||
MUserDefWin udw = null;
|
||||
|
||||
try {
|
||||
u1 = new MUser(Env.getCtx(), 0, null);
|
||||
u1.setName("testMergeUser1");
|
||||
u1.saveEx();
|
||||
|
||||
u2 = new MUser(Env.getCtx(), 0, null);
|
||||
u2.setName("testMergeUser2");
|
||||
u2.saveEx();
|
||||
|
||||
udw = new MUserDefWin(Env.getCtx(), 0, null);
|
||||
udw.setAD_User_ID(u1.get_ID());
|
||||
udw.setAD_Window_ID(SystemIDs.WINDOW_SALES_ORDER);
|
||||
udw.saveEx();
|
||||
|
||||
Merge merge = new Merge();
|
||||
boolean ok = merge.merge(Merge.AD_USER_ID, u1.get_ID(), u2.get_ID());
|
||||
assertTrue(ok, "Merge fail");
|
||||
|
||||
u1.load(null);
|
||||
assertEquals(0, u1.get_ID(), "User not deleted after merge");
|
||||
udw.load(null);
|
||||
assertEquals(u2.get_ID(), udw.getAD_User_ID(), "Unexpected MUserDefWin.AD_User_ID after merge");
|
||||
} finally {
|
||||
if (udw != null && udw.get_ID() > 0)
|
||||
udw.deleteEx(true);
|
||||
if (u1 != null && u1.get_ID() > 0)
|
||||
u1.deleteEx(true);
|
||||
if (u2 != null && u2.get_ID() > 0)
|
||||
u2.deleteEx(true);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue