IDEMPIERE-2172 Attribute set with mandatory type = When Shipping not … (#1040)
* IDEMPIERE-2172 Attribute set with mandatory type = When Shipping not working Fix reversal and add more unit test * IDEMPIERE-2172 Attribute set with mandatory type = When Shipping not working Use constant for movement type checking
This commit is contained in:
parent
5c675536cd
commit
3530351601
|
@ -1421,7 +1421,7 @@ 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
|
||||
if (product != null && QtyMA.signum() < 0 && MovementType.equals(MOVEMENTTYPE_CustomerShipment) && 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(),
|
||||
|
@ -1455,7 +1455,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
if (product != null && QtyMA.signum() > 0 && MovementType.equals("C-") && ma.getM_AttributeSetInstance_ID() > 0
|
||||
if (product != null && QtyMA.signum() > 0 && MovementType.equals(MOVEMENTTYPE_CustomerShipment) && 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(),
|
||||
|
@ -1496,7 +1496,7 @@ 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
|
||||
if (product != null && MovementType.equals(MOVEMENTTYPE_CustomerShipment) && 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());
|
||||
|
@ -1596,10 +1596,10 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
if (product != null && MovementType.equals("C-") && sLine.getM_AttributeSetInstance_ID() > 0 && Qty.signum() > 0
|
||||
if (product != null && MovementType.equals(MOVEMENTTYPE_CustomerShipment) && 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());
|
||||
String status = moveOnHandToShipmentASI(product, sLine.getM_Locator_ID(), sLine.getM_AttributeSetInstance_ID(), Qty.negate(), getMovementDate(), sLine.get_ID(), true, get_TrxName());
|
||||
if (status != null)
|
||||
return status;
|
||||
}
|
||||
|
@ -2392,7 +2392,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
{
|
||||
MInOutLineMA ma = new MInOutLineMA (rLine,
|
||||
mas[j].getM_AttributeSetInstance_ID(),
|
||||
mas[j].getMovementQty().negate(),mas[j].getDateMaterialPolicy(),true);
|
||||
mas[j].getMovementQty().negate(),mas[j].getDateMaterialPolicy(),mas[j].isAutoGenerated());
|
||||
ma.saveEx();
|
||||
}
|
||||
}
|
||||
|
@ -2625,7 +2625,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
/**
|
||||
* 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_Locator_ID shipment line locator id
|
||||
* @param M_AttributeSetInstance_ID
|
||||
* @param qty
|
||||
* @param dateMaterialPolicy
|
||||
|
@ -2642,14 +2642,13 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
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)
|
||||
if (asi != null && asi.getQtyOnHand().signum() != 0 && !reversal)
|
||||
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))) {
|
||||
if (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;
|
||||
m_processMsg = "Cannot move Inventory OnHand to Non 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,
|
||||
|
@ -2659,70 +2658,6 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
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;
|
||||
|
@ -2735,9 +2670,83 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
|||
m_processMsg = "Transaction To not inserted (MA) [" + product.getValue() + "] - ";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
} else {
|
||||
return doMove(product, M_Locator_ID, M_AttributeSetInstance_ID, dateMaterialPolicy, qty, M_InOutLine_ID, reversal, trxName);
|
||||
}
|
||||
} else {
|
||||
BigDecimal totalASI = 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;
|
||||
|
||||
return doMove(product, M_Locator_ID, M_AttributeSetInstance_ID, dateMaterialPolicy, qty, M_InOutLine_ID, reversal, trxName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String doMove(MProduct product, int M_Locator_ID, int M_AttributeSetInstance_ID, Timestamp dateMaterialPolicy, BigDecimal qty,
|
||||
int M_InOutLine_ID, boolean reversal, String trxName) {
|
||||
MStorageOnHand[] storages;
|
||||
BigDecimal totalOnHand = BigDecimal.ZERO;
|
||||
Timestamp onHandDateMaterialPolicy = 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 Non 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;
|
||||
}
|
||||
onHandDateMaterialPolicy = 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 != null ? dateMaterialPolicy : onHandDateMaterialPolicy), 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
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
package org.idempiere.test.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.compiere.model.MPayment;
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.compiere.model.MBPartner;
|
|||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MInOutLineMA;
|
||||
import org.compiere.model.MInvoice;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
|
@ -1090,6 +1091,8 @@ public class SalesOrderTest extends AbstractTestCase {
|
|||
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected movement qty for second ASI MTransaction record");
|
||||
|
||||
//reverse the MR
|
||||
Timestamp tomorrow = TimeUtil.addDays(today, 1);
|
||||
Env.setContext(Env.getCtx(), Env.DATE, tomorrow);
|
||||
shipment.load(getTrxName());
|
||||
info = MWorkflow.runDocumentActionWorkflow(shipment, DocAction.ACTION_Reverse_Accrual);
|
||||
assertFalse(info.isError(), info.getSummary());
|
||||
|
@ -1099,6 +1102,14 @@ public class SalesOrderTest extends AbstractTestCase {
|
|||
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");
|
||||
storages = MStorageOnHand.getOfProduct(Env.getCtx(), PRODUCT_PCHAIR, getTrxName());
|
||||
for (MStorageOnHand storage : storages) {
|
||||
if (storage.getM_Warehouse_ID() == getM_Warehouse_ID()) {
|
||||
if (storage.getM_AttributeSetInstance_ID() == asi.get_ID()) {
|
||||
assertEquals(0, storage.getQtyOnHand().intValue(), "Unexpected qty on hand for asi: " + storage.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MInOut reversal = new MInOut(Env.getCtx(), shipment.getReversal_ID(), getTrxName());
|
||||
MInOutLine[] reversalLines = reversal.getLines();
|
||||
|
@ -1107,7 +1118,7 @@ public class SalesOrderTest extends AbstractTestCase {
|
|||
.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");
|
||||
assertEquals(1, noASITrxs.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())
|
||||
|
@ -1117,4 +1128,177 @@ public class SalesOrderTest extends AbstractTestCase {
|
|||
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");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetASIWhenShipping2() {
|
||||
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("2"));
|
||||
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(2, 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("2"));
|
||||
shipmentLine.setQty(new BigDecimal("2"));
|
||||
shipmentLine.saveEx();
|
||||
|
||||
MAttributeSetInstance asi1 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi1.setM_AttributeSet_ID(MProduct.get(PRODUCT_PCHAIR).getM_AttributeSet_ID());
|
||||
asi1.setSerNo("PChair Serial #1000000");
|
||||
asi1.saveEx();
|
||||
MAttributeSetInstance asi2 = new MAttributeSetInstance(Env.getCtx(), 0, getTrxName());
|
||||
asi2.setM_AttributeSet_ID(MProduct.get(PRODUCT_PCHAIR).getM_AttributeSet_ID());
|
||||
asi2.setSerNo("PChair Serial #1000000");
|
||||
asi2.saveEx();
|
||||
MInOutLineMA ma1 = new MInOutLineMA(Env.getCtx(), 0, getTrxName());
|
||||
ma1.setM_AttributeSetInstance_ID(asi1.get_ID());
|
||||
ma1.setM_InOutLine_ID(shipmentLine.get_ID());
|
||||
ma1.setDateMaterialPolicy(shipment.getMovementDate());
|
||||
ma1.setMovementQty(new BigDecimal("1"));
|
||||
ma1.setIsAutoGenerated(false);
|
||||
ma1.saveEx();
|
||||
MInOutLineMA ma2 = new MInOutLineMA(Env.getCtx(), 0, getTrxName());
|
||||
ma2.setM_AttributeSetInstance_ID(asi2.get_ID());
|
||||
ma2.setM_InOutLine_ID(shipmentLine.get_ID());
|
||||
ma2.setDateMaterialPolicy(shipment.getMovementDate());
|
||||
ma2.setMovementQty(new BigDecimal("1"));
|
||||
ma2.setIsAutoGenerated(false);
|
||||
ma2.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-2, newOnHand, "Unexpected on hand quantity");
|
||||
|
||||
int asiOnHand = MStorageOnHand.getQtyOnHand(PRODUCT_PCHAIR, getM_Warehouse_ID(), asi1.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()==asi1.get_ID()) {
|
||||
asiRecords++;
|
||||
}
|
||||
}
|
||||
assertEquals(0, asiOnHand, "Unexpected on hand quantity for Serial ASI 1");
|
||||
assertEquals(1, asiRecords, "Unexpected number of Serial ASI 1 Storage records");
|
||||
|
||||
asiOnHand = MStorageOnHand.getQtyOnHand(PRODUCT_PCHAIR, getM_Warehouse_ID(), asi2.get_ID(), getTrxName()).intValue();
|
||||
asiRecords = 0;
|
||||
storages = MStorageOnHand.getOfProduct(Env.getCtx(), PRODUCT_PCHAIR, getTrxName());
|
||||
for (MStorageOnHand storage : storages) {
|
||||
if (storage.getM_Warehouse_ID()==getM_Warehouse_ID() && storage.getM_AttributeSetInstance_ID()==asi2.get_ID()) {
|
||||
asiRecords++;
|
||||
}
|
||||
}
|
||||
assertEquals(0, asiOnHand, "Unexpected on hand quantity for Serial ASI 2");
|
||||
assertEquals(1, asiRecords, "Unexpected number of Serial ASI 2 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(), ma1.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 1 MTransaction record");
|
||||
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected movement qty for second ASI 1 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(shipmentLine.get_ID(), shipmentLine.getM_Product_ID(), ma2.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 2 MTransaction record");
|
||||
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected movement qty for second ASI 2 MTransaction record");
|
||||
|
||||
//reverse the MR
|
||||
Timestamp tomorrow = TimeUtil.addDays(today, 1);
|
||||
Env.setContext(Env.getCtx(), Env.DATE, tomorrow);
|
||||
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(), asi1.get_ID(), getTrxName()).intValue();
|
||||
assertEquals(0, asiOnHand, "Unexpected on hand quantity for Serial ASI 1");
|
||||
storages = MStorageOnHand.getOfProduct(Env.getCtx(), PRODUCT_PCHAIR, getTrxName());
|
||||
for (MStorageOnHand storage : storages) {
|
||||
if (storage.getM_Warehouse_ID() == getM_Warehouse_ID()) {
|
||||
if (storage.getM_AttributeSetInstance_ID() == asi1.get_ID()) {
|
||||
assertEquals(0, storage.getQtyOnHand().intValue(), "Unexpected qty on hand for asi 1: " + storage.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asiOnHand = MStorageOnHand.getQtyOnHand(PRODUCT_PCHAIR, getM_Warehouse_ID(), asi2.get_ID(), getTrxName()).intValue();
|
||||
assertEquals(0, asiOnHand, "Unexpected on hand quantity for Serial ASI 2");
|
||||
storages = MStorageOnHand.getOfProduct(Env.getCtx(), PRODUCT_PCHAIR, getTrxName());
|
||||
for (MStorageOnHand storage : storages) {
|
||||
if (storage.getM_Warehouse_ID() == getM_Warehouse_ID()) {
|
||||
if (storage.getM_AttributeSetInstance_ID() == asi2.get_ID()) {
|
||||
assertEquals(0, storage.getQtyOnHand().intValue(), "Unexpected qty on hand for asi 2: " + storage.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(2, noASITrxs.size(), "Unexpected number of records for reversal no ASI MTransaction");
|
||||
assertEquals(1, noASITrxs.get(0).getMovementQty().intValue(), "Unexpected reversal movement qty for no ASI MTransaction record");
|
||||
assertEquals(1, noASITrxs.get(1).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(), asi1.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 1 MTransaction record");
|
||||
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected reversal movement qty for second ASI 1 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(), asi2.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 2 MTransaction record");
|
||||
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected reversal movement qty for second ASI 2 MTransaction record");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue