From ce22d1cc5152419d3b6342b4260e123b669270e3 Mon Sep 17 00:00:00 2001 From: hengsin Date: Thu, 18 Aug 2022 00:34:51 +0800 Subject: [PATCH] IDEMPIERE-5391 Unit Test: Fix support for parallel execution of test (#1446) --- .../src/org/compiere/model/MTable.java | 6 +- .../idempiere.unit.test.parallel.launch | 405 +++++++++++++++ .../idempiere/test/ConversionRateHelper.java | 89 ++++ .../src/org/idempiere/test/DictionaryIDs.java | 7 +- .../test/base/Convert_PostgreSQLTest.java | 3 + .../org/idempiere/test/base/InOutTest.java | 32 +- .../test/base/MatchInv2ndAcctSchemaTest.java | 66 ++- .../org/idempiere/test/base/MatchInvTest.java | 188 ------- .../test/base/MatchInvTestIsolated.java | 263 ++++++++++ .../test/form/CreateFromInvoiceFormTest.java | 4 +- .../test/form/CreateFromRMAFormTest.java | 2 +- .../test/form/CreateFromShipmentFormTest.java | 4 +- .../model/Allocation2ndAcctSchemaTest.java | 82 ++-- .../idempiere/test/model/AllocationTest.java | 60 +-- .../test/model/BankStatementTest.java | 11 + .../idempiere/test/model/InventoryTest.java | 199 -------- .../test/model/InventoryTestIsolated.java | 298 ++++++++++++ .../test/model/InvoiceCustomerTest.java | 5 + .../test/model/MStorageOnHandTest.java | 178 +------ .../model/MStorageOnHandTestIsolated.java | 230 +++++++++ .../org/idempiere/test/model/MTaxTest.java | 8 +- .../test/model/ModelClassMappingTest.java | 2 + .../idempiere/test/model/ProductionTest.java | 337 ------------- .../test/model/ProductionTestIsolated.java | 460 ++++++++++++++++++ .../test/model/PurchaseOrderTest.java | 26 +- .../idempiere/test/model/SalesOrderTest.java | 2 + .../idempiere/test/performance/CacheTest.java | 2 + 27 files changed, 1904 insertions(+), 1065 deletions(-) create mode 100644 org.idempiere.test/idempiere.unit.test.parallel.launch create mode 100644 org.idempiere.test/src/org/idempiere/test/ConversionRateHelper.java create mode 100644 org.idempiere.test/src/org/idempiere/test/base/MatchInvTestIsolated.java create mode 100644 org.idempiere.test/src/org/idempiere/test/model/InventoryTestIsolated.java create mode 100644 org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTestIsolated.java create mode 100644 org.idempiere.test/src/org/idempiere/test/model/ProductionTestIsolated.java diff --git a/org.adempiere.base/src/org/compiere/model/MTable.java b/org.adempiere.base/src/org/compiere/model/MTable.java index 509b1a052e..9afadfa7d5 100644 --- a/org.adempiere.base/src/org/compiere/model/MTable.java +++ b/org.adempiere.base/src/org/compiere/model/MTable.java @@ -24,7 +24,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; @@ -151,10 +150,9 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport { if (tableName == null) return null; - Iterator it = s_cache.values().iterator(); - while (it.hasNext()) + MTable[] tables = s_cache.values().toArray(new MTable[0]); + for (MTable retValue : tables) { - MTable retValue = it.next(); if (tableName.equalsIgnoreCase(retValue.getTableName())) { return s_cache.get (ctx, retValue.get_ID(), e -> new MTable(ctx, e)); diff --git a/org.idempiere.test/idempiere.unit.test.parallel.launch b/org.idempiere.test/idempiere.unit.test.parallel.launch new file mode 100644 index 0000000000..3bbe2d3d7f --- /dev/null +++ b/org.idempiere.test/idempiere.unit.test.parallel.launch @@ -0,0 +1,405 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.idempiere.test/src/org/idempiere/test/ConversionRateHelper.java b/org.idempiere.test/src/org/idempiere/test/ConversionRateHelper.java new file mode 100644 index 0000000000..73e98912e9 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/ConversionRateHelper.java @@ -0,0 +1,89 @@ +/*********************************************************************** + * 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; + +import java.math.BigDecimal; +import java.sql.Timestamp; + +import org.compiere.model.MConversionRate; +import org.compiere.model.Query; +import org.compiere.util.Env; + +/** + * + * @author hengsin + * + */ +public final class ConversionRateHelper { + + private ConversionRateHelper() { + } + + /** + * + * @param C_Currency_ID + * @param C_Currency_ID_To + * @param C_ConversionType_ID + * @param date + * @param rate + * @param isMultiplyRate + * @return {@link MConversionRate} + */ + public static MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID, + Timestamp date, BigDecimal rate, boolean isMultiplyRate) { + MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null); + cr.setC_Currency_ID(C_Currency_ID); + cr.setC_Currency_ID_To(C_Currency_ID_To); + cr.setC_ConversionType_ID(C_ConversionType_ID); + cr.setValidFrom(date); + cr.setValidTo(date); + if (isMultiplyRate) + cr.setMultiplyRate(rate); + else + cr.setDivideRate(rate); + cr.saveEx(); + return cr; + } + + /** + * + * @param cr + */ + public static void deleteConversionRate(MConversionRate cr) { + String whereClause = "ValidFrom=? AND ValidTo=? " + + "AND C_Currency_ID=? AND C_Currency_ID_To=? " + + "AND C_ConversionType_ID=? " + + "AND AD_Client_ID=? AND AD_Org_ID=?"; + MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null) + .setParameters(cr.getValidFrom(), cr.getValidTo(), + cr.getC_Currency_ID_To(), cr.getC_Currency_ID(), + cr.getC_ConversionType_ID(), + cr.getAD_Client_ID(), cr.getAD_Org_ID()) + .firstOnly(); + if (reciprocal != null) + reciprocal.deleteEx(true); + cr.deleteEx(true); + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java b/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java index 283e3a8afd..42ed000d41 100644 --- a/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java +++ b/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java @@ -93,7 +93,12 @@ public final class DictionaryIDs { C_AND_W(117), JOE_BLOCK(118), SEED_FARM(120), - PATIO(121); + PATIO(121), + WOOD_INC(50000), + COLOR_INC(50001), + CHROME_INC(50002), + CHEMICAL_INC(50003), + AGRI_TECH(200000); public final int id; diff --git a/org.idempiere.test/src/org/idempiere/test/base/Convert_PostgreSQLTest.java b/org.idempiere.test/src/org/idempiere/test/base/Convert_PostgreSQLTest.java index 8b3bb54c1b..16f4925373 100644 --- a/org.idempiere.test/src/org/idempiere/test/base/Convert_PostgreSQLTest.java +++ b/org.idempiere.test/src/org/idempiere/test/base/Convert_PostgreSQLTest.java @@ -20,12 +20,15 @@ import org.compiere.util.Env; import org.compiere.util.Ini; import org.idempiere.test.AbstractTestCase; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; /** * Unit testing for Convert_PostgreSQL. * @author Low Heng Sin * @version 20061225 */ +@Execution(ExecutionMode.SAME_THREAD) public final class Convert_PostgreSQLTest extends AbstractTestCase { //private Convert_PostgreSQL convert = new Convert_PostgreSQL(); String sql; diff --git a/org.idempiere.test/src/org/idempiere/test/base/InOutTest.java b/org.idempiere.test/src/org/idempiere/test/base/InOutTest.java index 32ad0feb27..94119801aa 100644 --- a/org.idempiere.test/src/org/idempiere/test/base/InOutTest.java +++ b/org.idempiere.test/src/org/idempiere/test/base/InOutTest.java @@ -54,7 +54,6 @@ import org.compiere.model.MShipper; import org.compiere.model.MShippingProcessor; import org.compiere.model.MWarehouse; import org.compiere.model.PO; -import org.compiere.model.Query; import org.compiere.model.SystemIDs; import org.compiere.model.X_C_BP_ShippingAcct; import org.compiere.model.X_M_ShippingProcessorCfg; @@ -65,8 +64,10 @@ import org.compiere.util.Env; import org.compiere.util.TimeUtil; import org.compiere.wf.MWorkflow; import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.ConversionRateHelper; import org.idempiere.test.DictionaryIDs; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; /** * @author etantg @@ -77,6 +78,7 @@ public class InOutTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * https://idempiere.atlassian.net/browse/IDEMPIERE-4656 */ @@ -212,6 +214,7 @@ public class InOutTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * https://idempiere.atlassian.net/browse/IDEMPIERE-4656 */ @@ -374,34 +377,11 @@ public class InOutTest extends AbstractTestCase { private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID, Timestamp date, BigDecimal rate, boolean isMultiplyRate) { - MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null); - cr.setC_Currency_ID(C_Currency_ID); - cr.setC_Currency_ID_To(C_Currency_ID_To); - cr.setC_ConversionType_ID(C_ConversionType_ID); - cr.setValidFrom(date); - cr.setValidTo(date); - if (isMultiplyRate) - cr.setMultiplyRate(rate); - else - cr.setDivideRate(rate); - cr.saveEx(); - return cr; + return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate); } private void deleteConversionRate(MConversionRate cr) { - String whereClause = "ValidFrom=? AND ValidTo=? " - + "AND C_Currency_ID=? AND C_Currency_ID_To=? " - + "AND C_ConversionType_ID=? " - + "AND AD_Client_ID=? AND AD_Org_ID=?"; - MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null) - .setParameters(cr.getValidFrom(), cr.getValidTo(), - cr.getC_Currency_ID_To(), cr.getC_Currency_ID(), - cr.getC_ConversionType_ID(), - cr.getAD_Client_ID(), cr.getAD_Org_ID()) - .firstOnly(); - if (reciprocal != null) - reciprocal.deleteEx(true); - cr.deleteEx(true); + ConversionRateHelper.deleteConversionRate(cr); } private MOrder createPurchaseOrder(MBPartner bpartner, Timestamp date, int M_PriceList_ID, int C_ConversionType_ID) { diff --git a/org.idempiere.test/src/org/idempiere/test/base/MatchInv2ndAcctSchemaTest.java b/org.idempiere.test/src/org/idempiere/test/base/MatchInv2ndAcctSchemaTest.java index 9d4c9f622f..360fb087c4 100644 --- a/org.idempiere.test/src/org/idempiere/test/base/MatchInv2ndAcctSchemaTest.java +++ b/org.idempiere.test/src/org/idempiere/test/base/MatchInv2ndAcctSchemaTest.java @@ -59,15 +59,16 @@ import org.compiere.model.MProductPrice; import org.compiere.model.MWarehouse; import org.compiere.model.PO; import org.compiere.model.ProductCost; -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.wf.MWorkflow; import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.ConversionRateHelper; import org.idempiere.test.DictionaryIDs; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; /** * @author Elaine Tan - etantg @@ -78,6 +79,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (same period) * PO Qty1=2400, Qty2=2400 @@ -167,6 +169,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (same period) * PO Qty=10, Price=33.75 @@ -177,7 +180,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * IV Qty=5 */ public void testCreditMemoPosting_2() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company @@ -284,6 +287,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (different period) * PO Qty=3, Price=0.3023, Period 1 @@ -292,7 +296,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * CM Qty=2, Period 2 */ public void testCreditMemoPosting_3() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); @@ -409,6 +413,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (different period) * PO Qty1=1000, Qty2=1000, Qty3=1000, Price1=3.00, Price2=2.70, Price3=3.15, Period 1 @@ -417,7 +422,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * CM Qty1=200, Qty2=300, Period 3 */ public void testCreditMemoPosting_4() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id); MProduct product1 = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree MProduct product2 = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.OAK.id); // Oak Tree MProduct product3 = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.PLUM_TREE.id); // Plum Tree @@ -582,6 +587,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (same period) * PO Qty=2, Price=0.1875 @@ -590,7 +596,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * CM Qty=1 */ public void testCreditMemoPosting_5() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company @@ -670,6 +676,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (same period) * PO Qty=200, Price=0.1875 @@ -758,6 +765,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (same period) * PO Qty=45, Price=0.3742 @@ -766,7 +774,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * CM Qty=44 */ public void testCreditMemoPosting_7() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company @@ -844,6 +852,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting for credit memo (same period + reversal) * PO Qty=2, Price=0.1875 @@ -854,7 +863,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * CM Qty=1 */ public void testCreditMemoPosting_8() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company @@ -977,6 +986,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting (same period) * PO Qty=1200, Price=0.3742 @@ -985,7 +995,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * MR Qty=1200 */ public void testMatReceiptPosting_1() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); int C_ConversionType_ID = DictionaryIDs.C_ConversionType.COMPANY.id; // Company @@ -1063,6 +1073,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting (different period) * PO Qty=1200, Price=0.3742, Period 1 @@ -1071,7 +1082,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * MR Qty=44, Period 2 */ public void testMatReceiptPosting_2() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); @@ -1160,6 +1171,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting (same period + reversal) * PO Qty=2, Price=0.1875 @@ -1293,6 +1305,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting (different period + reversal) * PO Qty=2, Price=0.1875, Period 1 @@ -1303,7 +1316,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * MR Qty=1, Period 2 */ public void testMatReceiptPosting_4() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.WOOD_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); @@ -1437,6 +1450,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting (same period) * PO Qty=500, Price=23.32 @@ -1445,7 +1459,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * IV Qty=250 */ public void testMatReceiptPosting_5() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); @@ -1549,6 +1563,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the matched invoice posting (same period + reversal) * PO Qty=5, Price=65 @@ -1557,7 +1572,7 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { * MR Qty=5 (Reversed) */ public void testMatReceiptPostingWithDiffCurrencyPrecision() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHEMICAL_INC.id); MProduct product = MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ELM.id); // Elm Tree Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); @@ -1658,34 +1673,11 @@ public class MatchInv2ndAcctSchemaTest extends AbstractTestCase { private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID, Timestamp date, BigDecimal rate, boolean isMultiplyRate) { - MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null); - cr.setC_Currency_ID(C_Currency_ID); - cr.setC_Currency_ID_To(C_Currency_ID_To); - cr.setC_ConversionType_ID(C_ConversionType_ID); - cr.setValidFrom(date); - cr.setValidTo(date); - if (isMultiplyRate) - cr.setMultiplyRate(rate); - else - cr.setDivideRate(rate); - cr.saveEx(); - return cr; + return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate); } private void deleteConversionRate(MConversionRate cr) { - String whereClause = "ValidFrom=? AND ValidTo=? " - + "AND C_Currency_ID=? AND C_Currency_ID_To=? " - + "AND C_ConversionType_ID=? " - + "AND AD_Client_ID=? AND AD_Org_ID=?"; - MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null) - .setParameters(cr.getValidFrom(), cr.getValidTo(), - cr.getC_Currency_ID_To(), cr.getC_Currency_ID(), - cr.getC_ConversionType_ID(), - cr.getAD_Client_ID(), cr.getAD_Org_ID()) - .firstOnly(); - if (reciprocal != null) - reciprocal.deleteEx(true); - cr.deleteEx(true); + ConversionRateHelper.deleteConversionRate(cr); } private MOrder createPurchaseOrder(MBPartner bpartner, Timestamp date, int M_PriceList_ID, int C_ConversionType_ID) { diff --git a/org.idempiere.test/src/org/idempiere/test/base/MatchInvTest.java b/org.idempiere.test/src/org/idempiere/test/base/MatchInvTest.java index 263f095a1a..6cb12b5b0f 100644 --- a/org.idempiere.test/src/org/idempiere/test/base/MatchInvTest.java +++ b/org.idempiere.test/src/org/idempiere/test/base/MatchInvTest.java @@ -26,13 +26,11 @@ package org.idempiere.test.base; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Timestamp; -import java.util.List; import org.compiere.acct.Doc; import org.compiere.acct.DocManager; @@ -41,14 +39,11 @@ import org.compiere.model.MAcctSchema; import org.compiere.model.MBPartner; import org.compiere.model.MClient; import org.compiere.model.MConversionRate; -import org.compiere.model.MCost; import org.compiere.model.MCurrency; import org.compiere.model.MDocType; import org.compiere.model.MFactAcct; import org.compiere.model.MInOut; import org.compiere.model.MInOutLine; -import org.compiere.model.MInventory; -import org.compiere.model.MInventoryLine; import org.compiere.model.MInvoice; import org.compiere.model.MInvoiceLine; import org.compiere.model.MMatchInv; @@ -57,8 +52,6 @@ import org.compiere.model.MOrderLine; import org.compiere.model.MPriceList; import org.compiere.model.MPriceListVersion; import org.compiere.model.MProduct; -import org.compiere.model.MProductCategory; -import org.compiere.model.MProductCategoryAcct; import org.compiere.model.MProductPrice; import org.compiere.model.MRMA; import org.compiere.model.MRMALine; @@ -357,187 +350,6 @@ public class MatchInvTest extends AbstractTestCase { rollback(); } - @Test - /** - * Test Standard Cost and Invoice Price Variance posting - */ - public void testMatchInvStdCost() { - MProductCategory category = new MProductCategory(Env.getCtx(), 0, null); - category.setName("Standard Costing"); - category.saveEx(); - String whereClause = "M_Product_Category_ID=?"; - List categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null) - .setParameters(category.get_ID()) - .list(); - for (MProductCategoryAcct categoryAcct : categoryAccts) { - categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); - categoryAcct.saveEx(); - } - - try { - int mulchId = DictionaryIDs.M_Product.MULCH.id; // Mulch product - MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName()); - mulch.setM_Product_Category_ID(category.get_ID()); - mulch.saveEx(); - - int purchaseId = DictionaryIDs.M_PriceList.PURCHASE.id; // Purchase Price List - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); // Seed Farm Inc. - MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); - BigDecimal mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - - // Change standard cost of mulch product to 2.1234 - int hqLocator = DictionaryIDs.M_Locator.HQ.id; - int costAdjustmentDocTypeId = DictionaryIDs.C_DocType.COST_ADJUSTMENT.id; - MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName()); - inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); - inventory.setC_DocType_ID(costAdjustmentDocTypeId); - inventory.setM_Warehouse_ID(getM_Warehouse_ID()); - inventory.setMovementDate(getLoginDate()); - inventory.setDocAction(DocAction.ACTION_Complete); - inventory.saveEx(); - - BigDecimal endProductCost = new BigDecimal("2.1234").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName()); - il.setM_Inventory_ID(inventory.get_ID()); - il.setM_Locator_ID(hqLocator); - il.setM_Product_ID(mulch.getM_Product_ID()); - il.setCurrentCostPrice(mulchCost); - il.setNewCostPrice(endProductCost); - il.saveEx(); - - ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); - inventory.load(getTrxName()); - assertFalse(info.isError(), info.getSummary()); - assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus()); - - if (!inventory.isPosted()) { - String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName()); - assertNull(msg, msg); - } - mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - assertEquals(endProductCost, mulchCost, "Cost not adjusted: " + mulchCost.toPlainString()); - - //test converted cost for all schemas - MAcctSchema[] schemas = MAcctSchema.getClientAcctSchema(Env.getCtx(), getAD_Client_ID()); - for (int i = 0; i < schemas.length; i++) { - BigDecimal expected = MConversionRate.convert (Env.getCtx(), - mulchCost, as.getC_Currency_ID(), schemas[i].getC_Currency_ID(), - inventory.getMovementDate(), 0, getAD_Client_ID(), getAD_Org_ID(), true); - BigDecimal mulchCostConv = MCost.getCurrentCost(mulch, 0, schemas[i], schemas[i].getAD_Org_ID(), MAcctSchema.COSTINGMETHOD_StandardCosting, - BigDecimal.ONE, 0, true, getTrxName()).setScale(schemas[i].getCostingPrecision(), RoundingMode.HALF_UP); - assertEquals(expected, mulchCostConv, "Converted Cost for schema incorrect: " + schemas[i].toString()+ " - " + mulchCostConv.toPlainString()); - } - - MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); - order.setBPartner(bpartner); - order.setIsSOTrx(false); - order.setC_DocTypeTarget_ID(); - order.setM_PriceList_ID(purchaseId); - order.setDocStatus(DocAction.STATUS_Drafted); - order.setDocAction(DocAction.ACTION_Complete); - order.saveEx(); - - MOrderLine orderLine = new MOrderLine(order); - orderLine.setLine(10); - orderLine.setProduct(mulch); - orderLine.setQty(BigDecimal.ONE); - orderLine.saveEx(); - - info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete); - order.load(getTrxName()); - assertFalse(info.isError(), info.getSummary()); - assertEquals(DocAction.STATUS_Completed, order.getDocStatus()); - - MInOut receipt = new MInOut(order, 122, order.getDateOrdered()); // MM Receipt - receipt.saveEx(); - - MInOutLine receiptLine = new MInOutLine(receipt); - receiptLine.setC_OrderLine_ID(orderLine.get_ID()); - receiptLine.setLine(10); - receiptLine.setProduct(mulch); - receiptLine.setQty(BigDecimal.ONE); - MWarehouse wh = MWarehouse.get(Env.getCtx(), receipt.getM_Warehouse_ID()); - int M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID(); - receiptLine.setM_Locator_ID(M_Locator_ID); - receiptLine.saveEx(); - - info = MWorkflow.runDocumentActionWorkflow(receipt, DocAction.ACTION_Complete); - receipt.load(getTrxName()); - assertFalse(info.isError(), info.getSummary()); - assertEquals(DocAction.STATUS_Completed, receipt.getDocStatus()); - - if (!receipt.isPosted()) { - String error = DocumentEngine.postImmediate(Env.getCtx(), receipt.getAD_Client_ID(), MInOut.Table_ID, receipt.get_ID(), false, getTrxName()); - assertTrue(error == null); - } - receipt.load(getTrxName()); - assertTrue(receipt.isPosted()); - - MInvoice invoice = new MInvoice(receipt, receipt.getMovementDate()); - invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_APInvoice); - invoice.setDocStatus(DocAction.STATUS_Drafted); - invoice.setDocAction(DocAction.ACTION_Complete); - invoice.saveEx(); - - MInvoiceLine invoiceLine = new MInvoiceLine(invoice); - invoiceLine.setM_InOutLine_ID(receiptLine.get_ID()); - invoiceLine.setLine(10); - invoiceLine.setProduct(mulch); - invoiceLine.setQty(BigDecimal.ONE); - invoiceLine.saveEx(); - - info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete); - invoice.load(getTrxName()); - assertFalse(info.isError(), info.getSummary()); - assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus()); - - if (!invoice.isPosted()) { - String error = DocumentEngine.postImmediate(Env.getCtx(), invoice.getAD_Client_ID(), MInvoice.Table_ID, invoice.get_ID(), false, getTrxName()); - assertTrue(error == null); - } - invoice.load(getTrxName()); - assertTrue(invoice.isPosted()); - - MMatchInv[] miList = MMatchInv.getInvoiceLine(Env.getCtx(), invoiceLine.get_ID(), getTrxName()); - for (MMatchInv mi : miList) { - if (!mi.isPosted()) { - String error = DocumentEngine.postImmediate(Env.getCtx(), mi.getAD_Client_ID(), MMatchInv.Table_ID, mi.get_ID(), false, getTrxName()); - assertTrue(error == null); - } - mi.load(getTrxName()); - assertTrue(mi.isPosted()); - - Doc doc = DocManager.getDocument(as, MMatchInv.Table_ID, mi.get_ID(), getTrxName()); - doc.setC_BPartner_ID(mi.getC_InvoiceLine().getC_Invoice().getC_BPartner_ID()); - MAccount acctNIR = doc.getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as); - - ProductCost pc = new ProductCost (Env.getCtx(), mi.getM_Product_ID(), mi.getM_AttributeSetInstance_ID(), getTrxName()); - MAccount acctInvClr = pc.getAccount(ProductCost.ACCTTYPE_P_InventoryClearing, as); - MAccount acctIPV = pc.getAccount(ProductCost.ACCTTYPE_P_IPV, as); - int C_AcctSchema_ID = as.getC_AcctSchema_ID(); - - String whereClause2 = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MMatchInv.Table_ID - + " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + mi.get_ID() - + " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + C_AcctSchema_ID; - int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause2, getTrxName()); - BigDecimal invMatchAmt = invoiceLine.getMatchedQty().multiply(invoiceLine.getPriceActual()).setScale(as.getStdPrecision(), RoundingMode.HALF_UP); - mulchCost = mulchCost.setScale(as.getStdPrecision(), RoundingMode.HALF_UP); - for (int id : ids) { - MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName()); - if (fa.getAccount_ID() == acctNIR.getAccount_ID()) - assertEquals(fa.getAmtAcctDr().setScale(2, RoundingMode.HALF_UP), mulchCost.setScale(2, RoundingMode.HALF_UP), ""); - else if (fa.getAccount_ID() == acctInvClr.getAccount_ID()) - assertEquals(fa.getAmtAcctCr().setScale(2, RoundingMode.HALF_UP), invMatchAmt.setScale(2, RoundingMode.HALF_UP), ""); - else if (fa.getAccount_ID() == acctIPV.getAccount_ID()) - assertEquals(fa.getAmtAcctDr().subtract(fa.getAmtAcctCr()).setScale(2, RoundingMode.HALF_UP), invMatchAmt.subtract(mulchCost).setScale(2, RoundingMode.HALF_UP), ""); - } - } - } finally { - getTrx().rollback(); - category.deleteEx(true); - } - } - @Test /** * Test the matched invoice posting for credit memo diff --git a/org.idempiere.test/src/org/idempiere/test/base/MatchInvTestIsolated.java b/org.idempiere.test/src/org/idempiere/test/base/MatchInvTestIsolated.java new file mode 100644 index 0000000000..e0934d0e33 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/base/MatchInvTestIsolated.java @@ -0,0 +1,263 @@ +/*********************************************************************** + * 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: * + * - Elaine Tan - etantg * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.base; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + +import org.compiere.acct.Doc; +import org.compiere.acct.DocManager; +import org.compiere.model.MAccount; +import org.compiere.model.MAcctSchema; +import org.compiere.model.MBPartner; +import org.compiere.model.MClient; +import org.compiere.model.MConversionRate; +import org.compiere.model.MCost; +import org.compiere.model.MDocType; +import org.compiere.model.MFactAcct; +import org.compiere.model.MInOut; +import org.compiere.model.MInOutLine; +import org.compiere.model.MInventory; +import org.compiere.model.MInventoryLine; +import org.compiere.model.MInvoice; +import org.compiere.model.MInvoiceLine; +import org.compiere.model.MMatchInv; +import org.compiere.model.MOrder; +import org.compiere.model.MOrderLine; +import org.compiere.model.MProduct; +import org.compiere.model.MProductCategory; +import org.compiere.model.MProductCategoryAcct; +import org.compiere.model.MWarehouse; +import org.compiere.model.ProductCost; +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.wf.MWorkflow; +import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.DictionaryIDs; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; + +/** + * + * @author hengsin + * + */ +@Isolated +public class MatchInvTestIsolated extends AbstractTestCase { + + public MatchInvTestIsolated() { + } + + @Test + /** + * Test Standard Cost and Invoice Price Variance posting + */ + public void testMatchInvStdCost() { + MProductCategory category = new MProductCategory(Env.getCtx(), 0, null); + category.setName("Standard Costing"); + category.saveEx(); + String whereClause = "M_Product_Category_ID=?"; + List categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null) + .setParameters(category.get_ID()) + .list(); + for (MProductCategoryAcct categoryAcct : categoryAccts) { + categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); + categoryAcct.saveEx(); + } + + try { + int mulchId = DictionaryIDs.M_Product.MULCH.id; // Mulch product + MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName()); + mulch.setM_Product_Category_ID(category.get_ID()); + mulch.saveEx(); + + int purchaseId = DictionaryIDs.M_PriceList.PURCHASE.id; // Purchase Price List + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); // Seed Farm Inc. + MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); + BigDecimal mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + + // Change standard cost of mulch product to 2.1234 + int hqLocator = DictionaryIDs.M_Locator.HQ.id; + int costAdjustmentDocTypeId = DictionaryIDs.C_DocType.COST_ADJUSTMENT.id; + MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName()); + inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); + inventory.setC_DocType_ID(costAdjustmentDocTypeId); + inventory.setM_Warehouse_ID(getM_Warehouse_ID()); + inventory.setMovementDate(getLoginDate()); + inventory.setDocAction(DocAction.ACTION_Complete); + inventory.saveEx(); + + BigDecimal endProductCost = new BigDecimal("2.1234").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName()); + il.setM_Inventory_ID(inventory.get_ID()); + il.setM_Locator_ID(hqLocator); + il.setM_Product_ID(mulch.getM_Product_ID()); + il.setCurrentCostPrice(mulchCost); + il.setNewCostPrice(endProductCost); + il.saveEx(); + + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); + inventory.load(getTrxName()); + assertFalse(info.isError(), info.getSummary()); + assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus()); + + if (!inventory.isPosted()) { + String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName()); + assertNull(msg, msg); + } + mulchCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + assertEquals(endProductCost, mulchCost, "Cost not adjusted: " + mulchCost.toPlainString()); + + //test converted cost for all schemas + MAcctSchema[] schemas = MAcctSchema.getClientAcctSchema(Env.getCtx(), getAD_Client_ID()); + for (int i = 0; i < schemas.length; i++) { + BigDecimal expected = MConversionRate.convert (Env.getCtx(), + mulchCost, as.getC_Currency_ID(), schemas[i].getC_Currency_ID(), + inventory.getMovementDate(), 0, getAD_Client_ID(), getAD_Org_ID(), true); + BigDecimal mulchCostConv = MCost.getCurrentCost(mulch, 0, schemas[i], schemas[i].getAD_Org_ID(), MAcctSchema.COSTINGMETHOD_StandardCosting, + BigDecimal.ONE, 0, true, getTrxName()).setScale(schemas[i].getCostingPrecision(), RoundingMode.HALF_UP); + assertEquals(expected, mulchCostConv, "Converted Cost for schema incorrect: " + schemas[i].toString()+ " - " + mulchCostConv.toPlainString()); + } + + MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); + order.setBPartner(bpartner); + order.setIsSOTrx(false); + order.setC_DocTypeTarget_ID(); + order.setM_PriceList_ID(purchaseId); + order.setDocStatus(DocAction.STATUS_Drafted); + order.setDocAction(DocAction.ACTION_Complete); + order.saveEx(); + + MOrderLine orderLine = new MOrderLine(order); + orderLine.setLine(10); + orderLine.setProduct(mulch); + orderLine.setQty(BigDecimal.ONE); + orderLine.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete); + order.load(getTrxName()); + assertFalse(info.isError(), info.getSummary()); + assertEquals(DocAction.STATUS_Completed, order.getDocStatus()); + + MInOut receipt = new MInOut(order, 122, order.getDateOrdered()); // MM Receipt + receipt.saveEx(); + + MInOutLine receiptLine = new MInOutLine(receipt); + receiptLine.setC_OrderLine_ID(orderLine.get_ID()); + receiptLine.setLine(10); + receiptLine.setProduct(mulch); + receiptLine.setQty(BigDecimal.ONE); + MWarehouse wh = MWarehouse.get(Env.getCtx(), receipt.getM_Warehouse_ID()); + int M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID(); + receiptLine.setM_Locator_ID(M_Locator_ID); + receiptLine.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(receipt, DocAction.ACTION_Complete); + receipt.load(getTrxName()); + assertFalse(info.isError(), info.getSummary()); + assertEquals(DocAction.STATUS_Completed, receipt.getDocStatus()); + + if (!receipt.isPosted()) { + String error = DocumentEngine.postImmediate(Env.getCtx(), receipt.getAD_Client_ID(), MInOut.Table_ID, receipt.get_ID(), false, getTrxName()); + assertTrue(error == null); + } + receipt.load(getTrxName()); + assertTrue(receipt.isPosted()); + + MInvoice invoice = new MInvoice(receipt, receipt.getMovementDate()); + invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_APInvoice); + invoice.setDocStatus(DocAction.STATUS_Drafted); + invoice.setDocAction(DocAction.ACTION_Complete); + invoice.saveEx(); + + MInvoiceLine invoiceLine = new MInvoiceLine(invoice); + invoiceLine.setM_InOutLine_ID(receiptLine.get_ID()); + invoiceLine.setLine(10); + invoiceLine.setProduct(mulch); + invoiceLine.setQty(BigDecimal.ONE); + invoiceLine.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete); + invoice.load(getTrxName()); + assertFalse(info.isError(), info.getSummary()); + assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus()); + + if (!invoice.isPosted()) { + String error = DocumentEngine.postImmediate(Env.getCtx(), invoice.getAD_Client_ID(), MInvoice.Table_ID, invoice.get_ID(), false, getTrxName()); + assertTrue(error == null); + } + invoice.load(getTrxName()); + assertTrue(invoice.isPosted()); + + MMatchInv[] miList = MMatchInv.getInvoiceLine(Env.getCtx(), invoiceLine.get_ID(), getTrxName()); + for (MMatchInv mi : miList) { + if (!mi.isPosted()) { + String error = DocumentEngine.postImmediate(Env.getCtx(), mi.getAD_Client_ID(), MMatchInv.Table_ID, mi.get_ID(), false, getTrxName()); + assertTrue(error == null); + } + mi.load(getTrxName()); + assertTrue(mi.isPosted()); + + Doc doc = DocManager.getDocument(as, MMatchInv.Table_ID, mi.get_ID(), getTrxName()); + doc.setC_BPartner_ID(mi.getC_InvoiceLine().getC_Invoice().getC_BPartner_ID()); + MAccount acctNIR = doc.getAccount(Doc.ACCTTYPE_NotInvoicedReceipts, as); + + ProductCost pc = new ProductCost (Env.getCtx(), mi.getM_Product_ID(), mi.getM_AttributeSetInstance_ID(), getTrxName()); + MAccount acctInvClr = pc.getAccount(ProductCost.ACCTTYPE_P_InventoryClearing, as); + MAccount acctIPV = pc.getAccount(ProductCost.ACCTTYPE_P_IPV, as); + int C_AcctSchema_ID = as.getC_AcctSchema_ID(); + + String whereClause2 = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MMatchInv.Table_ID + + " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + mi.get_ID() + + " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + C_AcctSchema_ID; + int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause2, getTrxName()); + BigDecimal invMatchAmt = invoiceLine.getMatchedQty().multiply(invoiceLine.getPriceActual()).setScale(as.getStdPrecision(), RoundingMode.HALF_UP); + mulchCost = mulchCost.setScale(as.getStdPrecision(), RoundingMode.HALF_UP); + for (int id : ids) { + MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName()); + if (fa.getAccount_ID() == acctNIR.getAccount_ID()) + assertEquals(fa.getAmtAcctDr().setScale(2, RoundingMode.HALF_UP), mulchCost.setScale(2, RoundingMode.HALF_UP), ""); + else if (fa.getAccount_ID() == acctInvClr.getAccount_ID()) + assertEquals(fa.getAmtAcctCr().setScale(2, RoundingMode.HALF_UP), invMatchAmt.setScale(2, RoundingMode.HALF_UP), ""); + else if (fa.getAccount_ID() == acctIPV.getAccount_ID()) + assertEquals(fa.getAmtAcctDr().subtract(fa.getAmtAcctCr()).setScale(2, RoundingMode.HALF_UP), invMatchAmt.subtract(mulchCost).setScale(2, RoundingMode.HALF_UP), ""); + } + } + } finally { + getTrx().rollback(); + category.deleteEx(true); + } + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/form/CreateFromInvoiceFormTest.java b/org.idempiere.test/src/org/idempiere/test/form/CreateFromInvoiceFormTest.java index ba51fc653d..5d3a50fa76 100644 --- a/org.idempiere.test/src/org/idempiere/test/form/CreateFromInvoiceFormTest.java +++ b/org.idempiere.test/src/org/idempiere/test/form/CreateFromInvoiceFormTest.java @@ -87,7 +87,7 @@ public class CreateFromInvoiceFormTest extends AbstractTestCase { MOrderLine line1 = new MOrderLine(order); line1.setLine(10); - line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id)); + line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id)); line1.setQty(new BigDecimal("1")); line1.setDatePromised(today); line1.saveEx(); @@ -179,7 +179,7 @@ public class CreateFromInvoiceFormTest extends AbstractTestCase { MOrderLine line1 = new MOrderLine(order); line1.setLine(10); - line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id)); + line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id)); line1.setQty(new BigDecimal("1")); line1.setDatePromised(today); line1.saveEx(); diff --git a/org.idempiere.test/src/org/idempiere/test/form/CreateFromRMAFormTest.java b/org.idempiere.test/src/org/idempiere/test/form/CreateFromRMAFormTest.java index e1b76ca1e6..ffc3e3ae5d 100644 --- a/org.idempiere.test/src/org/idempiere/test/form/CreateFromRMAFormTest.java +++ b/org.idempiere.test/src/org/idempiere/test/form/CreateFromRMAFormTest.java @@ -85,7 +85,7 @@ public class CreateFromRMAFormTest extends AbstractTestCase { MOrderLine orderLine = new MOrderLine(order); orderLine.setLine(10); - orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id)); + orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id)); orderLine.setQty(new BigDecimal("1")); orderLine.setDatePromised(today); orderLine.saveEx(); diff --git a/org.idempiere.test/src/org/idempiere/test/form/CreateFromShipmentFormTest.java b/org.idempiere.test/src/org/idempiere/test/form/CreateFromShipmentFormTest.java index 0ade647cfb..cd8609308a 100644 --- a/org.idempiere.test/src/org/idempiere/test/form/CreateFromShipmentFormTest.java +++ b/org.idempiere.test/src/org/idempiere/test/form/CreateFromShipmentFormTest.java @@ -90,7 +90,7 @@ public class CreateFromShipmentFormTest extends AbstractTestCase { MOrderLine orderLine = new MOrderLine(order); orderLine.setLine(10); - orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id)); + orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id)); orderLine.setQty(new BigDecimal("1")); orderLine.setDatePromised(today); orderLine.saveEx(); @@ -170,7 +170,7 @@ public class CreateFromShipmentFormTest extends AbstractTestCase { MOrderLine orderLine = new MOrderLine(order); orderLine.setLine(10); - orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id)); + orderLine.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.HOLLY_BUSH.id)); orderLine.setQty(new BigDecimal("1")); orderLine.setDatePromised(today); orderLine.saveEx(); diff --git a/org.idempiere.test/src/org/idempiere/test/model/Allocation2ndAcctSchemaTest.java b/org.idempiere.test/src/org/idempiere/test/model/Allocation2ndAcctSchemaTest.java index 8f1d99180e..4149515aa5 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/Allocation2ndAcctSchemaTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/Allocation2ndAcctSchemaTest.java @@ -59,11 +59,14 @@ import org.compiere.model.Query; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.process.ProcessInfo; +import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.wf.MWorkflow; import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.ConversionRateHelper; import org.idempiere.test.DictionaryIDs; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; /** * @author Elaine Tan - etantg @@ -74,6 +77,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period) * Invoice Total=12,587.48, Period 1 @@ -179,6 +183,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period) * Invoice Total=12,587.48 @@ -189,7 +194,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-5053 */ public void testAllocateInvoicePaymentPosting_2() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Timestamp date = currentDate; @@ -265,6 +270,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period) * Payment Total=12,000, Period 1 @@ -273,7 +279,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4200 */ public void testAllocateInvoicePaymentPosting_3() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -336,6 +342,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period) * Payment Total=12,000 @@ -344,7 +351,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4200 */ public void testAllocateInvoicePaymentPosting_4() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Timestamp date = currentDate; @@ -396,6 +403,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period) * Invoice1 Total=9,362.50, Period 1 @@ -410,7 +418,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4200 */ public void testAllocateInvoicePaymentPosting_5() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -545,6 +553,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period) * Invoice1 Total=9,362.50 @@ -682,6 +691,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period) * Payment Total=12,000, Period 1 @@ -692,7 +702,8 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4127 */ public void testAllocateInvoicePaymentPosting_7() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id, getTrxName()); + DB.getDatabase().forUpdate(bpartner, 0); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -783,6 +794,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period) * Payment Total=12,000 @@ -793,7 +805,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4127 */ public void testAllocateInvoicePaymentPosting_8() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id, getTrxName()); // C&W Construction MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Timestamp date = currentDate; @@ -810,6 +822,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { try { MBankAccount ba = getBankAccount(usd.getC_Currency_ID()); BigDecimal payAmt = new BigDecimal(12000); + DB.getDatabase().forUpdate(bpartner, 0); MPayment payment = createPayment(true, bpartner, ba.getC_BankAccount_ID(), date, payAmt, euro.getC_Currency_ID(), C_ConversionType_ID); completeDocument(payment); postDocument(payment); @@ -873,6 +886,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period) * Invoice Total=12,000, Period 1 @@ -883,7 +897,9 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4127 */ public void testAllocateInvoicePaymentPosting_9() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id, getTrxName()); + DB.getDatabase().forUpdate(bpartner, 0); + MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -972,6 +988,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period) * Invoice Total=12,000 @@ -982,7 +999,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4127 */ public void testAllocateInvoicePaymentPosting_10() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Timestamp date = currentDate; @@ -1060,6 +1077,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period + reversal) * Invoice Total=1000, Period 1 @@ -1223,6 +1241,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period + reversal) * Payment Total=1000, Period 1 @@ -1231,7 +1250,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-5339 */ public void testAllocateInvoicePaymentPosting_12() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); // C&W Construction + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); @@ -1386,6 +1405,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period + reversal) * Invoice Total=1000, Period 1 @@ -1449,6 +1469,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period + reversal) * Invoice Total=1000 @@ -1456,7 +1477,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4696 */ public void testAllocateInvoicePosting_2() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Timestamp date = currentDate; @@ -1500,6 +1521,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period + offset) * Invoice Total=1000, Period 1 @@ -1507,7 +1529,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4696 */ public void testAllocateInvoicePosting_3() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); @@ -1572,6 +1594,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period + offset) * Invoice Total=1000 @@ -1579,7 +1602,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4696 */ public void testAllocateInvoicePosting_4() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id); MCharge charge = MCharge.get(Env.getCtx(), DictionaryIDs.C_Charge.FREIGHT.id); // Freight Charges Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Timestamp date = currentDate; @@ -1632,6 +1655,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period + reversal) * Payment Total=1000, Period 1 @@ -1639,7 +1663,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4696 */ public void testAllocatePaymentPosting_1() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1691,6 +1715,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period + reversal) * Payment Total=1000, Period 1 @@ -1738,6 +1763,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period + offset) * Payment Total=1000, Period 1 @@ -1745,7 +1771,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { * https://idempiere.atlassian.net/browse/IDEMPIERE-4696 */ public void testAllocatePaymentPosting_3() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.TREE_FARM.id); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1803,6 +1829,7 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (same period + offset) * Payment Total=1000 @@ -1862,34 +1889,11 @@ public class Allocation2ndAcctSchemaTest extends AbstractTestCase { private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID, Timestamp date, BigDecimal rate, boolean isMultiplyRate) { - MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null); - cr.setC_Currency_ID(C_Currency_ID); - cr.setC_Currency_ID_To(C_Currency_ID_To); - cr.setC_ConversionType_ID(C_ConversionType_ID); - cr.setValidFrom(date); - cr.setValidTo(date); - if (isMultiplyRate) - cr.setMultiplyRate(rate); - else - cr.setDivideRate(rate); - cr.saveEx(); - return cr; + return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate); } private void deleteConversionRate(MConversionRate cr) { - String whereClause = "ValidFrom=? AND ValidTo=? " - + "AND C_Currency_ID=? AND C_Currency_ID_To=? " - + "AND C_ConversionType_ID=? " - + "AND AD_Client_ID=? AND AD_Org_ID=?"; - MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null) - .setParameters(cr.getValidFrom(), cr.getValidTo(), - cr.getC_Currency_ID_To(), cr.getC_Currency_ID(), - cr.getC_ConversionType_ID(), - cr.getAD_Client_ID(), cr.getAD_Org_ID()) - .firstOnly(); - if (reciprocal != null) - reciprocal.deleteEx(true); - cr.deleteEx(true); + ConversionRateHelper.deleteConversionRate(cr); } private MInvoice createInvoice(boolean isSOTrx, MBPartner bpartner, Timestamp date, int M_PriceList_ID, int C_ConversionType_ID) { diff --git a/org.idempiere.test/src/org/idempiere/test/model/AllocationTest.java b/org.idempiere.test/src/org/idempiere/test/model/AllocationTest.java index 54ae952bab..ae648f37b4 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/AllocationTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/AllocationTest.java @@ -56,17 +56,22 @@ import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.process.ProcessInfo; import org.compiere.util.CLogErrorBuffer; +import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.TimeUtil; import org.compiere.wf.MWorkflow; import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.ConversionRateHelper; import org.idempiere.test.DictionaryIDs; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; +import org.junit.jupiter.api.parallel.ResourceLock; /** * @author Carlos Ruiz - globalqss * */ +@Isolated public class AllocationTest extends AbstractTestCase { /** @@ -176,12 +181,13 @@ public class AllocationTest extends AbstractTestCase { String trxName = getTrxName(); // Get the OpenBalance of C&W - MBPartner bpartner = new MBPartner(ctx, DictionaryIDs.C_BPartner.C_AND_W.id, trxName); + MBPartner bpartner = new MBPartner(ctx, DictionaryIDs.C_BPartner.PATIO.id, trxName); + DB.getDatabase().forUpdate(bpartner, 0); BigDecimal initialBalance = bpartner.getTotalOpenBalance(); // Create Invoice $100 MInvoice invoice = new MInvoice(ctx, 0, trxName); - invoice.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.C_AND_W.id)); + invoice.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.PATIO.id)); invoice.setC_DocTypeTarget_ID(MDocType.DOCBASETYPE_ARInvoice); invoice.setC_DocType_ID(invoice.getC_DocTypeTarget_ID()); // required to avoid runDocumentActionWorkflow exception invoice.setPaymentRule(MInvoice.PAYMENTRULE_Check); @@ -340,11 +346,12 @@ public class AllocationTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * https://idempiere.atlassian.net/browse/IDEMPIERE-4696 */ public void testPaymentReversePosting() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), 114); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.COLOR_INC.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -427,8 +434,9 @@ public class AllocationTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) public void testAllocatePaymentPosting() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), 114); // Tree Farm Inc. + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.CHROME_INC.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -532,34 +540,11 @@ public class AllocationTest extends AbstractTestCase { private MConversionRate createConversionRate(int C_Currency_ID, int C_Currency_ID_To, int C_ConversionType_ID, Timestamp date, BigDecimal rate, boolean isMultiplyRate) { - MConversionRate cr = new MConversionRate(Env.getCtx(), 0, null); - cr.setC_Currency_ID(C_Currency_ID); - cr.setC_Currency_ID_To(C_Currency_ID_To); - cr.setC_ConversionType_ID(C_ConversionType_ID); - cr.setValidFrom(date); - cr.setValidTo(date); - if (isMultiplyRate) - cr.setMultiplyRate(rate); - else - cr.setDivideRate(rate); - cr.saveEx(); - return cr; + return ConversionRateHelper.createConversionRate(C_Currency_ID, C_Currency_ID_To, C_ConversionType_ID, date, rate, isMultiplyRate); } private void deleteConversionRate(MConversionRate cr) { - String whereClause = "ValidFrom=? AND ValidTo=? " - + "AND C_Currency_ID=? AND C_Currency_ID_To=? " - + "AND C_ConversionType_ID=? " - + "AND AD_Client_ID=? AND AD_Org_ID=?"; - MConversionRate reciprocal = new Query(Env.getCtx(), MConversionRate.Table_Name, whereClause, null) - .setParameters(cr.getValidFrom(), cr.getValidTo(), - cr.getC_Currency_ID_To(), cr.getC_Currency_ID(), - cr.getC_ConversionType_ID(), - cr.getAD_Client_ID(), cr.getAD_Org_ID()) - .firstOnly(); - if (reciprocal != null) - reciprocal.deleteEx(true); - cr.deleteEx(true); + ConversionRateHelper.deleteConversionRate(cr); } private MPayment createReceiptPayment(int C_BPartner_ID, int C_BankAccount_ID, Timestamp date, int C_Currency_ID, int C_ConversionType_ID, BigDecimal payAmt) { @@ -893,7 +878,7 @@ public class AllocationTest extends AbstractTestCase { // #4 check accounts public void testAllocatePaymentPostingWithWriteOffandDiscountAPInv() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id); // Patio Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1023,7 +1008,7 @@ public class AllocationTest extends AbstractTestCase { // #4 check accounts public void testAllocatePaymentPostingWithWriteOffandDiscountAPCrMe() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id); // Patio Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1416,7 +1401,7 @@ public class AllocationTest extends AbstractTestCase { // #4 check accounts public void testPaymentPostingWithWriteOffandDiscountAPInv() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.AGRI_TECH.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1547,7 +1532,7 @@ public class AllocationTest extends AbstractTestCase { // #4 check accounts public void testPaymentPostingWithWriteOffandDiscountAPCrMe() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1678,7 +1663,7 @@ public class AllocationTest extends AbstractTestCase { // #4 Check accounts public void testAllocatePostingWithWriteOffandDiscountARInvARCrMe() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.JOE_BLOCK.id); + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1815,7 +1800,7 @@ public class AllocationTest extends AbstractTestCase { // #4 Check accounts public void testAllocatePostingWithWriteOffandDiscountAPInvAPCrMe() { - MBPartner bpartner = MBPartner.get(Env.getCtx(), 121); // Patio + MBPartner bpartner = MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.SEED_FARM.id); Timestamp currentDate = Env.getContextAsDate(Env.getCtx(), "#Date"); Calendar cal = Calendar.getInstance(); @@ -1943,6 +1928,7 @@ public class AllocationTest extends AbstractTestCase { } @Test + @ResourceLock(value = MConversionRate.Table_Name) /** * Test the allocation posting (different period) * Invoice Total=12,587.48, Period 1 @@ -1968,6 +1954,10 @@ public class AllocationTest extends AbstractTestCase { MCurrency usd = MCurrency.get(DictionaryIDs.C_Currency.USD.id); // USD MCurrency euro = MCurrency.get(DictionaryIDs.C_Currency.EUR.id); // EUR BigDecimal eurToUsd1 = new BigDecimal(32.458922422202); + + MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName()); + DB.getDatabase().forUpdate(bp, 0); + MConversionRate cr1 = createConversionRate(euro.getC_Currency_ID(), usd.getC_Currency_ID(), C_ConversionType_ID, date1, eurToUsd1, false); BigDecimal eurToUsd2 = new BigDecimal(33.93972535567); diff --git a/org.idempiere.test/src/org/idempiere/test/model/BankStatementTest.java b/org.idempiere.test/src/org/idempiere/test/model/BankStatementTest.java index bf4bac7921..9f963df4e3 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/BankStatementTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/BankStatementTest.java @@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.sql.Timestamp; +import org.compiere.model.MBPartner; import org.compiere.model.MBankStatement; import org.compiere.model.MBankStatementLine; import org.compiere.model.MPayment; @@ -40,6 +41,7 @@ import org.compiere.model.Query; import org.compiere.process.DocAction; import org.compiere.process.ProcessInfo; import org.compiere.util.CacheMgt; +import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.TimeUtil; @@ -47,6 +49,7 @@ import org.compiere.wf.MWorkflow; import org.idempiere.test.AbstractTestCase; import org.idempiere.test.DictionaryIDs; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; /** * @author hengsin @@ -88,6 +91,7 @@ public class BankStatementTest extends AbstractTestCase { } @Test + @ResourceLock(value = MSysConfig.ALLOW_REVERSAL_OF_RECONCILED_PAYMENT) public void testReversalOfReconciledPayment1() { Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); @@ -107,6 +111,9 @@ public class BankStatementTest extends AbstractTestCase { } try { + MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName()); + DB.getDatabase().forUpdate(bp, 0); + MPayment payment1 = new MPayment(Env.getCtx(), 0, getTrxName()); payment1.setC_BPartner_ID(DictionaryIDs.C_BPartner.C_AND_W.id); //C&W payment1.setC_DocType_ID(true); // Receipt @@ -169,6 +176,7 @@ public class BankStatementTest extends AbstractTestCase { } @Test + @ResourceLock(value = MSysConfig.ALLOW_REVERSAL_OF_RECONCILED_PAYMENT) public void testReversalOfReconciledPayment2() { Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); @@ -187,6 +195,9 @@ public class BankStatementTest extends AbstractTestCase { sysConfig = null; } try { + MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName()); + DB.getDatabase().forUpdate(bp, 0); + MPayment payment1 = new MPayment(Env.getCtx(), 0, getTrxName()); payment1.setC_BPartner_ID(DictionaryIDs.C_BPartner.C_AND_W.id); //C&W payment1.setC_DocType_ID(true); // Receipt diff --git a/org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java b/org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java index cce06368df..8b90320eed 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java @@ -29,15 +29,12 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; import java.sql.Timestamp; -import java.util.Arrays; import java.util.Properties; import org.compiere.model.MAcctSchema; -import org.compiere.model.MAttributeSet; import org.compiere.model.MAttributeSetInstance; import org.compiere.model.MBPartner; import org.compiere.model.MClient; @@ -48,16 +45,10 @@ import org.compiere.model.MInventory; import org.compiere.model.MInventoryLine; 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.MStorageOnHand; -import org.compiere.model.MWarehouse; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.process.ProcessInfo; -import org.compiere.util.CacheMgt; import org.compiere.util.Env; import org.compiere.util.TimeUtil; import org.compiere.wf.MWorkflow; @@ -189,194 +180,4 @@ public class InventoryTest extends AbstractTestCase { assertNull(error, error); } } - - @Test - public void testSkipProductWithSerial() { - Properties ctx = Env.getCtx(); - String trxName = getTrxName(); - - MAttributeSet set = new MAttributeSet(Env.getCtx(), DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id, null); - set.setIsSerNo(true); - set.saveEx(); - - MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null); - boolean disallow = wh.isDisallowNegativeInv(); - MProduct product = null; - try { - - if (!disallow) { - wh.setIsDisallowNegativeInv(true); - wh.saveEx(); - CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); - } - - product = new MProduct(ctx, 0, null); - product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); - product.setName("testSkipProductWithSerial"); - product.setValue("testSkipProductWithSerial"); - product.setProductType(MProduct.PRODUCTTYPE_Item); - product.setIsStocked(true); - product.setIsSold(true); - product.setIsPurchased(true); - product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); - product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); - product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - product.saveEx(); - - MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null); - MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName()); - pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID()); - pp.setM_Product_ID(product.get_ID()); - pp.setPriceStd(new BigDecimal("2")); - pp.setPriceList(new BigDecimal("2")); - pp.saveEx(); - - MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); - asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - asi.setSerNo("testSkipProductWithSerial #1"); - asi.saveEx(); - - createPOAndMRForProduct(product.get_ID(), asi); - - MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); - assertEquals(1, onhands.length, "Unexpected number of on hand records"); - assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record"); - - MInventory inventory = new MInventory(ctx, 0, trxName); - inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id); - inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id); - inventory.saveEx(); - - MInventoryLine iline = new MInventoryLine(inventory, - DictionaryIDs.M_Locator.HQ.id, - product.getM_Product_ID(), - 0, // M_AttributeSetInstance_ID - Env.ONE, // QtyBook - Env.ZERO); - iline.saveEx(); - - //should error out with negative on hand (skip the only asi record with serno) - ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); - assertTrue(info.isError(), info.getSummary()); - } finally { - rollback(); - set.setIsSerNo(false); - set.saveEx(); - - if (product != null) - product.deleteEx(true); - - if (!disallow) { - wh.setIsDisallowNegativeInv(false); - wh.saveEx(); - CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); - } - } - } - - @Test - public void testSkipProductWithSerial2() { - Properties ctx = Env.getCtx(); - String trxName = getTrxName(); - - MAttributeSet set = new MAttributeSet(Env.getCtx(), DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id, null); - set.setIsSerNo(true); - set.saveEx(); - - MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null); - boolean disallow = wh.isDisallowNegativeInv(); - MProduct product = null; - try { - - if (!disallow) { - wh.setIsDisallowNegativeInv(true); - wh.saveEx(); - CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); - } - - product = new MProduct(ctx, 0, null); - product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); - product.setName("testSkipProductWithSerial"); - product.setValue("testSkipProductWithSerial"); - product.setProductType(MProduct.PRODUCTTYPE_Item); - product.setIsStocked(true); - product.setIsSold(true); - product.setIsPurchased(true); - product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); - product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); - product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - product.saveEx(); - - MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null); - MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName()); - pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID()); - pp.setM_Product_ID(product.get_ID()); - pp.setPriceStd(new BigDecimal("2")); - pp.setPriceList(new BigDecimal("2")); - pp.saveEx(); - - MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); - asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - asi.setSerNo("testSkipProductWithSerial #1"); - asi.saveEx(); - - createPOAndMRForProduct(product.get_ID(), asi); - - MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); - assertEquals(1, onhands.length, "Unexpected number of on hand records"); - assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record"); - - MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); - asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - asi1.saveEx(); - - createPOAndMRForProduct(product.get_ID(), asi1); - - onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); - assertEquals(2, onhands.length, "Unexpected number of on hand records"); - Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null)); - assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record"); - assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record"); - - MInventory inventory = new MInventory(ctx, 0, trxName); - inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id); - inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id); - inventory.saveEx(); - - MInventoryLine iline = new MInventoryLine(inventory, - DictionaryIDs.M_Locator.HQ.id, - product.getM_Product_ID(), - 0, // M_AttributeSetInstance_ID - new BigDecimal("2"), // QtyBook - new BigDecimal("1")); - iline.saveEx(); - - //should success with qty difference being applied to the asi with null serno record - ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); - assertFalse(info.isError(), info.getSummary()); - inventory.load(getTrxName()); - assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus()); - - onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); - assertEquals(2, onhands.length, "Unexpected number of on hand records"); - Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null)); - assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record"); - assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record"); - assertEquals(1, onhands[0].getQtyOnHand().intValue()); - assertEquals(0, onhands[1].getQtyOnHand().intValue()); - } finally { - rollback(); - set.setIsSerNo(false); - set.saveEx(); - - if (product != null) - product.deleteEx(true); - - if (!disallow) { - wh.setIsDisallowNegativeInv(false); - wh.saveEx(); - CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); - } - } - } } diff --git a/org.idempiere.test/src/org/idempiere/test/model/InventoryTestIsolated.java b/org.idempiere.test/src/org/idempiere/test/model/InventoryTestIsolated.java new file mode 100644 index 0000000000..c523325520 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/InventoryTestIsolated.java @@ -0,0 +1,298 @@ +/*********************************************************************** + * 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: * + * - Carlos Ruiz - globalqss * + **********************************************************************/ +package org.idempiere.test.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Properties; + +import org.compiere.model.MAttributeSetInstance; +import org.compiere.model.MBPartner; +import org.compiere.model.MInOut; +import org.compiere.model.MInOutLine; +import org.compiere.model.MInventory; +import org.compiere.model.MInventoryLine; +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.MStorageOnHand; +import org.compiere.model.MWarehouse; +import org.compiere.process.DocAction; +import org.compiere.process.DocumentEngine; +import org.compiere.process.ProcessInfo; +import org.compiere.util.CacheMgt; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; +import org.compiere.wf.MWorkflow; +import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.DictionaryIDs; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; + +/** + * + * @author hengsin + * + */ +@Isolated +public class InventoryTestIsolated extends AbstractTestCase { + + public InventoryTestIsolated() { + } + + @Test + public void testSkipProductWithSerial() { + Properties ctx = Env.getCtx(); + String trxName = getTrxName(); + + MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null); + boolean disallow = wh.isDisallowNegativeInv(); + MProduct product = null; + try { + + if (!disallow) { + wh.setIsDisallowNegativeInv(true); + wh.saveEx(); + CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); + } + + product = new MProduct(ctx, 0, null); + product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); + product.setName("testSkipProductWithSerial"); + product.setValue("testSkipProductWithSerial"); + product.setProductType(MProduct.PRODUCTTYPE_Item); + product.setIsStocked(true); + product.setIsSold(true); + product.setIsPurchased(true); + product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); + product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); + product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id); + product.saveEx(); + + MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null); + MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName()); + pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID()); + pp.setM_Product_ID(product.get_ID()); + pp.setPriceStd(new BigDecimal("2")); + pp.setPriceList(new BigDecimal("2")); + pp.saveEx(); + + MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); + asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id); + asi.setSerNo("testSkipProductWithSerial #1"); + asi.saveEx(); + + createPOAndMRForProduct(product.get_ID(), asi); + + MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); + assertEquals(1, onhands.length, "Unexpected number of on hand records"); + assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record"); + + MInventory inventory = new MInventory(ctx, 0, trxName); + inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id); + inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id); + inventory.saveEx(); + + MInventoryLine iline = new MInventoryLine(inventory, + DictionaryIDs.M_Locator.HQ.id, + product.getM_Product_ID(), + 0, // M_AttributeSetInstance_ID + Env.ONE, // QtyBook + Env.ZERO); + iline.saveEx(); + + //should error out with negative on hand (skip the only asi record with serno) + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); + assertTrue(info.isError(), info.getSummary()); + } finally { + rollback(); + + if (product != null) + product.deleteEx(true); + + if (!disallow) { + wh.setIsDisallowNegativeInv(false); + wh.saveEx(); + CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); + } + } + } + + @Test + public void testSkipProductWithSerial2() { + Properties ctx = Env.getCtx(); + String trxName = getTrxName(); + + MWarehouse wh = new MWarehouse(Env.getCtx(), DictionaryIDs.M_Warehouse.HQ.id, null); + boolean disallow = wh.isDisallowNegativeInv(); + MProduct product = null; + try { + + if (!disallow) { + wh.setIsDisallowNegativeInv(true); + wh.saveEx(); + CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); + } + + product = new MProduct(ctx, 0, null); + product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); + product.setName("testSkipProductWithSerial2"); + product.setValue("testSkipProductWithSerial2"); + product.setProductType(MProduct.PRODUCTTYPE_Item); + product.setIsStocked(true); + product.setIsSold(true); + product.setIsPurchased(true); + product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); + product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); + product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id); + product.saveEx(); + + MPriceListVersion plv = MPriceList.get(DictionaryIDs.M_PriceList.PURCHASE.id).getPriceListVersion(null); + MProductPrice pp = new MProductPrice(Env.getCtx(), 0, getTrxName()); + pp.setM_PriceList_Version_ID(plv.getM_PriceList_Version_ID()); + pp.setM_Product_ID(product.get_ID()); + pp.setPriceStd(new BigDecimal("2")); + pp.setPriceList(new BigDecimal("2")); + pp.saveEx(); + + MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); + asi.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id); + asi.setSerNo("testSkipProductWithSerial2 #1"); + asi.saveEx(); + + createPOAndMRForProduct(product.get_ID(), asi); + + MStorageOnHand[] onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); + assertEquals(1, onhands.length, "Unexpected number of on hand records"); + assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for on hand record"); + + MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); + asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.PATIO_CHAIR.id); + asi1.saveEx(); + + createPOAndMRForProduct(product.get_ID(), asi1); + + onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); + assertEquals(2, onhands.length, "Unexpected number of on hand records"); + Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null)); + assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record"); + assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record"); + + MInventory inventory = new MInventory(ctx, 0, trxName); + inventory.setM_Warehouse_ID(DictionaryIDs.M_Warehouse.HQ.id); + inventory.setC_DocType_ID(DictionaryIDs.C_DocType.MATERIAL_PHYSICAL_INVENTORY.id); + inventory.saveEx(); + + MInventoryLine iline = new MInventoryLine(inventory, + DictionaryIDs.M_Locator.HQ.id, + product.getM_Product_ID(), + 0, // M_AttributeSetInstance_ID + new BigDecimal("2"), // QtyBook + new BigDecimal("1")); + iline.saveEx(); + + //should success with qty difference being applied to the asi with null serno record + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + inventory.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus()); + + onhands = MStorageOnHand.getOfProduct(Env.getCtx(), product.get_ID(), getTrxName()); + assertEquals(2, onhands.length, "Unexpected number of on hand records"); + Arrays.sort(onhands, new MStorageOnHand(Env.getCtx(), 0, null)); + assertEquals(onhands[0].getM_AttributeSetInstance_ID(), asi.get_ID(), "Unexpected M_AttributeSetInstance_ID for first on hand record"); + assertEquals(onhands[1].getM_AttributeSetInstance_ID(), asi1.get_ID(), "Unexpected M_AttributeSetInstance_ID for second on hand record"); + assertEquals(1, onhands[0].getQtyOnHand().intValue()); + assertEquals(0, onhands[1].getQtyOnHand().intValue()); + } finally { + rollback(); + + if (product != null) + product.deleteEx(true); + + if (!disallow) { + wh.setIsDisallowNegativeInv(false); + wh.saveEx(); + CacheMgt.get().reset(MWarehouse.Table_Name, wh.get_ID()); + } + } + } + + private void createPOAndMRForProduct(int productId, MAttributeSetInstance asi) { + MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); + order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id)); + order.setC_DocTypeTarget_ID(DictionaryIDs.C_DocType.PURCHASE_ORDER.id); + order.setIsSOTrx(false); + order.setSalesRep_ID(DictionaryIDs.AD_User.GARDEN_ADMIN.id); + order.setDocStatus(DocAction.STATUS_Drafted); + order.setDocAction(DocAction.ACTION_Complete); + Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); + order.setDateOrdered(today); + order.setDatePromised(today); + order.saveEx(); + + MOrderLine line1 = new MOrderLine(order); + line1.setLine(10); + line1.setProduct(new MProduct(Env.getCtx(), productId, getTrxName())); + 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()); + + MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered()); + receipt1.setDocStatus(DocAction.STATUS_Drafted); + receipt1.setDocAction(DocAction.ACTION_Complete); + receipt1.saveEx(); + + MInOutLine receiptLine1 = new MInOutLine(receipt1); + receiptLine1.setOrderLine(line1, 0, new BigDecimal("1")); + receiptLine1.setQty(new BigDecimal("1")); + if (asi != null) + receiptLine1.setM_AttributeSetInstance_ID(asi.get_ID()); + receiptLine1.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(receipt1, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + receipt1.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, receipt1.getDocStatus()); + if (!receipt1.isPosted()) { + String error = DocumentEngine.postImmediate(Env.getCtx(), receipt1.getAD_Client_ID(), receipt1.get_Table_ID(), receipt1.get_ID(), false, getTrxName()); + assertNull(error, error); + } + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java b/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java index 2254df65b0..6ec5496669 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/InvoiceCustomerTest.java @@ -60,10 +60,12 @@ import org.compiere.wf.MWorkflow; import org.idempiere.test.AbstractTestCase; import org.idempiere.test.DictionaryIDs; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; /** * @author Carlos Ruiz - globalqss */ +@Isolated public class InvoiceCustomerTest extends AbstractTestCase { public InvoiceCustomerTest() { @@ -81,6 +83,9 @@ public class InvoiceCustomerTest extends AbstractTestCase { if (errorLogs != null) severeCount = errorLogs.length; + MBPartner bp = new MBPartner (Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id, getTrxName()); + DB.getDatabase().forUpdate(bp, 0); + // Invoice $200 today MInvoice invoice = new MInvoice(Env.getCtx(), 0, getTrxName()); invoice.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.C_AND_W.id)); // C&W diff --git a/org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTest.java b/org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTest.java index 7928704a07..81b1351755 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTest.java @@ -25,25 +25,16 @@ package org.idempiere.test.model; 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 java.math.BigDecimal; import java.sql.Timestamp; -import java.util.List; import org.compiere.model.MAttributeSet; import org.compiere.model.MAttributeSetInstance; import org.compiere.model.MLocator; -import org.compiere.model.MPInstance; -import org.compiere.model.MPInstancePara; -import org.compiere.model.MProcess; import org.compiere.model.MProduct; import org.compiere.model.MStorageOnHand; -import org.compiere.model.Query; -import org.compiere.model.SystemIDs; -import org.compiere.process.ProcessInfo; -import org.compiere.process.ServerProcessCtl; import org.compiere.util.CacheMgt; import org.compiere.util.DB; import org.compiere.util.Env; @@ -196,172 +187,5 @@ public class MStorageOnHandTest extends AbstractTestCase { MStorageOnHand.add(Env.getCtx(), hqLocator1.get_ID(), product.get_ID(), asi1.get_ID(), new BigDecimal("2"), today, getTrxName()); M_Locator_ID = MStorageOnHand.getM_Locator_ID(hqLocator.getM_Warehouse_ID(), product.get_ID(), -1, new BigDecimal("1"), getTrxName()); assertEquals(hqLocator1.get_ID(), M_Locator_ID); - } - - @Test - public void testStorageCleanUp() { - MProduct product = new MProduct(Env.getCtx(), 0, getTrxName()); - product.setName("testStorageCleanUp"); - product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - product.setIsStocked(true); - product.setProductType(MProduct.PRODUCTTYPE_Item); - product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); - product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); - product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); - product.saveEx(); - - Timestamp today = TimeUtil.getDay(null); - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("2"), today, getTrxName()); - Query query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); - int count = query.setParameters(product.get_ID()).count(); - assertEquals(1, count); - - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("-2"), today, getTrxName()); - DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product.get_ID()}, getTrxName()); - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); - count = query.setParameters(product.get_ID()).count(); - assertEquals(1, count); - - //movement get product from cache - MProduct product1 = new MProduct(Env.getCtx(), 0, null); - product1.setName("testStorageCleanUp#1"); - product1.setValue(product1.getName()); - product1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - product1.setIsStocked(true); - product1.setProductType(MProduct.PRODUCTTYPE_Item); - product1.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); - product1.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); - product1.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); - product1.saveEx(); - - try { - MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); - asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - asi1.setLot("Lot1"); - asi1.saveEx(); - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), asi1.get_ID(), new BigDecimal("-1"), today, getTrxName()); - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), 0, new BigDecimal("1"), today, getTrxName()); - - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - MStorageOnHand onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first(); - assertNotNull(onhand); - assertEquals(-1, onhand.getQtyOnHand().intValue()); - - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - onhand = query.setParameters(product1.get_ID(), 0).first(); - assertNotNull(onhand); - assertEquals(1, onhand.getQtyOnHand().intValue()); - - MProduct product2 = new MProduct(Env.getCtx(), 0, getTrxName()); - product2.setName("testStorageCleanUp#2"); - product2.setValue(product2.getName()); - product2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - product2.setIsStocked(true); - product2.setProductType(MProduct.PRODUCTTYPE_Item); - product2.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); - product2.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); - product2.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); - product2.saveEx(); - - MAttributeSetInstance asi2 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); - asi2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - asi2.setLot("LotX"); - asi2.saveEx(); - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi2.get_ID(), new BigDecimal("-1"), today, getTrxName()); - - MAttributeSetInstance asi3 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); - asi3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - asi3.setLot("LotY"); - asi3.saveEx(); - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi3.get_ID(), new BigDecimal("1"), today, getTrxName()); - - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first(); - assertNotNull(onhand); - assertEquals(-1, onhand.getQtyOnHand().intValue()); - - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first(); - assertNotNull(onhand); - assertEquals(1, onhand.getQtyOnHand().intValue()); - - MProduct product3 = new MProduct(Env.getCtx(), 0, getTrxName()); - product3.setName("testStorageCleanUp#3"); - product3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - product3.setIsStocked(true); - product3.setProductType(MProduct.PRODUCTTYPE_Item); - product3.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); - product3.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); - product3.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); - product3.saveEx(); - - MAttributeSetInstance asi4 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); - asi4.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); - asi4.setSerNo(product3.getName()+"SerialNo#1"); - asi4.saveEx(); - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("1"), today, getTrxName()); - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); - count = query.setParameters(product3.get_ID()).count(); - assertEquals(1, count); - - MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("-1"), today, getTrxName()); - DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product3.get_ID()}, getTrxName()); - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); - count = query.setParameters(product3.get_ID()).count(); - assertEquals(1, count); - - MPInstance instance = new MPInstance(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup, 0); - instance.saveEx(); - MPInstancePara para = new MPInstancePara(instance, 10); - para.setParameterName("C_DocType_ID"); - para.setP_Number(DictionaryIDs.C_DocType.MATERIAL_MOVEMENT.id); - para.saveEx(); - - MProcess process = MProcess.get(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup); - ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID()); - pi.setAD_PInstance_ID(instance.get_ID()); - pi.setAD_Client_ID(getAD_Client_ID()); - pi.setAD_User_ID(getAD_User_ID()); - pi.setTransactionName(getTrxName()); - ServerProcessCtl.process(pi, getTrx(), false); - assertFalse(pi.isError(), pi.getSummary()); - - //check 0 stock removed - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); - count = query.setParameters(product.get_ID()).count(); - assertEquals(0, count); - - //check 0 stock with serno not removed - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); - List onhands = query.setParameters(product3.get_ID()).list(); - assertEquals(1, onhands.size()); - assertEquals(0, onhands.get(0).getQtyOnHand().intValue()); - assertEquals(asi4.get_ID(), onhands.get(0).getM_AttributeSetInstance_ID()); - - //check -1 and 1 consolidated - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first(); - assertNotNull(onhand); - assertEquals(0, onhand.getQtyOnHand().intValue()); - - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - onhand = query.setParameters(product1.get_ID(), 0).first(); - assertNotNull(onhand); - assertEquals(0, onhand.getQtyOnHand().intValue()); - - //check -1 and 1 not consolidated due to different lot - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first(); - assertNotNull(onhand); - assertEquals(-1, onhand.getQtyOnHand().intValue()); - - query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); - onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first(); - assertNotNull(onhand); - assertEquals(1, onhand.getQtyOnHand().intValue()); - } finally { - getTrx().rollback(); - product1.deleteEx(true); - } - } + } } diff --git a/org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTestIsolated.java b/org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTestIsolated.java new file mode 100644 index 0000000000..f916104c83 --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/MStorageOnHandTestIsolated.java @@ -0,0 +1,230 @@ +/*********************************************************************** + * 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.model; + +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 java.math.BigDecimal; +import java.sql.Timestamp; +import java.util.List; + +import org.compiere.model.MAttributeSetInstance; +import org.compiere.model.MPInstance; +import org.compiere.model.MPInstancePara; +import org.compiere.model.MProcess; +import org.compiere.model.MProduct; +import org.compiere.model.MStorageOnHand; +import org.compiere.model.Query; +import org.compiere.model.SystemIDs; +import org.compiere.process.ProcessInfo; +import org.compiere.process.ServerProcessCtl; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; +import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.DictionaryIDs; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; + +/** + * + * @author hengsin + * + */ +@Isolated +public class MStorageOnHandTestIsolated extends AbstractTestCase { + + public MStorageOnHandTestIsolated() { + } + + @Test + public void testStorageCleanUp() { + MProduct product = new MProduct(Env.getCtx(), 0, getTrxName()); + product.setName("testStorageCleanUp"); + product.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + product.setIsStocked(true); + product.setProductType(MProduct.PRODUCTTYPE_Item); + product.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); + product.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); + product.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); + product.saveEx(); + + Timestamp today = TimeUtil.getDay(null); + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("2"), today, getTrxName()); + Query query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); + int count = query.setParameters(product.get_ID()).count(); + assertEquals(1, count); + + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product.get_ID(), 0, new BigDecimal("-2"), today, getTrxName()); + DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product.get_ID()}, getTrxName()); + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); + count = query.setParameters(product.get_ID()).count(); + assertEquals(1, count); + + //movement get product from cache + MProduct product1 = new MProduct(Env.getCtx(), 0, null); + product1.setName("testStorageCleanUp#1"); + product1.setValue(product1.getName()); + product1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + product1.setIsStocked(true); + product1.setProductType(MProduct.PRODUCTTYPE_Item); + product1.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); + product1.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); + product1.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); + product1.saveEx(); + + try { + MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); + asi1.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + asi1.setLot("Lot1"); + asi1.saveEx(); + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), asi1.get_ID(), new BigDecimal("-1"), today, getTrxName()); + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product1.get_ID(), 0, new BigDecimal("1"), today, getTrxName()); + + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + MStorageOnHand onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first(); + assertNotNull(onhand); + assertEquals(-1, onhand.getQtyOnHand().intValue()); + + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + onhand = query.setParameters(product1.get_ID(), 0).first(); + assertNotNull(onhand); + assertEquals(1, onhand.getQtyOnHand().intValue()); + + MProduct product2 = new MProduct(Env.getCtx(), 0, getTrxName()); + product2.setName("testStorageCleanUp#2"); + product2.setValue(product2.getName()); + product2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + product2.setIsStocked(true); + product2.setProductType(MProduct.PRODUCTTYPE_Item); + product2.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); + product2.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); + product2.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); + product2.saveEx(); + + MAttributeSetInstance asi2 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); + asi2.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + asi2.setLot("LotX"); + asi2.saveEx(); + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi2.get_ID(), new BigDecimal("-1"), today, getTrxName()); + + MAttributeSetInstance asi3 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); + asi3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + asi3.setLot("LotY"); + asi3.saveEx(); + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product2.get_ID(), asi3.get_ID(), new BigDecimal("1"), today, getTrxName()); + + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first(); + assertNotNull(onhand); + assertEquals(-1, onhand.getQtyOnHand().intValue()); + + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first(); + assertNotNull(onhand); + assertEquals(1, onhand.getQtyOnHand().intValue()); + + MProduct product3 = new MProduct(Env.getCtx(), 0, getTrxName()); + product3.setName("testStorageCleanUp#3"); + product3.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + product3.setIsStocked(true); + product3.setProductType(MProduct.PRODUCTTYPE_Item); + product3.setC_UOM_ID(DictionaryIDs.C_UOM.EACH.id); + product3.setM_Product_Category_ID(DictionaryIDs.M_Product_Category.CHEMICALS.id); + product3.setC_TaxCategory_ID(DictionaryIDs.C_TaxCategory.STANDARD.id); + product3.saveEx(); + + MAttributeSetInstance asi4 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName()); + asi4.setM_AttributeSet_ID(DictionaryIDs.M_AttributeSet.FERTILIZER_LOT.id); + asi4.setSerNo(product3.getName()+"SerialNo#1"); + asi4.saveEx(); + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("1"), today, getTrxName()); + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); + count = query.setParameters(product3.get_ID()).count(); + assertEquals(1, count); + + MStorageOnHand.add(Env.getCtx(), DictionaryIDs.M_Locator.HQ.id, product3.get_ID(), asi4.get_ID(), new BigDecimal("-1"), today, getTrxName()); + DB.executeUpdateEx("UPDATE M_StorageOnHand SET Created=? WHERE M_Product_ID=?", new Object[] {TimeUtil.addDays(today, -7), product3.get_ID()}, getTrxName()); + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); + count = query.setParameters(product3.get_ID()).count(); + assertEquals(1, count); + + MPInstance instance = new MPInstance(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup, 0); + instance.saveEx(); + MPInstancePara para = new MPInstancePara(instance, 10); + para.setParameterName("C_DocType_ID"); + para.setP_Number(DictionaryIDs.C_DocType.MATERIAL_MOVEMENT.id); + para.saveEx(); + + MProcess process = MProcess.get(Env.getCtx(), SystemIDs.PROCESS_M_StorageCleanup); + ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID()); + pi.setAD_PInstance_ID(instance.get_ID()); + pi.setAD_Client_ID(getAD_Client_ID()); + pi.setAD_User_ID(getAD_User_ID()); + pi.setTransactionName(getTrxName()); + ServerProcessCtl.process(pi, getTrx(), false); + assertFalse(pi.isError(), pi.getSummary()); + + //check 0 stock removed + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); + count = query.setParameters(product.get_ID()).count(); + assertEquals(0, count); + + //check 0 stock with serno not removed + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName()); + List onhands = query.setParameters(product3.get_ID()).list(); + assertEquals(1, onhands.size()); + assertEquals(0, onhands.get(0).getQtyOnHand().intValue()); + assertEquals(asi4.get_ID(), onhands.get(0).getM_AttributeSetInstance_ID()); + + //check -1 and 1 consolidated + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + onhand = query.setParameters(product1.get_ID(), asi1.get_ID()).first(); + assertNotNull(onhand); + assertEquals(0, onhand.getQtyOnHand().intValue()); + + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + onhand = query.setParameters(product1.get_ID(), 0).first(); + assertNotNull(onhand); + assertEquals(0, onhand.getQtyOnHand().intValue()); + + //check -1 and 1 not consolidated due to different lot + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + onhand = query.setParameters(product2.get_ID(), asi2.get_ID()).first(); + assertNotNull(onhand); + assertEquals(-1, onhand.getQtyOnHand().intValue()); + + query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName()); + onhand = query.setParameters(product2.get_ID(), asi3.get_ID()).first(); + assertNotNull(onhand); + assertEquals(1, onhand.getQtyOnHand().intValue()); + } finally { + getTrx().rollback(); + product1.deleteEx(true); + } + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/MTaxTest.java b/org.idempiere.test/src/org/idempiere/test/model/MTaxTest.java index 67e08f8a8b..e483394faa 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/MTaxTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/MTaxTest.java @@ -102,14 +102,14 @@ public class MTaxTest extends AbstractTestCase { bp.setIsTaxExempt(true); bp.saveEx(); - int id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(), + int id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(), bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName()); assertEquals(taxExemptId, id, "Unexpected tax id"); bp.setIsTaxExempt(false); bp.saveEx(); - id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(), + id = Core.getTaxLookup().get(Env.getCtx(), DictionaryIDs.M_Product.AZALEA_BUSH.id, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(), bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName()); assertTrue(id != taxExemptId, "Unexpected tax id: " + id); assertEquals(DictionaryIDs.C_Tax.STANDARD.id, id, "Unexpected tax id"); @@ -138,7 +138,7 @@ public class MTaxTest extends AbstractTestCase { CacheMgt.get().reset(); //need to create product with trx as order line get product from cache - MProduct p = MProduct.get(DictionaryIDs.M_Product.MULCH.id); + MProduct p = MProduct.get(DictionaryIDs.M_Product.AZALEA_BUSH.id); product = new MProduct(Env.getCtx(), 0, null); product.setM_Product_Category_ID(p.getM_Product_Category_ID()); product.setC_TaxCategory_ID(category.get_ID()); @@ -281,7 +281,7 @@ public class MTaxTest extends AbstractTestCase { CacheMgt.get().reset(); //need to create product with trx as order line get product from cache - MProduct p = MProduct.get(DictionaryIDs.M_Product.MULCH.id); + MProduct p = MProduct.get(DictionaryIDs.M_Product.AZALEA_BUSH.id); product = new MProduct(Env.getCtx(), 0, null); product.setM_Product_Category_ID(p.getM_Product_Category_ID()); product.setC_TaxCategory_ID(category.get_ID()); diff --git a/org.idempiere.test/src/org/idempiere/test/model/ModelClassMappingTest.java b/org.idempiere.test/src/org/idempiere/test/model/ModelClassMappingTest.java index 75ce9ee9d0..8fcea8fc5b 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/ModelClassMappingTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/ModelClassMappingTest.java @@ -40,6 +40,7 @@ import org.compiere.model.Query; import org.compiere.util.Env; import org.idempiere.test.AbstractTestCase; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.type.filter.AssignableTypeFilter; @@ -48,6 +49,7 @@ import org.springframework.core.type.filter.AssignableTypeFilter; * @author hengsin * */ +@Isolated public class ModelClassMappingTest extends AbstractTestCase { //copy from DefaultModelFactory diff --git a/org.idempiere.test/src/org/idempiere/test/model/ProductionTest.java b/org.idempiere.test/src/org/idempiere/test/model/ProductionTest.java index c4b4afe7b1..d41ca5d947 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/ProductionTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/ProductionTest.java @@ -31,26 +31,17 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; -import java.math.RoundingMode; import java.sql.Timestamp; import java.util.List; -import org.compiere.model.MAccount; import org.compiere.model.MAcctSchema; import org.compiere.model.MAttributeSetInstance; import org.compiere.model.MBPartner; -import org.compiere.model.MClient; -import org.compiere.model.MCost; import org.compiere.model.MCostElement; -import org.compiere.model.MFactAcct; import org.compiere.model.MInOut; import org.compiere.model.MInOutLine; -import org.compiere.model.MInventory; -import org.compiere.model.MInventoryLine; import org.compiere.model.MOrder; import org.compiere.model.MOrderLine; -import org.compiere.model.MPInstance; -import org.compiere.model.MPInstancePara; import org.compiere.model.MPriceList; import org.compiere.model.MPriceListVersion; import org.compiere.model.MProcess; @@ -61,7 +52,6 @@ import org.compiere.model.MProductPrice; import org.compiere.model.MProduction; import org.compiere.model.MProductionLine; import org.compiere.model.MStorageOnHand; -import org.compiere.model.ProductCost; import org.compiere.model.Query; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; @@ -83,97 +73,6 @@ import org.junit.jupiter.api.Test; * */ public class ProductionTest extends AbstractTestCase { - - @Test - public void testAverageCostingProduction() { - int mulchId = 137; - int hqLocator = 101; - - createPOAndMRForProduct(mulchId); - - MProduct mulch = MProduct.get(mulchId); - BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); - BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()); - - MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName()); - mulchX.setName("Mulch X"); - mulchX.setIsBOM(true); - mulchX.setIsStocked(true); - mulchX.setC_UOM_ID(mulch.getC_UOM_ID()); - mulchX.setM_Product_Category_ID(mulch.getM_Product_Category_ID()); - mulchX.setProductType(mulch.getProductType()); - mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID()); - mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID()); - mulchX.saveEx(); - BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); - - MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName()); - bom.setM_Product_ID(mulchX.get_ID()); - bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive); - bom.setBOMUse(MPPProductBOM.BOMUSE_Master); - bom.setName(mulchX.getName()); - bom.saveEx(); - - MPPProductBOMLine line = new MPPProductBOMLine(bom); - line.setM_Product_ID(mulchId); - line.setQtyBOM(new BigDecimal("1")); - line.saveEx(); - - mulchX.load(getTrxName()); - mulchX.setIsVerified(true); - mulchX.saveEx(); - - MProduction production = new MProduction(Env.getCtx(), 0, getTrxName()); - production.setM_Product_ID(mulchX.get_ID()); - production.setM_Locator_ID(hqLocator); - production.setIsUseProductionPlan(false); - production.setMovementDate(getLoginDate()); - production.setDocAction(DocAction.ACTION_Complete); - production.setDocStatus(DocAction.STATUS_Drafted); - production.setIsComplete(false); - production.setProductionQty(new BigDecimal("1")); - production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID()); - production.saveEx(); - - int productionCreate = 53226; - MProcess process = MProcess.get(Env.getCtx(), productionCreate); - ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID()); - pi.setAD_Client_ID(getAD_Client_ID()); - pi.setAD_User_ID(getAD_User_ID()); - pi.setRecord_ID(production.get_ID()); - pi.setTransactionName(getTrxName()); - ServerProcessCtl.process(pi, getTrx(), false); - assertFalse(pi.isError(), pi.getSummary()); - - production.load(getTrxName()); - assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y"); - assertTrue(production.getLines().length > 0, "No Production Lines"); - - ProcessInfo info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete); - production.load(getTrxName()); - assertFalse(info.isError(), info.getSummary()); - assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus()); - - BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); - BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); - - BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0); - BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0); - assertEquals(new BigDecimal("-1"), componentChange, "On hand of component doesn't reduce as expected"); - assertEquals(new BigDecimal("1"), endProductChange, "On hand of end product doesn't increase as expected"); - - if (!production.isPosted()) { - String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName()); - assertNull(msg, msg); - } - - BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName()); - MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); - componentCost = componentCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - endProductCost = endProductCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - assertEquals(componentCost, endProductCost, "Cost not roll up correctly"); - } - // creates an order and material receipt for qty 25 at special price of 2.60 each private void createPOAndMRForProduct(int mulchId) { MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); @@ -220,243 +119,7 @@ public class ProductionTest extends AbstractTestCase { assertNull(error, error); } } - - @Test - public void testStandardCostingProduction() { - MProductCategory category = new MProductCategory(Env.getCtx(), 0, null); - category.setName("Standard Costing"); - category.saveEx(); - - String whereClause = "M_Product_Category_ID=?"; - List categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null) - .setParameters(category.get_ID()) - .list(); - for (MProductCategoryAcct categoryAcct : categoryAccts) { - categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); - categoryAcct.saveEx(); - } - // ProductCost api doesn't use trx to retrieve product - int mulchId = 137; - MProduct mulch = new MProduct(Env.getCtx(), mulchId, null); - int categorySaveId = mulch.getM_Product_Category_ID(); - mulch.setM_Product_Category_ID(category.get_ID()); - mulch.saveEx(); - - try { - int hqLocator = 101; - createPOAndMRForProduct(mulchId); - - BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); - BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()); - - MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName()); - mulchX.setName("Mulch X"); - mulchX.setIsBOM(true); - mulchX.setIsStocked(true); - mulchX.setC_UOM_ID(mulch.getC_UOM_ID()); - mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID()); - mulchX.setProductType(mulch.getProductType()); - mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID()); - mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID()); - mulchX.saveEx(); - BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); - int costAdjustmentDocTypeId = 200004; - MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName()); - inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); - inventory.setC_DocType_ID(costAdjustmentDocTypeId); - inventory.setM_Warehouse_ID(getM_Warehouse_ID()); - inventory.setMovementDate(getLoginDate()); - inventory.setDocAction(DocAction.ACTION_Complete); - inventory.saveEx(); - - MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); - BigDecimal endProductCost = new BigDecimal("2.50").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName()); - il.setM_Inventory_ID(inventory.get_ID()); - il.setM_Locator_ID(hqLocator); - il.setM_Product_ID(mulchX.getM_Product_ID()); - il.setCurrentCostPrice(new BigDecimal("0")); - il.setNewCostPrice(endProductCost); - il.saveEx(); - - ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); - inventory.load(getTrxName()); - assertFalse(info.isError(), info.getSummary()); - assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus()); - - if (!inventory.isPosted()) { - String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName()); - assertNull(msg, msg); - } - BigDecimal adjusted = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - assertEquals(endProductCost, adjusted, "Cost not adjusted: " + adjusted.toPlainString()); - - MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName()); - bom.setM_Product_ID(mulchX.get_ID()); - bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive); - bom.setBOMUse(MPPProductBOM.BOMUSE_Master); - bom.setName(mulchX.getName()); - bom.saveEx(); - - MPPProductBOMLine line = new MPPProductBOMLine(bom); - line.setM_Product_ID(mulchId); - line.setQtyBOM(new BigDecimal("1")); - line.saveEx(); - - mulchX.load(getTrxName()); - mulchX.setIsVerified(true); - mulchX.saveEx(); - - MProduction production = new MProduction(Env.getCtx(), 0, getTrxName()); - production.setM_Product_ID(mulchX.get_ID()); - production.setM_Locator_ID(hqLocator); - production.setIsUseProductionPlan(false); - production.setMovementDate(getLoginDate()); - production.setDocAction(DocAction.ACTION_Complete); - production.setDocStatus(DocAction.STATUS_Drafted); - production.setIsComplete(false); - production.setProductionQty(new BigDecimal("1")); - production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID()); - production.saveEx(); - - int productionCreate = 53226; - MProcess process = MProcess.get(Env.getCtx(), productionCreate); - ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID()); - pi.setAD_Client_ID(getAD_Client_ID()); - pi.setAD_User_ID(getAD_User_ID()); - pi.setRecord_ID(production.get_ID()); - pi.setTransactionName(getTrxName()); - ServerProcessCtl.process(pi, getTrx(), false); - assertFalse(pi.isError(), pi.getSummary()); - - production.load(getTrxName()); - assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y"); - assertTrue(production.getLines().length > 0, "No Production Lines"); - - info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete); - production.load(getTrxName()); - assertFalse(info.isError(), info.getSummary()); - assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus()); - - BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); - BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); - BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0); - BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0); - - assertEquals(componentChange, new BigDecimal("-1"), "On hand of component doesn't reduce as expected"); - assertEquals(endProductChange, new BigDecimal("1"), "On hand of end product doesn't increase as expected"); - - if (!production.isPosted()) { - String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName()); - assertNull(msg, msg); - } - - BigDecimal endProductCost1 = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - assertEquals(endProductCost, endProductCost1, "Standard Cost Changed"); - - ProductCost pc = new ProductCost (Env.getCtx(), mulchX.getM_Product_ID(), 0, getTrxName()); - MAccount acctVariance = pc.getAccount(ProductCost.ACCTTYPE_P_RateVariance, as); - - whereClause = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MProduction.Table_ID - + " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + production.get_ID() - + " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + as.getC_AcctSchema_ID() - + " AND " + MFactAcct.COLUMNNAME_Account_ID + "=" + acctVariance.getAccount_ID(); - int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause, getTrxName()); - BigDecimal variance = BigDecimal.ZERO; - for (int id : ids) { - MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName()); - variance = fa.getAmtAcctDr().subtract(fa.getAmtAcctCr()); - break; - } - BigDecimal varianceExpected = componentCost.subtract(endProductCost).setScale(as.getStdPrecision(), RoundingMode.HALF_UP); - assertEquals(varianceExpected.setScale(2, RoundingMode.HALF_UP), variance.setScale(2, RoundingMode.HALF_UP), "Variance not posted correctly."); - } finally { - getTrx().rollback(); - mulch.setM_Product_Category_ID(categorySaveId); - mulch.saveEx(); - category.deleteEx(true); - } - } - - @Test - public void testRollUp() { - MProductCategory category = new MProductCategory(Env.getCtx(), 0, null); - category.setName("Standard Costing"); - category.saveEx(); - - String whereClause = "M_Product_Category_ID=?"; - List categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null) - .setParameters(category.get_ID()) - .list(); - for (MProductCategoryAcct categoryAcct : categoryAccts) { - categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); - categoryAcct.saveEx(); - } - - try { - int rollUpProcessId = 53230; - int mulchId = 137; - MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName()); - mulch.setM_Product_Category_ID(category.get_ID()); - mulch.saveEx(); - - MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); - BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); - - MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName()); - mulchX.setName("Mulch X"); - mulchX.setIsBOM(true); - mulchX.setIsStocked(true); - mulchX.setC_UOM_ID(mulch.getC_UOM_ID()); - mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID()); - mulchX.setProductType(mulch.getProductType()); - mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID()); - mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID()); - mulchX.saveEx(); - - MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName()); - bom.setM_Product_ID(mulchX.get_ID()); - bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive); - bom.setBOMUse(MPPProductBOM.BOMUSE_Master); - bom.setName(mulchX.getName()); - bom.saveEx(); - - MPPProductBOMLine line = new MPPProductBOMLine(bom); - line.setM_Product_ID(mulchId); - line.setQtyBOM(new BigDecimal("1")); - line.saveEx(); - - mulchX.load(getTrxName()); - mulchX.setIsVerified(true); - mulchX.saveEx(); - - MPInstance instance = new MPInstance(Env.getCtx(), rollUpProcessId, 0); - instance.saveEx(); - MPInstancePara para = new MPInstancePara(instance, 10); - para.setParameterName("M_Product_ID"); - para.setP_Number(mulchX.get_ID()); - para.saveEx(); - - para = new MPInstancePara(instance, 20); - para.setParameterName("M_CostElement_ID"); - para.setP_Number(MCostElement.getMaterialCostElement(Env.getCtx(), MAcctSchema.COSTINGMETHOD_StandardCosting).get_ID()); - para.saveEx(); - - ProcessInfo info = new ProcessInfo(MProcess.get(rollUpProcessId).getName(), rollUpProcessId); - info.setAD_PInstance_ID(instance.getAD_PInstance_ID()); - info.setTransactionName(getTrxName()); - ServerProcessCtl.process(info, getTrx(), false); - assertFalse(info.isError(), info.getSummary()); - - BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);; - assertEquals(componentCost, endProductCost, "BOM Cost not roll up."); - } finally { - getTrx().rollback(); - category.deleteEx(true); - } - } - @Test public void testAutoProduce() { int mulchId = 137; diff --git a/org.idempiere.test/src/org/idempiere/test/model/ProductionTestIsolated.java b/org.idempiere.test/src/org/idempiere/test/model/ProductionTestIsolated.java new file mode 100644 index 0000000000..2effe557aa --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/ProductionTestIsolated.java @@ -0,0 +1,460 @@ +/*********************************************************************** + * 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.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.sql.Timestamp; +import java.util.List; + +import org.compiere.model.MAccount; +import org.compiere.model.MAcctSchema; +import org.compiere.model.MBPartner; +import org.compiere.model.MClient; +import org.compiere.model.MCost; +import org.compiere.model.MCostElement; +import org.compiere.model.MFactAcct; +import org.compiere.model.MInOut; +import org.compiere.model.MInOutLine; +import org.compiere.model.MInventory; +import org.compiere.model.MInventoryLine; +import org.compiere.model.MOrder; +import org.compiere.model.MOrderLine; +import org.compiere.model.MPInstance; +import org.compiere.model.MPInstancePara; +import org.compiere.model.MProcess; +import org.compiere.model.MProduct; +import org.compiere.model.MProductCategory; +import org.compiere.model.MProductCategoryAcct; +import org.compiere.model.MProduction; +import org.compiere.model.MStorageOnHand; +import org.compiere.model.ProductCost; +import org.compiere.model.Query; +import org.compiere.process.DocAction; +import org.compiere.process.DocumentEngine; +import org.compiere.process.ProcessInfo; +import org.compiere.process.ServerProcessCtl; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; +import org.compiere.wf.MWorkflow; +import org.eevolution.model.MPPProductBOM; +import org.eevolution.model.MPPProductBOMLine; +import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.DictionaryIDs; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.api.parallel.Isolated; + +/** + * + * @author hengsin + * + */ +@Isolated +@Execution(ExecutionMode.SAME_THREAD) +public class ProductionTestIsolated extends AbstractTestCase { + + public ProductionTestIsolated() { + } + + @Test + public void testAverageCostingProduction() { + int mulchId = 137; + int hqLocator = 101; + + createPOAndMRForProduct(mulchId); + + MProduct mulch = MProduct.get(mulchId); + BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); + BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()); + + MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName()); + mulchX.setName("Mulch X"); + mulchX.setIsBOM(true); + mulchX.setIsStocked(true); + mulchX.setC_UOM_ID(mulch.getC_UOM_ID()); + mulchX.setM_Product_Category_ID(mulch.getM_Product_Category_ID()); + mulchX.setProductType(mulch.getProductType()); + mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID()); + mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID()); + mulchX.saveEx(); + BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); + + MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName()); + bom.setM_Product_ID(mulchX.get_ID()); + bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive); + bom.setBOMUse(MPPProductBOM.BOMUSE_Master); + bom.setName(mulchX.getName()); + bom.saveEx(); + + MPPProductBOMLine line = new MPPProductBOMLine(bom); + line.setM_Product_ID(mulchId); + line.setQtyBOM(new BigDecimal("1")); + line.saveEx(); + + mulchX.load(getTrxName()); + mulchX.setIsVerified(true); + mulchX.saveEx(); + + MProduction production = new MProduction(Env.getCtx(), 0, getTrxName()); + production.setM_Product_ID(mulchX.get_ID()); + production.setM_Locator_ID(hqLocator); + production.setIsUseProductionPlan(false); + production.setMovementDate(getLoginDate()); + production.setDocAction(DocAction.ACTION_Complete); + production.setDocStatus(DocAction.STATUS_Drafted); + production.setIsComplete(false); + production.setProductionQty(new BigDecimal("1")); + production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID()); + production.saveEx(); + + int productionCreate = 53226; + MProcess process = MProcess.get(Env.getCtx(), productionCreate); + ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID()); + pi.setAD_Client_ID(getAD_Client_ID()); + pi.setAD_User_ID(getAD_User_ID()); + pi.setRecord_ID(production.get_ID()); + pi.setTransactionName(getTrxName()); + ServerProcessCtl.process(pi, getTrx(), false); + assertFalse(pi.isError(), pi.getSummary()); + + production.load(getTrxName()); + assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y"); + assertTrue(production.getLines().length > 0, "No Production Lines"); + + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete); + production.load(getTrxName()); + assertFalse(info.isError(), info.getSummary()); + assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus()); + + BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); + BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); + + BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0); + BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0); + assertEquals(new BigDecimal("-1"), componentChange, "On hand of component doesn't reduce as expected"); + assertEquals(new BigDecimal("1"), endProductChange, "On hand of end product doesn't increase as expected"); + + if (!production.isPosted()) { + String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName()); + assertNull(msg, msg); + } + + BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName()); + MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); + componentCost = componentCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + endProductCost = endProductCost.setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + assertEquals(componentCost, endProductCost, "Cost not roll up correctly"); + } + + @Test + public void testStandardCostingProduction() { + MProductCategory category = new MProductCategory(Env.getCtx(), 0, null); + category.setName("Standard Costing"); + category.saveEx(); + + String whereClause = "M_Product_Category_ID=?"; + List categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null) + .setParameters(category.get_ID()) + .list(); + for (MProductCategoryAcct categoryAcct : categoryAccts) { + categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); + categoryAcct.saveEx(); + } + // ProductCost api doesn't use trx to retrieve product + int mulchId = 137; + MProduct mulch = new MProduct(Env.getCtx(), mulchId, null); + int categorySaveId = mulch.getM_Product_Category_ID(); + mulch.setM_Product_Category_ID(category.get_ID()); + mulch.saveEx(); + + try { + int hqLocator = 101; + createPOAndMRForProduct(mulchId); + + BigDecimal componentOnHand1 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); + BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()); + + MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName()); + mulchX.setName("Mulch X"); + mulchX.setIsBOM(true); + mulchX.setIsStocked(true); + mulchX.setC_UOM_ID(mulch.getC_UOM_ID()); + mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID()); + mulchX.setProductType(mulch.getProductType()); + mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID()); + mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID()); + mulchX.saveEx(); + BigDecimal endProductOnHand1 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); + + int costAdjustmentDocTypeId = 200004; + MInventory inventory = new MInventory(Env.getCtx(), 0, getTrxName()); + inventory.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); + inventory.setC_DocType_ID(costAdjustmentDocTypeId); + inventory.setM_Warehouse_ID(getM_Warehouse_ID()); + inventory.setMovementDate(getLoginDate()); + inventory.setDocAction(DocAction.ACTION_Complete); + inventory.saveEx(); + + MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); + BigDecimal endProductCost = new BigDecimal("2.50").setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + MInventoryLine il = new MInventoryLine(Env.getCtx(), 0, getTrxName()); + il.setM_Inventory_ID(inventory.get_ID()); + il.setM_Locator_ID(hqLocator); + il.setM_Product_ID(mulchX.getM_Product_ID()); + il.setCurrentCostPrice(new BigDecimal("0")); + il.setNewCostPrice(endProductCost); + il.saveEx(); + + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); + inventory.load(getTrxName()); + assertFalse(info.isError(), info.getSummary()); + assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus(), "Cost Adjustment Status="+inventory.getDocStatus()); + + if (!inventory.isPosted()) { + String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MInventory.Table_ID, inventory.get_ID(), false, getTrxName()); + assertNull(msg, msg); + } + BigDecimal adjusted = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + assertEquals(endProductCost, adjusted, "Cost not adjusted: " + adjusted.toPlainString()); + + MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName()); + bom.setM_Product_ID(mulchX.get_ID()); + bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive); + bom.setBOMUse(MPPProductBOM.BOMUSE_Master); + bom.setName(mulchX.getName()); + bom.saveEx(); + + MPPProductBOMLine line = new MPPProductBOMLine(bom); + line.setM_Product_ID(mulchId); + line.setQtyBOM(new BigDecimal("1")); + line.saveEx(); + + mulchX.load(getTrxName()); + mulchX.setIsVerified(true); + mulchX.saveEx(); + + MProduction production = new MProduction(Env.getCtx(), 0, getTrxName()); + production.setM_Product_ID(mulchX.get_ID()); + production.setM_Locator_ID(hqLocator); + production.setIsUseProductionPlan(false); + production.setMovementDate(getLoginDate()); + production.setDocAction(DocAction.ACTION_Complete); + production.setDocStatus(DocAction.STATUS_Drafted); + production.setIsComplete(false); + production.setProductionQty(new BigDecimal("1")); + production.setPP_Product_BOM_ID(bom.getPP_Product_BOM_ID()); + production.saveEx(); + + int productionCreate = 53226; + MProcess process = MProcess.get(Env.getCtx(), productionCreate); + ProcessInfo pi = new ProcessInfo(process.getName(), process.get_ID()); + pi.setAD_Client_ID(getAD_Client_ID()); + pi.setAD_User_ID(getAD_User_ID()); + pi.setRecord_ID(production.get_ID()); + pi.setTransactionName(getTrxName()); + ServerProcessCtl.process(pi, getTrx(), false); + assertFalse(pi.isError(), pi.getSummary()); + + production.load(getTrxName()); + assertEquals("Y", production.getIsCreated(), "MProduction.IsCreated != Y"); + assertTrue(production.getLines().length > 0, "No Production Lines"); + + info = MWorkflow.runDocumentActionWorkflow(production, DocAction.ACTION_Complete); + production.load(getTrxName()); + assertFalse(info.isError(), info.getSummary()); + assertEquals(DocAction.STATUS_Completed, production.getDocStatus(), "Production Status="+production.getDocStatus()); + + BigDecimal componentOnHand2 = MStorageOnHand.getQtyOnHand(mulchId, getM_Warehouse_ID(), 0, getTrxName()); + BigDecimal endProductOnHand2 = MStorageOnHand.getQtyOnHand(mulchX.get_ID(), getM_Warehouse_ID(), 0, getTrxName()); + BigDecimal componentChange = componentOnHand2.subtract(componentOnHand1).setScale(0); + BigDecimal endProductChange = endProductOnHand2.subtract(endProductOnHand1).setScale(0); + + assertEquals(componentChange, new BigDecimal("-1"), "On hand of component doesn't reduce as expected"); + assertEquals(endProductChange, new BigDecimal("1"), "On hand of end product doesn't increase as expected"); + + if (!production.isPosted()) { + String msg = DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MProduction.Table_ID, production.get_ID(), false, getTrxName()); + assertNull(msg, msg); + } + + BigDecimal endProductCost1 = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + assertEquals(endProductCost, endProductCost1, "Standard Cost Changed"); + + ProductCost pc = new ProductCost (Env.getCtx(), mulchX.getM_Product_ID(), 0, getTrxName()); + MAccount acctVariance = pc.getAccount(ProductCost.ACCTTYPE_P_RateVariance, as); + + whereClause = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MProduction.Table_ID + + " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + production.get_ID() + + " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + as.getC_AcctSchema_ID() + + " AND " + MFactAcct.COLUMNNAME_Account_ID + "=" + acctVariance.getAccount_ID(); + int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause, getTrxName()); + BigDecimal variance = BigDecimal.ZERO; + for (int id : ids) { + MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName()); + variance = fa.getAmtAcctDr().subtract(fa.getAmtAcctCr()); + break; + } + BigDecimal varianceExpected = componentCost.subtract(endProductCost).setScale(as.getStdPrecision(), RoundingMode.HALF_UP); + assertEquals(varianceExpected.setScale(2, RoundingMode.HALF_UP), variance.setScale(2, RoundingMode.HALF_UP), "Variance not posted correctly."); + } finally { + getTrx().rollback(); + mulch.setM_Product_Category_ID(categorySaveId); + mulch.saveEx(); + category.deleteEx(true); + } + } + + @Test + public void testRollUp() { + MProductCategory category = new MProductCategory(Env.getCtx(), 0, null); + category.setName("Standard Costing"); + category.saveEx(); + + String whereClause = "M_Product_Category_ID=?"; + List categoryAccts = new Query(Env.getCtx(), MProductCategoryAcct.Table_Name, whereClause, null) + .setParameters(category.get_ID()) + .list(); + for (MProductCategoryAcct categoryAcct : categoryAccts) { + categoryAcct.setCostingMethod(MAcctSchema.COSTINGMETHOD_StandardCosting); + categoryAcct.saveEx(); + } + + try { + int rollUpProcessId = 53230; + int mulchId = 137; + MProduct mulch = new MProduct(Env.getCtx(), mulchId, getTrxName()); + mulch.setM_Product_Category_ID(category.get_ID()); + mulch.saveEx(); + + MAcctSchema as = MClient.get(getAD_Client_ID()).getAcctSchema(); + BigDecimal componentCost = MCost.getCurrentCost(mulch, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP); + + MProduct mulchX = new MProduct(Env.getCtx(), 0, getTrxName()); + mulchX.setName("Mulch X"); + mulchX.setIsBOM(true); + mulchX.setIsStocked(true); + mulchX.setC_UOM_ID(mulch.getC_UOM_ID()); + mulchX.setM_Product_Category_ID(category.getM_Product_Category_ID()); + mulchX.setProductType(mulch.getProductType()); + mulchX.setM_AttributeSet_ID(mulch.getM_AttributeSet_ID()); + mulchX.setC_TaxCategory_ID(mulch.getC_TaxCategory_ID()); + mulchX.saveEx(); + + MPPProductBOM bom = new MPPProductBOM(Env.getCtx(), 0, getTrxName()); + bom.setM_Product_ID(mulchX.get_ID()); + bom.setBOMType(MPPProductBOM.BOMTYPE_CurrentActive); + bom.setBOMUse(MPPProductBOM.BOMUSE_Master); + bom.setName(mulchX.getName()); + bom.saveEx(); + + MPPProductBOMLine line = new MPPProductBOMLine(bom); + line.setM_Product_ID(mulchId); + line.setQtyBOM(new BigDecimal("1")); + line.saveEx(); + + mulchX.load(getTrxName()); + mulchX.setIsVerified(true); + mulchX.saveEx(); + + MPInstance instance = new MPInstance(Env.getCtx(), rollUpProcessId, 0); + instance.saveEx(); + MPInstancePara para = new MPInstancePara(instance, 10); + para.setParameterName("M_Product_ID"); + para.setP_Number(mulchX.get_ID()); + para.saveEx(); + + para = new MPInstancePara(instance, 20); + para.setParameterName("M_CostElement_ID"); + para.setP_Number(MCostElement.getMaterialCostElement(Env.getCtx(), MAcctSchema.COSTINGMETHOD_StandardCosting).get_ID()); + para.saveEx(); + + ProcessInfo info = new ProcessInfo(MProcess.get(rollUpProcessId).getName(), rollUpProcessId); + info.setAD_PInstance_ID(instance.getAD_PInstance_ID()); + info.setTransactionName(getTrxName()); + ServerProcessCtl.process(info, getTrx(), false); + assertFalse(info.isError(), info.getSummary()); + + BigDecimal endProductCost = MCost.getCurrentCost(mulchX, 0, getTrxName()).setScale(as.getCostingPrecision(), RoundingMode.HALF_UP);; + assertEquals(componentCost, endProductCost, "BOM Cost not roll up."); + } finally { + getTrx().rollback(); + category.deleteEx(true); + } + } + + // creates an order and material receipt for qty 25 at special price of 2.60 each + private void createPOAndMRForProduct(int mulchId) { + MOrder order = new MOrder(Env.getCtx(), 0, getTrxName()); + order.setBPartner(MBPartner.get(Env.getCtx(), DictionaryIDs.C_BPartner.PATIO.id)); + order.setC_DocTypeTarget_ID(DictionaryIDs.C_DocType.PURCHASE_ORDER.id); + order.setIsSOTrx(false); + order.setSalesRep_ID(DictionaryIDs.AD_User.GARDEN_ADMIN.id); + order.setDocStatus(DocAction.STATUS_Drafted); + order.setDocAction(DocAction.ACTION_Complete); + Timestamp today = TimeUtil.getDay(System.currentTimeMillis()); + order.setDateOrdered(today); + order.setDatePromised(today); + order.saveEx(); + + MOrderLine line1 = new MOrderLine(order); + line1.setLine(10); + line1.setProduct(MProduct.get(Env.getCtx(), mulchId)); + line1.setQty(new BigDecimal("25")); + line1.setPrice(new BigDecimal("2.60")); + 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()); + + MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered()); + receipt1.setDocStatus(DocAction.STATUS_Drafted); + receipt1.setDocAction(DocAction.ACTION_Complete); + receipt1.saveEx(); + + MInOutLine receiptLine1 = new MInOutLine(receipt1); + receiptLine1.setOrderLine(line1, 0, new BigDecimal("25")); + receiptLine1.setQty(new BigDecimal("25")); + receiptLine1.saveEx(); + + info = MWorkflow.runDocumentActionWorkflow(receipt1, DocAction.ACTION_Complete); + assertFalse(info.isError(), info.getSummary()); + receipt1.load(getTrxName()); + assertEquals(DocAction.STATUS_Completed, receipt1.getDocStatus()); + if (!receipt1.isPosted()) { + String error = DocumentEngine.postImmediate(Env.getCtx(), receipt1.getAD_Client_ID(), receipt1.get_Table_ID(), receipt1.get_ID(), false, getTrxName()); + assertNull(error, error); + } + } +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java b/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java index 37c2aac533..fca33dfeb1 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/PurchaseOrderTest.java @@ -219,7 +219,7 @@ public class PurchaseOrderTest extends AbstractTestCase { Properties ctx = Env.getCtx(); String trxName = getTrxName(); - BigDecimal qtyOrderedOriginal = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName); + BigDecimal qtyOrderedOriginal = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName); MOrder order = new MOrder(ctx, 0, trxName); order.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.PATIO.id)); @@ -235,7 +235,7 @@ public class PurchaseOrderTest extends AbstractTestCase { MOrderLine line1 = new MOrderLine(order); line1.setLine(10); - line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.MULCH.id)); + line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id)); line1.setQty(THREE); line1.setDatePromised(today); line1.saveEx(); @@ -247,7 +247,7 @@ public class PurchaseOrderTest extends AbstractTestCase { line1.load(trxName); assertEquals(0, line1.getQtyReserved().compareTo(THREE)); - BigDecimal newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName); + BigDecimal newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName); assertEquals(0, qtyOrderedOriginal.add(THREE).compareTo(newQtyOrdered)); MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered()); @@ -268,7 +268,7 @@ public class PurchaseOrderTest extends AbstractTestCase { line1.load(trxName); assertEquals(0, line1.getQtyReserved().compareTo(Env.ZERO)); - newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName); + newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName); assertEquals(0, qtyOrderedOriginal.compareTo(newQtyOrdered)); // reactivate the purchase order @@ -291,7 +291,7 @@ public class PurchaseOrderTest extends AbstractTestCase { // IDEMPIERE-5039 - when reservations go negative they are changed to zero assertEquals(0, line1.getQtyReserved().compareTo(Env.ZERO)); - newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName); + newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName); assertEquals(0, qtyOrderedOriginal.compareTo(newQtyOrdered)); // create a new material receipt for the -3 reversed @@ -313,7 +313,7 @@ public class PurchaseOrderTest extends AbstractTestCase { line1.load(trxName); assertEquals(0, line1.getQtyReserved().compareTo(Env.ZERO)); - newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.MULCH.id, trxName); + newQtyOrdered = getQtyOrdered(ctx, DictionaryIDs.M_Product.HOLLY_BUSH.id, trxName); assertEquals(0, qtyOrderedOriginal.compareTo(newQtyOrdered)); } @@ -490,7 +490,7 @@ public class PurchaseOrderTest extends AbstractTestCase { new Object[] {MSysConfig.VALIDATE_MATCHING_TO_ORDERED_QTY}, null); CacheMgt.get().reset(); - BigDecimal initialQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName()); + BigDecimal initialQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName()); try { MOrder order = new MOrder(ctx, 0, trxName); order.setBPartner(MBPartner.get(ctx, DictionaryIDs.C_BPartner.PATIO.id)); @@ -506,7 +506,7 @@ public class PurchaseOrderTest extends AbstractTestCase { MOrderLine line1 = new MOrderLine(order); line1.setLine(10); - line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.MULCH.id)); + line1.setProduct(MProduct.get(ctx, DictionaryIDs.M_Product.ROSE_BUSH.id)); line1.setQty(new BigDecimal("1")); line1.setDatePromised(today); line1.saveEx(); @@ -517,7 +517,7 @@ public class PurchaseOrderTest extends AbstractTestCase { assertEquals(DocAction.STATUS_Completed, order.getDocStatus(), "Order not completed"); line1.load(trxName); assertEquals(1, line1.getQtyReserved().intValue(), "Wrong Order line qty reserved value"); - BigDecimal newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName()); + BigDecimal newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName()); assertEquals(initialQtyOrdered.intValue()+1, newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected"); MInOut receipt1 = new MInOut(order, DictionaryIDs.C_DocType.MM_RECEIPT.id, order.getDateOrdered()); @@ -537,7 +537,7 @@ public class PurchaseOrderTest extends AbstractTestCase { line1.load(trxName); assertEquals(0, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value"); - newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName()); + newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName()); assertEquals(initialQtyOrdered.intValue(), newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected"); // reactivate the purchase order @@ -559,7 +559,7 @@ public class PurchaseOrderTest extends AbstractTestCase { line1.load(trxName); assertEquals(0, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value"); assertEquals(2, line1.getQtyOrdered().intValue(), "Wrong order line qty ordered value"); - newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName()); + newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName()); assertEquals(initialQtyOrdered.intValue(), newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected"); //reverse MR @@ -574,7 +574,7 @@ public class PurchaseOrderTest extends AbstractTestCase { line1.load(trxName); assertEquals(2, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value"); assertEquals(0, line1.getQtyDelivered().intValue(), "Wrong order line qty delivered value"); - newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id, getTrxName()); + newQtyOrdered = getQtyOrdered(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id, getTrxName()); assertEquals(initialQtyOrdered.intValue()+2, newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected"); } finally { DB.executeUpdateEx("UPDATE AD_SysConfig SET Value='Y' WHERE AD_Client_ID=0 AND Name=?", @@ -599,7 +599,7 @@ public class PurchaseOrderTest extends AbstractTestCase { MOrderLine line1 = new MOrderLine(order); line1.setLine(10); - line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.MULCH.id)); + line1.setProduct(MProduct.get(Env.getCtx(), DictionaryIDs.M_Product.ROSE_BUSH.id)); line1.setQty(new BigDecimal("1")); line1.setDatePromised(today); line1.saveEx(); diff --git a/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java b/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java index b4221cd04f..32fc8b73df 100644 --- a/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java +++ b/org.idempiere.test/src/org/idempiere/test/model/SalesOrderTest.java @@ -69,10 +69,12 @@ import org.compiere.wf.MWorkflow; import org.idempiere.test.AbstractTestCase; import org.idempiere.test.DictionaryIDs; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; /** * @author hengsin */ +@Isolated public class SalesOrderTest extends AbstractTestCase { public SalesOrderTest() { diff --git a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java index d99b59d8b0..b2a9b7bb31 100644 --- a/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java +++ b/org.idempiere.test/src/org/idempiere/test/performance/CacheTest.java @@ -120,12 +120,14 @@ import org.idempiere.fa.service.api.IDepreciationMethodFactory; import org.idempiere.test.AbstractTestCase; import org.idempiere.test.TestActivator; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; /** * * @author hengsin * */ +@Isolated public class CacheTest extends AbstractTestCase { private static final int ORDER_HEADER_PRINT_FORMAT_ID = 118;