From 5da17855723921b75b5241cc28920a64e46d7e47 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Sat, 12 Dec 2020 16:12:31 +0100 Subject: [PATCH] =?UTF-8?q?IDEMPIERE-4596=20Cannot=20create=20a=20product?= =?UTF-8?q?=20and=20an=20inventory=20document=20in=20t=E2=80=A6=20(#459)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * IDEMPIERE-4596 Cannot create a product and an inventory document in the same transaction WIP - commit failing unit test * IDEMPIERE-4596 Cannot create a product and an inventory document in the same transaction Implement solution suggested by @hengsin * minor fix comment --- .../src/org/compiere/model/MInventory.java | 4 +- .../org/compiere/model/MInventoryLine.java | 2 +- .../src/org/compiere/model/MProduct.java | 16 +++- .../org/compiere/model/MStorageOnHand.java | 2 +- .../idempiere/test/model/InventoryTest.java | 96 +++++++++++++++++++ 5 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java diff --git a/org.adempiere.base/src/org/compiere/model/MInventory.java b/org.adempiere.base/src/org/compiere/model/MInventory.java index 9c0928dc3c..f246bfa912 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventory.java +++ b/org.adempiere.base/src/org/compiere/model/MInventory.java @@ -384,7 +384,7 @@ public class MInventory extends X_M_Inventory implements DocAction // Product requires ASI if (line.getM_AttributeSetInstance_ID() == 0) { - MProduct product = MProduct.get(getCtx(), line.getM_Product_ID()); + MProduct product = MProduct.get(getCtx(), line.getM_Product_ID(), get_TrxName()); if (product != null && product.isASIMandatory(line.isSOTrx())) { if (product.getAttributeSet() != null && !product.getAttributeSet().excludeTableEntry(MInventoryLine.Table_ID, line.isSOTrx())) { @@ -728,7 +728,7 @@ public class MInventory extends X_M_Inventory implements DocAction // Attribute Set Instance if (line.getM_AttributeSetInstance_ID() == 0) { - MProduct product = MProduct.get(getCtx(), line.getM_Product_ID()); + MProduct product = MProduct.get(getCtx(), line.getM_Product_ID(), get_TrxName()); if (qtyDiff.signum() > 0) // Incoming Trx { //auto balance negative on hand diff --git a/org.adempiere.base/src/org/compiere/model/MInventoryLine.java b/org.adempiere.base/src/org/compiere/model/MInventoryLine.java index aa03ea1218..3dd23d4a27 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventoryLine.java +++ b/org.adempiere.base/src/org/compiere/model/MInventoryLine.java @@ -190,7 +190,7 @@ public class MInventoryLine extends X_M_InventoryLine m_product = null; // reset if (m_product == null) { - m_product = MProduct.getCopy(getCtx(), M_Product_ID, get_TrxName()); + m_product = MProduct.get(getCtx(), M_Product_ID, get_TrxName()); } return m_product; } // getProduct diff --git a/org.adempiere.base/src/org/compiere/model/MProduct.java b/org.adempiere.base/src/org/compiere/model/MProduct.java index fafdd62080..4e4c05f5b1 100644 --- a/org.adempiere.base/src/org/compiere/model/MProduct.java +++ b/org.adempiere.base/src/org/compiere/model/MProduct.java @@ -53,7 +53,7 @@ public class MProduct extends X_M_Product implements ImmutablePOSupport /** * */ - private static final long serialVersionUID = -6713953630334843853L; + private static final long serialVersionUID = 8710213660955199146L; /** * Get MProduct from Cache (immutable) @@ -72,6 +72,18 @@ public class MProduct extends X_M_Product implements ImmutablePOSupport * @return MProduct or null */ public static MProduct get (Properties ctx, int M_Product_ID) + { + return get(ctx, M_Product_ID, null); + } // get + + /** + * Get MProduct from Cache (immutable) + * @param ctx context + * @param M_Product_ID id + * @param trxName trx + * @return MProduct or null + */ + public static MProduct get (Properties ctx, int M_Product_ID, String trxName) { if (M_Product_ID <= 0) { @@ -82,7 +94,7 @@ public class MProduct extends X_M_Product implements ImmutablePOSupport if (retValue != null) return retValue; - retValue = new MProduct (ctx, M_Product_ID, (String)null); + retValue = new MProduct (ctx, M_Product_ID, trxName); if (retValue.get_ID () == M_Product_ID) { s_cache.put (key, retValue, e -> new MProduct(Env.getCtx(), e)); diff --git a/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java b/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java index d91d2ab0e4..b0221b5a5d 100644 --- a/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java +++ b/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java @@ -516,7 +516,7 @@ public class MStorageOnHand extends X_M_StorageOnHand sql += "AND (s.M_AttributeSetInstance_ID=0 OR s.M_AttributeSetInstance_ID IS NULL) "; } - MProduct product = MProduct.get(Env.getCtx(), M_Product_ID); + MProduct product = MProduct.get(Env.getCtx(), M_Product_ID, trxName); if(product.isUseGuaranteeDateForMPolicy()){ sql += "ORDER BY l.PriorityNo DESC, " + diff --git a/org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java b/org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java new file mode 100644 index 0000000000..b5c65ca12b --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/InventoryTest.java @@ -0,0 +1,96 @@ +/*********************************************************************** + * 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 java.util.Properties; + +import org.compiere.model.MInventory; +import org.compiere.model.MInventoryLine; +import org.compiere.model.MProduct; +import org.compiere.process.DocAction; +import org.compiere.process.ProcessInfo; +import org.compiere.util.Env; +import org.compiere.wf.MWorkflow; +import org.idempiere.test.AbstractTestCase; +import org.junit.jupiter.api.Test; + +/** + * @author Carlos Ruiz - globalqss + */ +public class InventoryTest extends AbstractTestCase { + + public InventoryTest() { + } + + private static final int PRODCAT_BUSHES = 107; + private static final int TAXCAT_STANDARD = 107; + private static final int UOM_EACH = 100; + private static final int WAREHOUSE_HQ = 103; + private static final int LOCATOR_HQ = 101; + private static final int DOCTYPE_PHYSICAL_INV = 144; + + /** + * https://idempiere.atlassian.net/browse/IDEMPIERE-4596 + */ + @Test + public void testCreateAProductAndInventory() { + Properties ctx = Env.getCtx(); + String trxName = getTrxName(); + + MProduct product = new MProduct(ctx, 0, trxName); + product.setM_Product_Category_ID(PRODCAT_BUSHES); + product.setName("Test 4596"); + product.setValue("T4596"); + product.setProductType(MProduct.PRODUCTTYPE_Item); + product.setIsStocked(true); + product.setIsSold(true); + product.setIsPurchased(true); + product.setC_UOM_ID(UOM_EACH); + product.setC_TaxCategory_ID(TAXCAT_STANDARD); + product.saveEx(); + + MInventory inventory = new MInventory(ctx, 0, trxName); + inventory.setM_Warehouse_ID(WAREHOUSE_HQ); + inventory.setC_DocType_ID(DOCTYPE_PHYSICAL_INV); + inventory.saveEx(); + + MInventoryLine iline = new MInventoryLine(inventory, + LOCATOR_HQ, + product.getM_Product_ID(), + 0, // M_AttributeSetInstance_ID + Env.ZERO, // QtyBook + Env.ONEHUNDRED); + iline.saveEx(); + + ProcessInfo info = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete); + assertFalse(info.isError()); + inventory.load(trxName); + assertEquals(DocAction.STATUS_Completed, inventory.getDocStatus()); + } + +}