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
|
if (MovementType.charAt(1) == '-') // C- Customer Shipment - V- Vendor Return
|
||||||
QtyMA = QtyMA.negate();
|
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())
|
&& 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(),
|
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;
|
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())
|
&& 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(),
|
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 (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())
|
&& 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());
|
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;
|
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())
|
&& 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)
|
if (status != null)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -2392,7 +2392,7 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
{
|
{
|
||||||
MInOutLineMA ma = new MInOutLineMA (rLine,
|
MInOutLineMA ma = new MInOutLineMA (rLine,
|
||||||
mas[j].getM_AttributeSetInstance_ID(),
|
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();
|
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
|
* 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 product
|
||||||
* @param M_Locator_ID
|
* @param M_Locator_ID shipment line locator id
|
||||||
* @param M_AttributeSetInstance_ID
|
* @param M_AttributeSetInstance_ID
|
||||||
* @param qty
|
* @param qty
|
||||||
* @param dateMaterialPolicy
|
* @param dateMaterialPolicy
|
||||||
|
@ -2642,14 +2642,13 @@ public class MInOut extends X_M_InOut implements DocAction, IDocsPostProcess
|
||||||
return null;
|
return null;
|
||||||
if (dateMaterialPolicy != null) {
|
if (dateMaterialPolicy != null) {
|
||||||
MStorageOnHand asi = MStorageOnHand.get(getCtx(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, dateMaterialPolicy, trxName);
|
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;
|
return null;
|
||||||
|
|
||||||
MStorageOnHand noasi = MStorageOnHand.get(getCtx(), M_Locator_ID, product.getM_Product_ID(), 0, dateMaterialPolicy, trxName);
|
if (reversal) {
|
||||||
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 (!(MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), 0, qty.negate(), dateMaterialPolicy, trxName))) {
|
|
||||||
String lastError = CLogger.retrieveErrorString("");
|
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;
|
return DocAction.STATUS_Invalid;
|
||||||
}
|
}
|
||||||
MTransaction trxFrom = new MTransaction (Env.getCtx(), getAD_Org_ID(), getMovementType(), M_Locator_ID, product.getM_Product_ID(), 0,
|
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() + "] - ";
|
m_processMsg = "Transaction From not inserted (MA) [" + product.getValue() + "] - ";
|
||||||
return DocAction.STATUS_Invalid;
|
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)) {
|
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(), M_Locator_ID, product.getM_Product_ID(), M_AttributeSetInstance_ID, qty, dateMaterialPolicy, trxName)) {
|
||||||
String lastError = CLogger.retrieveErrorString("");
|
String lastError = CLogger.retrieveErrorString("");
|
||||||
m_processMsg = "Cannot move Inventory OnHand to Shipment ASI [" + product.getValue() + "] - " + lastError;
|
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() + "] - ";
|
m_processMsg = "Transaction To not inserted (MA) [" + product.getValue() + "] - ";
|
||||||
return DocAction.STATUS_Invalid;
|
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;
|
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
|
} // MInOut
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
package org.idempiere.test.model;
|
package org.idempiere.test.model;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
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 static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import org.compiere.model.MPayment;
|
import org.compiere.model.MPayment;
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.compiere.model.MBPartner;
|
||||||
import org.compiere.model.MClient;
|
import org.compiere.model.MClient;
|
||||||
import org.compiere.model.MInOut;
|
import org.compiere.model.MInOut;
|
||||||
import org.compiere.model.MInOutLine;
|
import org.compiere.model.MInOutLine;
|
||||||
|
import org.compiere.model.MInOutLineMA;
|
||||||
import org.compiere.model.MInvoice;
|
import org.compiere.model.MInvoice;
|
||||||
import org.compiere.model.MOrder;
|
import org.compiere.model.MOrder;
|
||||||
import org.compiere.model.MOrderLine;
|
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");
|
assertEquals(-1, asiTrxs.get(1).getMovementQty().intValue(), "Unexpected movement qty for second ASI MTransaction record");
|
||||||
|
|
||||||
//reverse the MR
|
//reverse the MR
|
||||||
|
Timestamp tomorrow = TimeUtil.addDays(today, 1);
|
||||||
|
Env.setContext(Env.getCtx(), Env.DATE, tomorrow);
|
||||||
shipment.load(getTrxName());
|
shipment.load(getTrxName());
|
||||||
info = MWorkflow.runDocumentActionWorkflow(shipment, DocAction.ACTION_Reverse_Accrual);
|
info = MWorkflow.runDocumentActionWorkflow(shipment, DocAction.ACTION_Reverse_Accrual);
|
||||||
assertFalse(info.isError(), info.getSummary());
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
@ -1099,6 +1102,14 @@ public class SalesOrderTest extends AbstractTestCase {
|
||||||
assertEquals(originalOnHand, newOnHand, "Unexpected on hand quantity no ASI");
|
assertEquals(originalOnHand, newOnHand, "Unexpected on hand quantity no ASI");
|
||||||
asiOnHand = MStorageOnHand.getQtyOnHand(PRODUCT_PCHAIR, getM_Warehouse_ID(), asi.get_ID(), getTrxName()).intValue();
|
asiOnHand = MStorageOnHand.getQtyOnHand(PRODUCT_PCHAIR, getM_Warehouse_ID(), asi.get_ID(), getTrxName()).intValue();
|
||||||
assertEquals(0, asiOnHand, "Unexpected on hand quantity for Serial ASI");
|
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());
|
MInOut reversal = new MInOut(Env.getCtx(), shipment.getReversal_ID(), getTrxName());
|
||||||
MInOutLine[] reversalLines = reversal.getLines();
|
MInOutLine[] reversalLines = reversal.getLines();
|
||||||
|
@ -1107,7 +1118,7 @@ public class SalesOrderTest extends AbstractTestCase {
|
||||||
.setOrderBy("M_Transaction_ID")
|
.setOrderBy("M_Transaction_ID")
|
||||||
.list();
|
.list();
|
||||||
assertEquals(1, noASITrxs.size(), "Unexpected number of records for reversal no ASI MTransaction");
|
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());
|
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())
|
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(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");
|
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