IDEMPIERE-5040 Stall M_InOutLine.QtyOverReceipt (#1005)
* IDEMPIERE-5040 Stall M_InOutLine.QtyOverReceipt * IDEMPIERE-5040 Stall M_InOutLine.QtyOverReceipt Drop the user of M_InOutLine.QtyOverReceipt column
This commit is contained in:
parent
744e84ccc5
commit
05447b38ce
|
@ -0,0 +1,23 @@
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- IDEMPIERE-5040 Stall M_InOutLine.QtyOverReceipt
|
||||||
|
-- Nov 19, 2021, 11:00:44 PM MYT
|
||||||
|
INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201096,'c97e6bf9-5754-485c-a983-5cb01429032f',TO_DATE('2021-11-19 23:00:43','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','m_inoutline_orderline_idx',TO_DATE('2021-11-19 23:00:43','YYYY-MM-DD HH24:MI:SS'),100,320,'N','N','N','N','N')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Nov 19, 2021, 11:00:58 PM MYT
|
||||||
|
INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201443,'4c920b11-27f2-40a5-b30f-cc8b525d942b',TO_DATE('2021-11-19 23:00:57','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2021-11-19 23:00:57','YYYY-MM-DD HH24:MI:SS'),100,3811,201096,10)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Nov 19, 2021, 11:01:04 PM MYT
|
||||||
|
CREATE INDEX m_inoutline_orderline_idx ON M_InOutLine (C_OrderLine_ID)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Nov 26, 2021, 6:14:22 AM MYT
|
||||||
|
UPDATE AD_Column SET IsActive='N',Updated=TO_DATE('2021-11-26 06:14:22','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210888
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('202111210850_IDEMPIERE-5040.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- IDEMPIERE-5040 Stall M_InOutLine.QtyOverReceipt
|
||||||
|
-- Nov 19, 2021, 11:00:44 PM MYT
|
||||||
|
INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201096,'c97e6bf9-5754-485c-a983-5cb01429032f',TO_TIMESTAMP('2021-11-19 23:00:43','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','m_inoutline_orderline_idx',TO_TIMESTAMP('2021-11-19 23:00:43','YYYY-MM-DD HH24:MI:SS'),100,320,'N','N','N','N','N')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Nov 19, 2021, 11:00:58 PM MYT
|
||||||
|
INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201443,'4c920b11-27f2-40a5-b30f-cc8b525d942b',TO_TIMESTAMP('2021-11-19 23:00:57','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2021-11-19 23:00:57','YYYY-MM-DD HH24:MI:SS'),100,3811,201096,10)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Nov 19, 2021, 11:01:04 PM MYT
|
||||||
|
CREATE INDEX m_inoutline_orderline_idx ON M_InOutLine (C_OrderLine_ID)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Nov 26, 2021, 6:14:22 AM MYT
|
||||||
|
UPDATE AD_Column SET IsActive='N',Updated=TO_TIMESTAMP('2021-11-26 06:14:22','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210888
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('202111210850_IDEMPIERE-5040.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -447,19 +447,6 @@ public interface I_M_InOutLine
|
||||||
*/
|
*/
|
||||||
public BigDecimal getQtyEntered();
|
public BigDecimal getQtyEntered();
|
||||||
|
|
||||||
/** Column name QtyOverReceipt */
|
|
||||||
public static final String COLUMNNAME_QtyOverReceipt = "QtyOverReceipt";
|
|
||||||
|
|
||||||
/** Set Over Receipt.
|
|
||||||
* Over Receipt Quantity
|
|
||||||
*/
|
|
||||||
public void setQtyOverReceipt (BigDecimal QtyOverReceipt);
|
|
||||||
|
|
||||||
/** Get Over Receipt.
|
|
||||||
* Over Receipt Quantity
|
|
||||||
*/
|
|
||||||
public BigDecimal getQtyOverReceipt();
|
|
||||||
|
|
||||||
/** Column name Ref_InOutLine_ID */
|
/** Column name Ref_InOutLine_ID */
|
||||||
public static final String COLUMNNAME_Ref_InOutLine_ID = "Ref_InOutLine_ID";
|
public static final String COLUMNNAME_Ref_InOutLine_ID = "Ref_InOutLine_ID";
|
||||||
|
|
||||||
|
|
|
@ -762,8 +762,6 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
line.setQtyOverReceipt(fromLine.getQtyOverReceipt());
|
|
||||||
|
|
||||||
//
|
//
|
||||||
line.setProcessed(false);
|
line.setProcessed(false);
|
||||||
if (line.save(get_TrxName()))
|
if (line.save(get_TrxName()))
|
||||||
|
@ -1358,8 +1356,6 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
log.fine("Material Transaction");
|
log.fine("Material Transaction");
|
||||||
MTransaction mtrx = null;
|
MTransaction mtrx = null;
|
||||||
|
|
||||||
//
|
|
||||||
BigDecimal overReceipt = BigDecimal.ZERO;
|
|
||||||
if (!isReversal())
|
if (!isReversal())
|
||||||
{
|
{
|
||||||
if (oLine != null)
|
if (oLine != null)
|
||||||
|
@ -1368,21 +1364,25 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
.subtract(oLine.getQtyDelivered());
|
.subtract(oLine.getQtyDelivered());
|
||||||
if (toDelivered.signum() < 0) // IDEMPIERE-2889
|
if (toDelivered.signum() < 0) // IDEMPIERE-2889
|
||||||
toDelivered = Env.ZERO;
|
toDelivered = Env.ZERO;
|
||||||
if (sLine.getMovementQty().compareTo(toDelivered) > 0)
|
|
||||||
overReceipt = sLine.getMovementQty().subtract(
|
|
||||||
toDelivered);
|
|
||||||
if (overReceipt.signum() != 0)
|
|
||||||
{
|
|
||||||
sLine.setQtyOverReceipt(overReceipt);
|
|
||||||
sLine.saveEx();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
BigDecimal storageReservationToUpdate = sLine.getMovementQty();
|
||||||
|
if (oLine != null)
|
||||||
{
|
{
|
||||||
overReceipt = sLine.getQtyOverReceipt();
|
if (!isReversal())
|
||||||
|
{
|
||||||
|
if (storageReservationToUpdate.compareTo(oLine.getQtyReserved()) > 0)
|
||||||
|
storageReservationToUpdate = oLine.getQtyReserved();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BigDecimal tmp = storageReservationToUpdate.negate().add(oLine.getQtyReserved());
|
||||||
|
if (tmp.compareTo(oLine.getQtyOrdered()) > 0)
|
||||||
|
storageReservationToUpdate = oLine.getQtyOrdered().subtract(oLine.getQtyReserved());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BigDecimal orderedQtyToUpdate = sLine.getMovementQty().subtract(overReceipt);
|
|
||||||
//
|
//
|
||||||
if (sLine.getM_AttributeSetInstance_ID() == 0)
|
if (sLine.getM_AttributeSetInstance_ID() == 0)
|
||||||
{
|
{
|
||||||
|
@ -1421,7 +1421,8 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oLine!=null && mtrx!=null && oLine.getQtyOrdered().signum() >= 0)
|
if (oLine!=null && mtrx!=null &&
|
||||||
|
((!isReversal() && oLine.getQtyReserved().signum() > 0) || (isReversal() && oLine.getQtyOrdered().signum() > 0)))
|
||||||
{
|
{
|
||||||
if (sLine.getC_OrderLine_ID() != 0 && oLine.getM_Product_ID() > 0)
|
if (sLine.getC_OrderLine_ID() != 0 && oLine.getM_Product_ID() > 0)
|
||||||
{
|
{
|
||||||
|
@ -1436,7 +1437,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
|
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
|
||||||
oLine.getM_Product_ID(),
|
oLine.getM_Product_ID(),
|
||||||
oLine.getM_AttributeSetInstance_ID(),
|
oLine.getM_AttributeSetInstance_ID(),
|
||||||
orderedQtyToUpdate.negate(),
|
storageReservationToUpdate.negate(),
|
||||||
isSOTrx(),
|
isSOTrx(),
|
||||||
get_TrxName(), tracer))
|
get_TrxName(), tracer))
|
||||||
{
|
{
|
||||||
|
@ -1510,7 +1511,8 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
m_processMsg = "Cannot correct Inventory OnHand [" + product.getValue() + "] - " + lastError;
|
m_processMsg = "Cannot correct Inventory OnHand [" + product.getValue() + "] - " + lastError;
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
}
|
}
|
||||||
if (oLine!=null && oLine.getQtyOrdered().signum() > 0 && oLine.getM_Product_ID() > 0)
|
if (oLine!=null && oLine.getM_Product_ID() > 0 &&
|
||||||
|
((!isReversal() && oLine.getQtyReserved().signum() > 0) || (isReversal() && oLine.getQtyOrdered().signum() > 0)))
|
||||||
{
|
{
|
||||||
IReservationTracer tracer = null;
|
IReservationTracer tracer = null;
|
||||||
IReservationTracerFactory factory = Core.getReservationTracerFactory();
|
IReservationTracerFactory factory = Core.getReservationTracerFactory();
|
||||||
|
@ -1523,7 +1525,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
|
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
|
||||||
oLine.getM_Product_ID(),
|
oLine.getM_Product_ID(),
|
||||||
oLine.getM_AttributeSetInstance_ID(),
|
oLine.getM_AttributeSetInstance_ID(),
|
||||||
orderedQtyToUpdate.negate(), isSOTrx(), get_TrxName(), tracer))
|
storageReservationToUpdate.negate(), isSOTrx(), get_TrxName(), tracer))
|
||||||
{
|
{
|
||||||
m_processMsg = "Cannot correct Inventory Reserved " + (isSOTrx()? "Reserved [" :"Ordered [") + product.getValue() + "]";
|
m_processMsg = "Cannot correct Inventory Reserved " + (isSOTrx()? "Reserved [" :"Ordered [") + product.getValue() + "]";
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
|
@ -1549,7 +1551,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
{
|
{
|
||||||
if (oLine.getQtyOrdered().signum() >= 0)
|
if (oLine.getQtyOrdered().signum() >= 0)
|
||||||
{
|
{
|
||||||
oLine.setQtyReserved(oLine.getQtyReserved().subtract(sLine.getMovementQty().subtract(sLine.getQtyOverReceipt())));
|
oLine.setQtyReserved(oLine.getQtyReserved().subtract(sLine.getMovementQty()));
|
||||||
|
|
||||||
if (oLine.getQtyReserved().signum() == -1)
|
if (oLine.getQtyReserved().signum() == -1)
|
||||||
oLine.setQtyReserved(Env.ZERO);
|
oLine.setQtyReserved(Env.ZERO);
|
||||||
|
@ -2312,7 +2314,6 @@ public class MInOut extends X_M_InOut implements DocAction
|
||||||
MInOutLine rLine = rLines[i];
|
MInOutLine rLine = rLines[i];
|
||||||
rLine.setQtyEntered(rLine.getQtyEntered().negate());
|
rLine.setQtyEntered(rLine.getQtyEntered().negate());
|
||||||
rLine.setMovementQty(rLine.getMovementQty().negate());
|
rLine.setMovementQty(rLine.getMovementQty().negate());
|
||||||
rLine.setQtyOverReceipt(rLine.getQtyOverReceipt().negate());
|
|
||||||
rLine.setM_AttributeSetInstance_ID(sLines[i].getM_AttributeSetInstance_ID());
|
rLine.setM_AttributeSetInstance_ID(sLines[i].getM_AttributeSetInstance_ID());
|
||||||
// Goodwill: store original (voided/reversed) document line
|
// Goodwill: store original (voided/reversed) document line
|
||||||
rLine.setReversalLine_ID(sLines[i].getM_InOutLine_ID());
|
rLine.setReversalLine_ID(sLines[i].getM_InOutLine_ID());
|
||||||
|
|
|
@ -2003,6 +2003,8 @@ public class MOrder extends X_C_Order implements DocAction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateOverReceipt();
|
||||||
|
|
||||||
setProcessed(true);
|
setProcessed(true);
|
||||||
m_processMsg = info.toString();
|
m_processMsg = info.toString();
|
||||||
//
|
//
|
||||||
|
@ -2010,7 +2012,15 @@ public class MOrder extends X_C_Order implements DocAction
|
||||||
return DocAction.STATUS_Completed;
|
return DocAction.STATUS_Completed;
|
||||||
} // completeIt
|
} // completeIt
|
||||||
|
|
||||||
|
private void updateOverReceipt() {
|
||||||
|
for(MOrderLine line : m_lines) {
|
||||||
|
if (line.getM_Product_ID() <= 0) continue;
|
||||||
|
if (line.getQtyDelivered().signum() > 0 && line.getQtyOrdered().compareTo(line.getQtyDelivered()) >= 0) {
|
||||||
|
DB.executeUpdateEx("UPDATE M_InOutLine Set QtyOverReceipt=0 WHERE C_OrderLine_ID=? AND QtyOverReceipt>0",
|
||||||
|
new Object[] {line.getC_OrderLine_ID()}, get_TrxName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected String landedCostAllocation() {
|
protected String landedCostAllocation() {
|
||||||
MOrderLandedCost[] landedCosts = MOrderLandedCost.getOfOrder(getC_Order_ID(), get_TrxName());
|
MOrderLandedCost[] landedCosts = MOrderLandedCost.getOfOrder(getC_Order_ID(), get_TrxName());
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class X_M_InOutLine extends PO implements I_M_InOutLine, I_Persistent
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 20211106L;
|
private static final long serialVersionUID = 20211126L;
|
||||||
|
|
||||||
/** Standard Constructor */
|
/** Standard Constructor */
|
||||||
public X_M_InOutLine (Properties ctx, int M_InOutLine_ID, String trxName)
|
public X_M_InOutLine (Properties ctx, int M_InOutLine_ID, String trxName)
|
||||||
|
@ -742,26 +742,6 @@ public class X_M_InOutLine extends PO implements I_M_InOutLine, I_Persistent
|
||||||
return bd;
|
return bd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set Over Receipt.
|
|
||||||
@param QtyOverReceipt
|
|
||||||
Over Receipt Quantity
|
|
||||||
*/
|
|
||||||
public void setQtyOverReceipt (BigDecimal QtyOverReceipt)
|
|
||||||
{
|
|
||||||
set_Value (COLUMNNAME_QtyOverReceipt, QtyOverReceipt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get Over Receipt.
|
|
||||||
@return Over Receipt Quantity
|
|
||||||
*/
|
|
||||||
public BigDecimal getQtyOverReceipt ()
|
|
||||||
{
|
|
||||||
BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_QtyOverReceipt);
|
|
||||||
if (bd == null)
|
|
||||||
return Env.ZERO;
|
|
||||||
return bd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set Referenced Shipment Line.
|
/** Set Referenced Shipment Line.
|
||||||
@param Ref_InOutLine_ID Referenced Shipment Line */
|
@param Ref_InOutLine_ID Referenced Shipment Line */
|
||||||
public void setRef_InOutLine_ID (int Ref_InOutLine_ID)
|
public void setRef_InOutLine_ID (int Ref_InOutLine_ID)
|
||||||
|
|
|
@ -487,14 +487,23 @@ public class Match
|
||||||
{
|
{
|
||||||
// Update Order Line
|
// Update Order Line
|
||||||
MOrderLine oLine = new MOrderLine(Env.getCtx(), Line_ID, trxName);
|
MOrderLine oLine = new MOrderLine(Env.getCtx(), Line_ID, trxName);
|
||||||
|
BigDecimal storageReservationToUpdate = null;
|
||||||
if (oLine.get_ID() != 0) // other in MInOut.completeIt
|
if (oLine.get_ID() != 0) // other in MInOut.completeIt
|
||||||
{
|
{
|
||||||
|
storageReservationToUpdate = oLine.getQtyReserved();
|
||||||
oLine.setQtyReserved(oLine.getQtyReserved().subtract(qty));
|
oLine.setQtyReserved(oLine.getQtyReserved().subtract(qty));
|
||||||
|
if (oLine.getQtyReserved().signum() == -1)
|
||||||
|
oLine.setQtyReserved(Env.ZERO);
|
||||||
|
else if (oLine.getQtyDelivered().compareTo(oLine.getQtyOrdered()) > 0)
|
||||||
|
oLine.setQtyReserved(Env.ZERO);
|
||||||
oLine.saveEx();
|
oLine.saveEx();
|
||||||
|
storageReservationToUpdate = storageReservationToUpdate.subtract(oLine.getQtyReserved());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Shipment Line
|
// Update Shipment Line
|
||||||
BigDecimal toDeliver = oLine.getQtyOrdered().subtract(oLine.getQtyDelivered());
|
BigDecimal toDeliver = oLine.getQtyOrdered().subtract(oLine.getQtyDelivered());
|
||||||
|
if (toDeliver.signum() < 0)
|
||||||
|
toDeliver = Env.ZERO;
|
||||||
if (sLine.getMovementQty().compareTo(toDeliver) <= 0)
|
if (sLine.getMovementQty().compareTo(toDeliver) <= 0)
|
||||||
{
|
{
|
||||||
sLine.setC_OrderLine_ID(Line_ID);
|
sLine.setC_OrderLine_ID(Line_ID);
|
||||||
|
@ -525,7 +534,7 @@ public class Match
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
// Correct Ordered Qty for Stocked Products (see MOrder.reserveStock / MInOut.processIt)
|
// Correct Ordered Qty for Stocked Products (see MOrder.reserveStock / MInOut.processIt)
|
||||||
if (oLine.get_ID() > 0 && oLine.getM_Product_ID() > 0 && oLine.getProduct().isStocked()) {
|
if (oLine.get_ID() > 0 && oLine.getM_Product_ID() > 0 && oLine.getProduct().isStocked() && storageReservationToUpdate != null) {
|
||||||
IReservationTracer tracer = null;
|
IReservationTracer tracer = null;
|
||||||
IReservationTracerFactory factory = Core.getReservationTracerFactory();
|
IReservationTracerFactory factory = Core.getReservationTracerFactory();
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
|
@ -537,7 +546,7 @@ public class Match
|
||||||
success = MStorageReservation.add (Env.getCtx(), oLine.getM_Warehouse_ID(),
|
success = MStorageReservation.add (Env.getCtx(), oLine.getM_Warehouse_ID(),
|
||||||
oLine.getM_Product_ID(),
|
oLine.getM_Product_ID(),
|
||||||
oLine.getM_AttributeSetInstance_ID(),
|
oLine.getM_AttributeSetInstance_ID(),
|
||||||
qty.negate(), oLine.getParent().isSOTrx(), trxName, tracer);
|
storageReservationToUpdate.negate(), oLine.getParent().isSOTrx(), trxName, tracer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ public class MatchInvTest extends AbstractTestCase {
|
||||||
|
|
||||||
info = MWorkflow.runDocumentActionWorkflow(delivery, DocAction.ACTION_Complete);
|
info = MWorkflow.runDocumentActionWorkflow(delivery, DocAction.ACTION_Complete);
|
||||||
delivery.load(getTrxName());
|
delivery.load(getTrxName());
|
||||||
assertFalse(info.isError());
|
assertFalse(info.isError(), info.getSummary());
|
||||||
assertEquals(DocAction.STATUS_Completed, delivery.getDocStatus());
|
assertEquals(DocAction.STATUS_Completed, delivery.getDocStatus());
|
||||||
|
|
||||||
if (!delivery.isPosted()) {
|
if (!delivery.isPosted()) {
|
||||||
|
|
|
@ -46,9 +46,12 @@ import org.compiere.model.MProduct;
|
||||||
import org.compiere.model.MStorageOnHand;
|
import org.compiere.model.MStorageOnHand;
|
||||||
import org.compiere.model.MStorageReservation;
|
import org.compiere.model.MStorageReservation;
|
||||||
import org.compiere.model.MStorageReservationLog;
|
import org.compiere.model.MStorageReservationLog;
|
||||||
|
import org.compiere.model.MSysConfig;
|
||||||
import org.compiere.model.Query;
|
import org.compiere.model.Query;
|
||||||
import org.compiere.process.DocAction;
|
import org.compiere.process.DocAction;
|
||||||
import org.compiere.process.ProcessInfo;
|
import org.compiere.process.ProcessInfo;
|
||||||
|
import org.compiere.util.CacheMgt;
|
||||||
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.TimeUtil;
|
import org.compiere.util.TimeUtil;
|
||||||
import org.compiere.wf.MWorkflow;
|
import org.compiere.wf.MWorkflow;
|
||||||
|
@ -482,4 +485,106 @@ public class PurchaseOrderTest extends AbstractTestCase {
|
||||||
ordered = MStorageReservation.get(Env.getCtx(), line1.getM_Warehouse_ID(), PRODUCT_WEEDER, 0, false, getTrxName());
|
ordered = MStorageReservation.get(Env.getCtx(), line1.getM_Warehouse_ID(), PRODUCT_WEEDER, 0, false, getTrxName());
|
||||||
assertTrue(log.getNewQty().equals(ordered.getQty()), "New Qty from MStorageReservationLog != Qty from MStorageReservation");
|
assertTrue(log.getNewQty().equals(ordered.getQty()), "New Qty from MStorageReservationLog != Qty from MStorageReservation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQtyOverReceipt() {
|
||||||
|
Properties ctx = Env.getCtx();
|
||||||
|
String trxName = getTrxName();
|
||||||
|
|
||||||
|
DB.executeUpdateEx("UPDATE AD_SysConfig SET Value='N' WHERE AD_Client_ID=0 AND Name=?",
|
||||||
|
new Object[] {MSysConfig.VALIDATE_MATCHING_TO_ORDERED_QTY}, null);
|
||||||
|
CacheMgt.get().reset();
|
||||||
|
|
||||||
|
BigDecimal initialQtyOrdered = getQtyOrdered(Env.getCtx(), PRODUCT_MULCH, getTrxName());
|
||||||
|
try {
|
||||||
|
MOrder order = new MOrder(ctx, 0, trxName);
|
||||||
|
order.setBPartner(MBPartner.get(ctx, BP_PATIO));
|
||||||
|
order.setC_DocTypeTarget_ID(DOCTYPE_PO);
|
||||||
|
order.setIsSOTrx(false);
|
||||||
|
order.setSalesRep_ID(USER_GARDENADMIN);
|
||||||
|
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(ctx, PRODUCT_MULCH));
|
||||||
|
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(trxName);
|
||||||
|
assertEquals(DocAction.STATUS_Completed, order.getDocStatus(), "Order not completed");
|
||||||
|
line1.load(trxName);
|
||||||
|
assertEquals(1, line1.getQtyReserved().intValue(), "Wrong Order line qty reserved value");
|
||||||
|
BigDecimal newQtyOrdered = getQtyOrdered(Env.getCtx(), PRODUCT_MULCH, getTrxName());
|
||||||
|
assertEquals(initialQtyOrdered.intValue()+1, newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||||
|
|
||||||
|
MInOut receipt1 = new MInOut(order, DOCTYPE_RECEIPT, order.getDateOrdered());
|
||||||
|
receipt1.setDocStatus(DocAction.STATUS_Drafted);
|
||||||
|
receipt1.setDocAction(DocAction.ACTION_Complete);
|
||||||
|
receipt1.saveEx();
|
||||||
|
|
||||||
|
MInOutLine receiptLine1 = new MInOutLine(receipt1);
|
||||||
|
receiptLine1.setOrderLine(line1, 0, new BigDecimal("2"));
|
||||||
|
receiptLine1.setQty(new BigDecimal("2"));
|
||||||
|
receiptLine1.saveEx();
|
||||||
|
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(receipt1, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
receipt1.load(trxName);
|
||||||
|
assertEquals(DocAction.STATUS_Completed, receipt1.getDocStatus(), "Material receipt not completed");
|
||||||
|
|
||||||
|
line1.load(trxName);
|
||||||
|
assertEquals(0, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value");
|
||||||
|
newQtyOrdered = getQtyOrdered(Env.getCtx(), PRODUCT_MULCH, getTrxName());
|
||||||
|
assertEquals(initialQtyOrdered.intValue(), newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||||
|
|
||||||
|
// reactivate the purchase order
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_ReActivate);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
order.load(trxName);
|
||||||
|
assertEquals(DocAction.STATUS_InProgress, order.getDocStatus(), "Order not reactivated");
|
||||||
|
|
||||||
|
// change the line quantity to 2
|
||||||
|
line1.load(trxName);
|
||||||
|
line1.setQty(new BigDecimal("2"));
|
||||||
|
line1.saveEx();
|
||||||
|
|
||||||
|
// complete the order again
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
order.load(trxName);
|
||||||
|
assertEquals(DocAction.STATUS_Completed, order.getDocStatus(), "Order not completed");
|
||||||
|
line1.load(trxName);
|
||||||
|
assertEquals(0, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value");
|
||||||
|
assertEquals(2, line1.getQtyOrdered().intValue(), "Wrong order line qty ordered value");
|
||||||
|
newQtyOrdered = getQtyOrdered(Env.getCtx(), PRODUCT_MULCH, getTrxName());
|
||||||
|
assertEquals(initialQtyOrdered.intValue(), newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||||
|
|
||||||
|
//reverse MR
|
||||||
|
receiptLine1.load(trxName);
|
||||||
|
assertEquals(2, receiptLine1.getMovementQty().intValue(), "Wrong receipt line movement qty value");
|
||||||
|
receipt1.load(trxName);
|
||||||
|
receipt1.getLines(true);
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(receipt1, DocAction.ACTION_Reverse_Accrual);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
receipt1.load(trxName);
|
||||||
|
assertEquals(DocAction.STATUS_Reversed, receipt1.getDocStatus(), "Material receipt not reversed");
|
||||||
|
line1.load(trxName);
|
||||||
|
assertEquals(2, line1.getQtyReserved().intValue(), "Wrong order line qty reserved value");
|
||||||
|
assertEquals(0, line1.getQtyDelivered().intValue(), "Wrong order line qty delivered value");
|
||||||
|
newQtyOrdered = getQtyOrdered(Env.getCtx(), PRODUCT_MULCH, getTrxName());
|
||||||
|
assertEquals(initialQtyOrdered.intValue()+2, newQtyOrdered.intValue(), "Quantiy Ordered not updated as expected");
|
||||||
|
} finally {
|
||||||
|
DB.executeUpdateEx("UPDATE AD_SysConfig SET Value='Y' WHERE AD_Client_ID=0 AND Name=?",
|
||||||
|
new Object[] {MSysConfig.VALIDATE_MATCHING_TO_ORDERED_QTY}, null);
|
||||||
|
CacheMgt.get().reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue