IDEMPIERE-2172 Attribute set with mandatory type = When Shipping not … (#1014)
* IDEMPIERE-2172 Attribute set with mandatory type = When Shipping not working * IDEMPIERE-2172 Attribute set with mandatory type = When Shipping not working - added MTransaction - added reversal handling
This commit is contained in:
parent
055c614336
commit
db4087f878
|
@ -1421,6 +1421,15 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
if (MovementType.charAt(1) == '-') // C- Customer Shipment - V- Vendor Return
|
||||
QtyMA = QtyMA.negate();
|
||||
|
||||
if (product != null && QtyMA.signum() < 0 && MovementType.equals("C-") && ma.getM_AttributeSetInstance_ID() > 0
|
||||
&& oLine != null && oLine.getM_AttributeSetInstance_ID()==0 && !ma.isAutoGenerated() && !isReversal())
|
||||
{
|
||||
String status = moveOnHandToShipmentASI(product, sLine.getM_Locator_ID(), ma.getM_AttributeSetInstance_ID(), QtyMA.negate(), ma.getDateMaterialPolicy(),
|
||||
sLine.get_ID(), false, get_TrxName());
|
||||
if (status != null)
|
||||
return status;
|
||||
}
|
||||
|
||||
// Update Storage - see also VMatch.createMatchRecord
|
||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
|
||||
sLine.getM_Locator_ID(),
|
||||
|
@ -1445,6 +1454,15 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
m_processMsg = "Could not create Material Transaction (MA) [" + product.getValue() + "]";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
if (product != null && QtyMA.signum() > 0 && MovementType.equals("C-") && ma.getM_AttributeSetInstance_ID() > 0
|
||||
&& oLine != null && oLine.getM_AttributeSetInstance_ID()==0 && !ma.isAutoGenerated() && isReversal())
|
||||
{
|
||||
String status = moveOnHandToShipmentASI(product, sLine.getM_Locator_ID(), ma.getM_AttributeSetInstance_ID(), QtyMA.negate(), ma.getDateMaterialPolicy(),
|
||||
sLine.get_ID(), true, get_TrxName());
|
||||
if (status != null)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (oLine!=null && mtrx!=null &&
|
||||
|
@ -1478,6 +1496,14 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
|
||||
if (mtrx == null)
|
||||
{
|
||||
if (product != null && MovementType.equals("C-") && sLine.getM_AttributeSetInstance_ID() > 0 && Qty.signum() < 0
|
||||
&& oLine != null && oLine.getM_AttributeSetInstance_ID()==0 && !isReversal())
|
||||
{
|
||||
String status = moveOnHandToShipmentASI(product, sLine.getM_Locator_ID(), sLine.getM_AttributeSetInstance_ID(), Qty.negate(), null, sLine.get_ID(), false, get_TrxName());
|
||||
if (status != null)
|
||||
return status;
|
||||
}
|
||||
|
||||
Timestamp dateMPolicy= null;
|
||||
BigDecimal pendingQty = Qty;
|
||||
if (pendingQty.signum() < 0) { // taking from inventory
|
||||
|
@ -1569,6 +1595,14 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
m_processMsg = CLogger.retrieveErrorString("Could not create Material Transaction [" + product.getValue() + "]");
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
if (product != null && MovementType.equals("C-") && sLine.getM_AttributeSetInstance_ID() > 0 && Qty.signum() > 0
|
||||
&& oLine != null && oLine.getM_AttributeSetInstance_ID()==0 && isReversal())
|
||||
{
|
||||
String status = moveOnHandToShipmentASI(product, sLine.getM_Locator_ID(), sLine.getM_AttributeSetInstance_ID(), Qty.negate(), null, sLine.get_ID(), true, get_TrxName());
|
||||
if (status != null)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
} // stock movement
|
||||
|
||||
|
@ -2588,4 +2622,122 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
|| DOCSTATUS_Reversed.equals(ds);
|
||||
} // isComplete
|
||||
|
||||
/**
|
||||
* For product with mix of No ASI and ASI inventory, this move Non ASI on hand to the new ASI created at shipment line or shipment line ma
|
||||
* @param product
|
||||
* @param M_Locator_ID
|
||||
* @param M_AttributeSetInstance_ID
|
||||
* @param qty
|
||||
* @param dateMaterialPolicy
|
||||
* @param M_InOutLine_ID
|
||||
* @param reversal
|
||||
* @param trxName
|
||||
* @return error doc status if there are any errors
|
||||
*/
|
||||
protected String moveOnHandToShipmentASI(MProduct product, int M_Locator_ID, int M_AttributeSetInstance_ID, BigDecimal qty,
|
||||
Timestamp dateMaterialPolicy, int M_InOutLine_ID, boolean reversal, String trxName) {
|
||||
if (qty.signum() == 0 || (qty.signum() < 0 && !reversal) || (qty.signum() > 0 && reversal))
|
||||
return null;
|
||||
if (M_AttributeSetInstance_ID == 0)
|
||||
return null;
|
||||
if (dateMaterialPolicy != null) {
|
||||
MStorageOnHand asi = MStorageOnHand.get(getCtx(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, dateMaterialPolicy, trxName);
|
||||
if (asi != null && asi.getQtyOnHand().signum() != 0)
|
||||
return null;
|
||||
|
||||
MStorageOnHand noasi = MStorageOnHand.get(getCtx(), M_Locator_ID, product.getM_Product_ID(), 0, dateMaterialPolicy, trxName);
|
||||
if (noasi != null && noasi.getM_AttributeSetInstance_ID()==0 && (noasi.getQtyOnHand().compareTo(qty) >= 0 || reversal)) {
|
||||
if (!(MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), 0, qty.negate(), dateMaterialPolicy, trxName))) {
|
||||
String lastError = CLogger.retrieveErrorString("");
|
||||
m_processMsg = "Cannot move Inventory OnHand (MA) to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
MTransaction trxFrom = new MTransaction (Env.getCtx(), getAD_Org_ID(), getMovementType(), M_Locator_ID, product.getM_Product_ID(), 0,
|
||||
qty.negate(), getMovementDate(), trxName);
|
||||
trxFrom.setM_InOutLine_ID(M_InOutLine_ID);
|
||||
if (!trxFrom.save()) {
|
||||
m_processMsg = "Transaction From not inserted (MA) [" + product.getValue() + "] - ";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
if (!(MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, qty, dateMaterialPolicy, trxName))) {
|
||||
String lastError = CLogger.retrieveErrorString("");
|
||||
m_processMsg = "Cannot move Inventory OnHand (MA) to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
MTransaction trxTo = new MTransaction (Env.getCtx(), getAD_Org_ID(), getMovementType(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID,
|
||||
qty, getMovementDate(), trxName);
|
||||
trxTo.setM_InOutLine_ID(M_InOutLine_ID);
|
||||
if (!trxTo.save()) {
|
||||
m_processMsg = "Transaction To not inserted (MA) [" + product.getValue() + "] - ";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BigDecimal totalASI = BigDecimal.ZERO;
|
||||
BigDecimal totalOnHand = BigDecimal.ZERO;
|
||||
MStorageOnHand[] storages = MStorageOnHand.getWarehouse(getCtx(), 0,
|
||||
product.getM_Product_ID(), M_AttributeSetInstance_ID, null,
|
||||
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false,
|
||||
M_Locator_ID, get_TrxName());
|
||||
for (MStorageOnHand onhand : storages) {
|
||||
totalASI = totalASI.add(onhand.getQtyOnHand());
|
||||
}
|
||||
if (!reversal && totalASI.signum() != 0)
|
||||
return null;
|
||||
else if (reversal && (totalASI.compareTo(qty) < 0))
|
||||
return null;
|
||||
|
||||
storages = MStorageOnHand.getWarehouse(getCtx(), 0,
|
||||
product.getM_Product_ID(), 0, null,
|
||||
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), true,
|
||||
M_Locator_ID, get_TrxName());
|
||||
List<MStorageOnHand> nonASIList = new ArrayList<>();
|
||||
for (MStorageOnHand storage : storages) {
|
||||
if (storage.getM_AttributeSetInstance_ID() == 0) {
|
||||
totalOnHand = totalOnHand.add(storage.getQtyOnHand());
|
||||
nonASIList.add(storage);
|
||||
}
|
||||
}
|
||||
if (totalOnHand.compareTo(qty) >= 0 || reversal) {
|
||||
BigDecimal totalToMove = qty;
|
||||
for (MStorageOnHand onhand : nonASIList) {
|
||||
BigDecimal toMove = totalToMove;
|
||||
if (!reversal && toMove.compareTo(onhand.getQtyOnHand()) >= 0) {
|
||||
toMove = onhand.getQtyOnHand();
|
||||
}
|
||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), 0, toMove.negate(), onhand.getDateMaterialPolicy(), trxName)) {
|
||||
String lastError = CLogger.retrieveErrorString("");
|
||||
m_processMsg = "Cannot move Inventory OnHand to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
MTransaction trxFrom = new MTransaction (Env.getCtx(), getAD_Org_ID(), getMovementType(), M_Locator_ID, product.getM_Product_ID(), 0,
|
||||
toMove.negate(), getMovementDate(), trxName);
|
||||
trxFrom.setM_InOutLine_ID(M_InOutLine_ID);
|
||||
if (!trxFrom.save()) {
|
||||
m_processMsg = "Transaction From not inserted (MA) [" + product.getValue() + "] - ";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
dateMaterialPolicy = onhand.getDateMaterialPolicy();
|
||||
totalToMove = totalToMove.subtract(toMove);
|
||||
if ((!reversal && totalToMove.signum() <= 0) || (reversal && totalToMove.signum() >= 0))
|
||||
break;
|
||||
}
|
||||
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, qty, dateMaterialPolicy, trxName)) {
|
||||
String lastError = CLogger.retrieveErrorString("");
|
||||
m_processMsg = "Cannot move Inventory OnHand to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
MTransaction trxTo = new MTransaction (Env.getCtx(), getAD_Org_ID(), getMovementType(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID,
|
||||
qty, getMovementDate(), trxName);
|
||||
trxTo.setM_InOutLine_ID(M_InOutLine_ID);
|
||||
if (!trxTo.save()) {
|
||||
m_processMsg = "Transaction To not inserted (MA) [" + product.getValue() + "] - ";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
} // MInOut
|
||||
|
|
|
@ -947,6 +947,32 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
|||
return qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Quantity On Hand of Warehouse with ASI=0
|
||||
* @param M_Product_ID
|
||||
* @param M_Warehouse_ID
|
||||
* @param trxName
|
||||
* @return QtyOnHand
|
||||
*/
|
||||
public static BigDecimal getQtyOnHandWithASIZero(int M_Product_ID, int M_Warehouse_ID, String trxName) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append(" SELECT SUM(QtyOnHand) FROM M_StorageOnHand oh JOIN M_Locator loc ON (oh.M_Locator_ID=loc.M_Locator_ID)")
|
||||
.append(" WHERE oh.M_Product_ID=?")
|
||||
.append(" AND loc.M_Warehouse_ID=?")
|
||||
.append(" AND oh.M_AttributeSetInstance_ID=0");
|
||||
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
params.add(M_Product_ID);
|
||||
params.add(M_Warehouse_ID);
|
||||
|
||||
BigDecimal qty = DB.getSQLValueBD(trxName, sql.toString(), params);
|
||||
if (qty == null)
|
||||
qty = Env.ZERO;
|
||||
|
||||
return qty;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Quantity On Hand of Warehouse Available for Reservation
|
||||
* @param M_Product_ID
|
||||
|
@ -980,6 +1006,33 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
|||
return qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Quantity On Hand of Warehouse Available for Reservation with ASI=0
|
||||
* @param M_Product_ID
|
||||
* @param M_Warehouse_ID
|
||||
* @param trxName
|
||||
* @return QtyOnHand
|
||||
*/
|
||||
public static BigDecimal getQtyOnHandForReservationWithASIZero(int M_Product_ID, int M_Warehouse_ID, String trxName) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append(" SELECT SUM(QtyOnHand) FROM M_StorageOnHand oh"
|
||||
+ " JOIN M_Locator loc ON (oh.M_Locator_ID=loc.M_Locator_ID)"
|
||||
+ " LEFT JOIN M_LocatorType lt ON (loc.M_LocatorType_ID=lt.M_LocatorType_ID)")
|
||||
.append(" WHERE oh.M_Product_ID=?")
|
||||
.append(" AND loc.M_Warehouse_ID=? AND COALESCE(lt.IsAvailableForReservation,'Y')='Y'")
|
||||
.append(" AND oh.M_AttributeSetInstance_ID=0");
|
||||
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
params.add(M_Product_ID);
|
||||
params.add(M_Warehouse_ID);
|
||||
|
||||
BigDecimal qty = DB.getSQLValueBDEx(trxName, sql.toString(), params);
|
||||
if (qty == null)
|
||||
qty = Env.ZERO;
|
||||
|
||||
return qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Quantity On Hand of Warehouse that's available for shipping
|
||||
* @param M_Product_ID
|
||||
|
@ -1012,6 +1065,32 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
|||
return qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Quantity On Hand of Warehouse that's available for shipping with ASI=0
|
||||
* @param M_Product_ID
|
||||
* @param M_Warehouse_ID
|
||||
* @param trxName
|
||||
* @return QtyOnHand
|
||||
*/
|
||||
public static BigDecimal getQtyOnHandForShippingWithASIZero(int M_Product_ID, int M_Warehouse_ID, String trxName) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append(" SELECT SUM(QtyOnHand) FROM M_StorageOnHand oh JOIN M_Locator loc ON (oh.M_Locator_ID=loc.M_Locator_ID)")
|
||||
.append(" LEFT JOIN M_LocatorType lt ON (loc.M_LocatorType_ID=lt.M_LocatorType_ID)")
|
||||
.append(" WHERE oh.M_Product_ID=?")
|
||||
.append(" AND loc.M_Warehouse_ID=? AND COALESCE(lt.IsAvailableForShipping,'Y')='Y'")
|
||||
.append(" AND oh.M_AttributeSetInstance_ID=0");
|
||||
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
params.add(M_Product_ID);
|
||||
params.add(M_Warehouse_ID);
|
||||
|
||||
BigDecimal qty = DB.getSQLValueBDEx(trxName, sql.toString(), params);
|
||||
if (qty == null)
|
||||
qty = Env.ZERO;
|
||||
|
||||
return qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Quantity On Hand of Locator
|
||||
* @param M_Product_ID
|
||||
|
@ -1043,6 +1122,31 @@ public class MStorageOnHand extends X_M_StorageOnHand
|
|||
return qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Quantity On Hand of Locator wtih ASI=0
|
||||
* @param M_Product_ID
|
||||
* @param M_Locator_ID
|
||||
* @param trxName
|
||||
* @return QtyOnHand
|
||||
*/
|
||||
public static BigDecimal getQtyOnHandForLocatorWithASIZero(int M_Product_ID, int M_Locator_ID, String trxName) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append(" SELECT SUM(oh.QtyOnHand) FROM M_StorageOnHand oh")
|
||||
.append(" WHERE oh.M_Product_ID=?")
|
||||
.append(" AND oh.M_Locator_ID=?")
|
||||
.append(" AND oh.M_AttributeSetInstance_ID=0");
|
||||
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
params.add(M_Product_ID);
|
||||
params.add(M_Locator_ID);
|
||||
|
||||
BigDecimal qty = DB.getSQLValueBD(trxName, sql.toString(), params);
|
||||
if (qty == null)
|
||||
qty = Env.ZERO;
|
||||
|
||||
return qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Representation
|
||||
* @return info
|
||||
|
|
|
@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.compiere.model.MAllocationHdr;
|
||||
|
@ -50,6 +51,7 @@ import org.compiere.model.MProduct;
|
|||
import org.compiere.model.MStorageOnHand;
|
||||
import org.compiere.model.MStorageReservation;
|
||||
import org.compiere.model.MStorageReservationLog;
|
||||
import org.compiere.model.MTransaction;
|
||||
import org.compiere.model.MUOM;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.model.Query;
|
||||
|
@ -78,6 +80,7 @@ public class SalesOrderTest extends AbstractTestCase {
|
|||
private static final int PRODUCT_AZALEA = 128;
|
||||
private static final int PRODUCT_FERT50 = 136;
|
||||
private static final int PRODUCT_MARY = 132;
|
||||
private static final int PRODUCT_PCHAIR = 133;
|
||||
private static final int ORG_FERTILIZER = 50001;
|
||||
private static final int WAREHOUSE_FERTILIZER = 50002;
|
||||
private static final int WAREHOUSE_HQ_TRANSIT = 50000;
|
||||
|
@ -1009,4 +1012,109 @@ public class SalesOrderTest extends AbstractTestCase {
|
|||
success = order.save();
|
||||
assertEquals(false, success);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetASIWhenShipping() {
|
||||
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||
order.setBPartner(MBPartner.get(Env.getCtx(), BP_JOE_BLOCK));
|
||||
order.setC_DocTypeTarget_ID(MOrder.DocSubTypeSO_Standard);
|
||||
order.setDeliveryRule(MOrder.DELIVERYRULE_CompleteOrder);
|
||||
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(), PRODUCT_PCHAIR));
|
||||
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(), "Unexpected Order document status");
|
||||
line1.load(getTrxName());
|
||||
assertEquals(1, line1.getQtyReserved().intValue(), "Unexpected order line qty reserved value");
|
||||
|
||||
int originalOnHand = MStorageOnHand.getQtyOnHandWithASIZero(PRODUCT_PCHAIR, getM_Warehouse_ID(), getTrxName()).intValue();
|
||||
|
||||
MInOut shipment = new MInOut(order, 120, order.getDateOrdered());
|
||||
shipment.setDocStatus(DocAction.STATUS_Drafted);
|
||||
shipment.setDocAction(DocAction.ACTION_Complete);
|
||||
shipment.saveEx();
|
||||
|
||||
MInOutLine shipmentLine = new MInOutLine(shipment);
|
||||
shipmentLine.setOrderLine(line1, 0, new BigDecimal("1"));
|
||||
shipmentLine.setQty(new BigDecimal("1"));
|
||||
MAttributeSetInstance asi = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi.setM_AttributeSet_ID(MProduct.get(PRODUCT_PCHAIR).getM_AttributeSet_ID());
|
||||
asi.setSerNo("PChair Serial #1000000");
|
||||
asi.saveEx();
|
||||
shipmentLine.setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID());
|
||||
shipmentLine.saveEx();
|
||||
|
||||
info = MWorkflow.runDocumentActionWorkflow(shipment, DocAction.ACTION_Complete);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
shipment.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Completed, shipment.getDocStatus(), "Unexpected Shipment document status");
|
||||
|
||||
int newOnHand = MStorageOnHand.getQtyOnHandWithASIZero(PRODUCT_PCHAIR, getM_Warehouse_ID(), getTrxName()).intValue();
|
||||
assertEquals(originalOnHand-1, newOnHand, "Unexpected on hand quantity");
|
||||
|
||||
int asiOnHand = MStorageOnHand.getQtyOnHand(PRODUCT_PCHAIR, getM_Warehouse_ID(), asi.get_ID(), getTrxName()).intValue();
|
||||
int asiRecords = 0;
|
||||
MStorageOnHand[] storages = MStorageOnHand.getOfProduct(Env.getCtx(), PRODUCT_PCHAIR, getTrxName());
|
||||
for (MStorageOnHand storage : storages) {
|
||||
if (storage.getM_Warehouse_ID()==getM_Warehouse_ID() && storage.getM_AttributeSetInstance_ID()==asi.get_ID()) {
|
||||
asiRecords++;
|
||||
}
|
||||
}
|
||||
assertEquals(0, asiOnHand, "Unexpected on hand quantity for Serial ASI");
|
||||
assertEquals(1, asiRecords, "Unexpected number of Serial ASI Storage records");
|
||||
|
||||
Query query = new Query(Env.getCtx(), MTransaction.Table_Name, "M_InOutLine_ID=? AND M_Product_ID=? AND M_AttributeSetInstance_ID=0", getTrxName());
|
||||
MTransaction trxFrom = query.setParameters(shipmentLine.get_ID(), shipmentLine.getM_Product_ID()).first();
|
||||
assertNotNull(trxFrom, "Can't find MTransaction record for no ASI MTransaction record");
|
||||
assertEquals(-1, trxFrom.getMovementQty().intValue(), "Unexpected movement qty for no ASI MTransaction record");
|
||||
|
||||
query = new Query(Env.getCtx(), MTransaction.Table_Name, "M_InOutLine_ID=? AND M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
List<MTransaction> asiTrxs = query.setParameters(shipmentLine.get_ID(), shipmentLine.getM_Product_ID(), shipmentLine.getM_AttributeSetInstance_ID())
|
||||
.setOrderBy("M_Transaction_ID")
|
||||
.list();
|
||||
assertEquals(2, asiTrxs.size(), "Unexpected number of records for ASI MTransaction");
|
||||
assertEquals(1, asiTrxs.get(0).getMovementQty().intValue(), "Unexpected movement qty for first ASI MTransaction record");
|
||||
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected movement qty for second ASI MTransaction record");
|
||||
|
||||
//reverse the MR
|
||||
shipment.load(getTrxName());
|
||||
info = MWorkflow.runDocumentActionWorkflow(shipment, DocAction.ACTION_Reverse_Accrual);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
shipment.load(getTrxName());
|
||||
assertEquals(DocAction.STATUS_Reversed, shipment.getDocStatus(), "Unexpected Shipment document status");
|
||||
newOnHand = MStorageOnHand.getQtyOnHandWithASIZero(PRODUCT_PCHAIR, getM_Warehouse_ID(), getTrxName()).intValue();
|
||||
assertEquals(originalOnHand, newOnHand, "Unexpected on hand quantity no ASI");
|
||||
asiOnHand = MStorageOnHand.getQtyOnHand(PRODUCT_PCHAIR, getM_Warehouse_ID(), asi.get_ID(), getTrxName()).intValue();
|
||||
assertEquals(0, asiOnHand, "Unexpected on hand quantity for Serial ASI");
|
||||
|
||||
MInOut reversal = new MInOut(Env.getCtx(), shipment.getReversal_ID(), getTrxName());
|
||||
MInOutLine[] reversalLines = reversal.getLines();
|
||||
query = new Query(Env.getCtx(), MTransaction.Table_Name, "M_InOutLine_ID=? AND M_Product_ID=? AND M_AttributeSetInstance_ID=0", getTrxName());
|
||||
List<MTransaction> noASITrxs = query.setParameters(reversalLines[0].get_ID(), reversalLines[0].getM_Product_ID())
|
||||
.setOrderBy("M_Transaction_ID")
|
||||
.list();
|
||||
assertEquals(1, noASITrxs.size(), "Unexpected number of records for reversal no ASI MTransaction");
|
||||
assertEquals(1, asiTrxs.get(0).getMovementQty().intValue(), "Unexpected reversal movement qty for no ASI MTransaction record");
|
||||
|
||||
query = new Query(Env.getCtx(), MTransaction.Table_Name, "M_InOutLine_ID=? AND M_Product_ID=? AND M_AttributeSetInstance_ID=?", getTrxName());
|
||||
asiTrxs = query.setParameters(reversalLines[0].get_ID(), reversalLines[0].getM_Product_ID(), reversalLines[0].getM_AttributeSetInstance_ID())
|
||||
.setOrderBy("M_Transaction_ID")
|
||||
.list();
|
||||
assertEquals(2, asiTrxs.size(), "Unexpected number of records for reversal ASI MTransaction");
|
||||
assertEquals(1, asiTrxs.get(0).getMovementQty().intValue(), "Unexpected reversal movement qty for first ASI MTransaction record");
|
||||
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected reversal movement qty for second ASI MTransaction record");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue