IDEMPIERE-5134 Clean up storage records after deactivation of product (#1104)
This commit is contained in:
parent
de1e9011c8
commit
349e0f35a6
|
@ -651,6 +651,8 @@ public class MProduct extends X_M_Product implements ImmutablePOSupport
|
|||
log.saveError("Error", Msg.parseTranslation(getCtx(), errMsg));
|
||||
return false;
|
||||
}
|
||||
|
||||
removeStorageRecords();
|
||||
} // storage
|
||||
|
||||
// it checks if UOM has been changed , if so disallow the change if the condition is true.
|
||||
|
@ -724,6 +726,33 @@ public class MProduct extends X_M_Product implements ImmutablePOSupport
|
|||
return errMsg.toString();
|
||||
}
|
||||
|
||||
private void removeStorageRecords() {
|
||||
int cnt = 0;
|
||||
//safe to remove if not using lot or serial
|
||||
if (isLot() || isSerial()) {
|
||||
//for lot/serial, make sure everything is zero
|
||||
cnt = DB.executeUpdateEx("UPDATE M_StorageOnHand SET QtyOnHand=0 WHERE M_Product_ID=? AND QtyOnHand != 0", new Object[] {getM_Product_ID()}, get_TrxName());
|
||||
if (log.isLoggable(Level.INFO)) {
|
||||
log.log(Level.INFO, toString()+" #M_StorageOnHand Updated=" + cnt);
|
||||
}
|
||||
} else {
|
||||
cnt = DB.executeUpdateEx("DELETE FROM M_StorageOnHand WHERE M_Product_ID=?", new Object[] {getM_Product_ID()}, get_TrxName());
|
||||
if (log.isLoggable(Level.INFO)) {
|
||||
log.log(Level.INFO, toString()+" #M_StorageOnHand Deleted=" + cnt);
|
||||
}
|
||||
}
|
||||
|
||||
//clear all reservation data
|
||||
cnt = DB.executeUpdateEx("DELETE FROM M_StorageReservation WHERE M_Product_ID=?", new Object[] {getM_Product_ID()}, get_TrxName());
|
||||
if (log.isLoggable(Level.INFO)) {
|
||||
log.log(Level.INFO, toString()+" #M_StorageReservation Deleted=" + cnt);
|
||||
}
|
||||
cnt = DB.executeUpdateEx("DELETE FROM M_StorageReservationLog WHERE M_Product_ID=?", new Object[] {getM_Product_ID()}, get_TrxName());
|
||||
if (log.isLoggable(Level.INFO)) {
|
||||
log.log(Level.INFO, toString()+" #M_StorageReservationLog Deleted=" + cnt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HasInventoryOrCost
|
||||
* @return true if it has Inventory or Cost
|
||||
|
@ -1011,4 +1040,19 @@ public class MProduct extends X_M_Product implements ImmutablePOSupport
|
|||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return true if instance of product is managed with lot
|
||||
*/
|
||||
public boolean isLot() {
|
||||
if (getM_AttributeSet_ID() == 0)
|
||||
return false;
|
||||
|
||||
MAttributeSet as = MAttributeSet.get(getM_AttributeSet_ID());
|
||||
if (as.isInstanceAttribute() && as.isLot())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
} // MProduct
|
||||
|
|
|
@ -28,11 +28,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.compiere.model.MAcctSchema;
|
||||
import org.compiere.model.MAttributeInstance;
|
||||
import org.compiere.model.MAttributeSet;
|
||||
|
@ -44,11 +46,15 @@ import org.compiere.model.MInOutLine;
|
|||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.MStorageReservation;
|
||||
import org.compiere.model.MUOM;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.CacheMgt;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.TimeUtil;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
|
@ -204,4 +210,35 @@ public class MProductTest extends AbstractTestCase {
|
|||
attributeSet.saveEx();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveStorageRecords() {
|
||||
int count = 0;
|
||||
|
||||
//make sure there's on hand and reservation records
|
||||
MProduct product = new MProduct(Env.getCtx(), MULCH_PRODUCT_ID, getTrxName());
|
||||
createPOAndMRForProduct(product.get_ID());
|
||||
Query query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertTrue(count > 0, "No Storage On Hand Record");
|
||||
query = new Query(Env.getCtx(), MStorageReservation.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertTrue(count > 0, "No Storage Reservation Record");
|
||||
|
||||
//this should faiil due to on hand > 0
|
||||
product.setIsActive(false);
|
||||
assertThrows(AdempiereException.class, () -> product.saveEx());
|
||||
|
||||
//clear on hand so that we can deactivate product
|
||||
DB.executeUpdateEx("UPDATE M_StorageOnHand SET QtyOnHand=0 WHERE M_Product_ID=?", new Object[] {product.get_ID()}, getTrxName());
|
||||
product.setIsActive(false);
|
||||
product.saveEx();
|
||||
|
||||
query = new Query(Env.getCtx(), MStorageOnHand.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(0, count, "Storage On Hand Record > 0");
|
||||
query = new Query(Env.getCtx(), MStorageReservation.Table_Name, "M_Product_ID=?", getTrxName());
|
||||
count = query.setParameters(product.get_ID()).count();
|
||||
assertEquals(0, count, "Storage Reservation Record > 0");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue