IDEMPIERE-545 improve logic of MMovementLineConfirm.ProcessLine() method. Fixed calculation of difference qty, Difference = Target - Confirmed Qty. Fixed callout movement getting wrong qty on hand for validation. Improve the robustness of the process - complete move and inventory document when user complete the move confirmation document.
This commit is contained in:
parent
87dba26de2
commit
19e875baf1
|
@ -122,9 +122,17 @@ public class CalloutMovement extends CalloutEngine
|
||||||
return;
|
return;
|
||||||
int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID");
|
int M_AttributeSetInstance_ID = Env.getContextAsInt(ctx, WindowNo, "M_AttributeSetInstance_ID");
|
||||||
BigDecimal available = Env.ZERO;
|
BigDecimal available = Env.ZERO;
|
||||||
MStorageOnHand oh = MStorageOnHand.get(ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, null);
|
if (M_AttributeSetInstance_ID > 0) {
|
||||||
if (oh != null)
|
MStorageOnHand oh = MStorageOnHand.get(ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, null);
|
||||||
available = oh.getQtyOnHand();
|
if (oh != null)
|
||||||
|
available = oh.getQtyOnHand();
|
||||||
|
} else {
|
||||||
|
MStorageOnHand[] ohs = MStorageOnHand.getAll(ctx, M_Product_ID, M_Locator_ID, null);
|
||||||
|
for (MStorageOnHand oh : ohs) {
|
||||||
|
available = available.add(oh.getQtyOnHand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (available == null)
|
if (available == null)
|
||||||
available = Env.ZERO;
|
available = Env.ZERO;
|
||||||
if (available.signum() == 0)
|
if (available.signum() == 0)
|
||||||
|
|
|
@ -21,14 +21,19 @@ import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.compiere.process.DocAction;
|
import org.compiere.process.DocAction;
|
||||||
import org.compiere.process.DocumentEngine;
|
import org.compiere.process.DocumentEngine;
|
||||||
|
import org.compiere.process.ProcessInfo;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.Msg;
|
import org.compiere.util.Msg;
|
||||||
|
import org.compiere.util.ValueNamePair;
|
||||||
|
import org.compiere.wf.MWorkflow;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,6 +135,7 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
private MInventory m_inventoryTo = null;
|
private MInventory m_inventoryTo = null;
|
||||||
/** Physical Inventory Info */
|
/** Physical Inventory Info */
|
||||||
private String m_inventoryInfo = null;
|
private String m_inventoryInfo = null;
|
||||||
|
private List<MInventory> m_inventoryDoc = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Lines
|
* Get Lines
|
||||||
|
@ -372,6 +378,7 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
approveIt();
|
approveIt();
|
||||||
if (log.isLoggable(Level.INFO)) log.info("completeIt - " + toString());
|
if (log.isLoggable(Level.INFO)) log.info("completeIt - " + toString());
|
||||||
//
|
//
|
||||||
|
m_inventoryDoc = new ArrayList<MInventory>();
|
||||||
MMovement move = new MMovement (getCtx(), getM_Movement_ID(), get_TrxName());
|
MMovement move = new MMovement (getCtx(), getM_Movement_ID(), get_TrxName());
|
||||||
MMovementLineConfirm[] lines = getLines(false);
|
MMovementLineConfirm[] lines = getLines(false);
|
||||||
for (int i = 0; i < lines.length; i++)
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
@ -400,24 +407,51 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
log.log(Level.SEVERE, "completeIt - Scrapped=" + confirm.getScrappedQty()
|
log.log(Level.SEVERE, "completeIt - Scrapped=" + confirm.getScrappedQty()
|
||||||
+ " - Difference=" + confirm.getDifferenceQty());
|
+ " - Difference=" + confirm.getDifferenceQty());
|
||||||
|
|
||||||
m_processMsg = "Differnce Doc not created";
|
if (m_processMsg == null)
|
||||||
|
m_processMsg = "Differnce Doc not created";
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // for all lines
|
} // for all lines
|
||||||
|
|
||||||
|
//complete movement
|
||||||
|
setProcessed(true);
|
||||||
|
saveEx();
|
||||||
|
ProcessInfo processInfo = MWorkflow.runDocumentActionWorkflow(move, DocAction.ACTION_Complete);
|
||||||
|
if (processInfo.isError())
|
||||||
|
{
|
||||||
|
m_processMsg = processInfo.getSummary();
|
||||||
|
setProcessed(false);
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_inventoryInfo != null)
|
if (m_inventoryInfo != null)
|
||||||
{
|
{
|
||||||
|
//complete inventory doc
|
||||||
|
for(MInventory inventory : m_inventoryDoc)
|
||||||
|
{
|
||||||
|
processInfo = MWorkflow.runDocumentActionWorkflow(inventory, DocAction.ACTION_Complete);
|
||||||
|
if (processInfo.isError())
|
||||||
|
{
|
||||||
|
m_processMsg = processInfo.getSummary();
|
||||||
|
setProcessed(false);
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_processMsg = " @M_Inventory_ID@: " + m_inventoryInfo;
|
m_processMsg = " @M_Inventory_ID@: " + m_inventoryInfo;
|
||||||
addDescription(Msg.translate(getCtx(), "M_Inventory_ID")
|
addDescription(Msg.translate(getCtx(), "M_Inventory_ID")
|
||||||
+ ": " + m_inventoryInfo);
|
+ ": " + m_inventoryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_inventoryDoc = null;
|
||||||
|
|
||||||
// User Validation
|
// User Validation
|
||||||
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
|
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
|
||||||
if (valid != null)
|
if (valid != null)
|
||||||
{
|
{
|
||||||
m_processMsg = valid;
|
m_processMsg = valid;
|
||||||
|
setProcessed(false);
|
||||||
return DocAction.STATUS_Invalid;
|
return DocAction.STATUS_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,9 +485,10 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
MWarehouse wh = MWarehouse.get(getCtx(), loc.getM_Warehouse_ID());
|
MWarehouse wh = MWarehouse.get(getCtx(), loc.getM_Warehouse_ID());
|
||||||
m_inventoryFrom = new MInventory (wh, get_TrxName());
|
m_inventoryFrom = new MInventory (wh, get_TrxName());
|
||||||
m_inventoryFrom.setDescription(Msg.translate(getCtx(), "M_MovementConfirm_ID") + " " + getDocumentNo());
|
m_inventoryFrom.setDescription(Msg.translate(getCtx(), "M_MovementConfirm_ID") + " " + getDocumentNo());
|
||||||
|
setInventoryDocType(m_inventoryFrom);
|
||||||
if (!m_inventoryFrom.save(get_TrxName()))
|
if (!m_inventoryFrom.save(get_TrxName()))
|
||||||
{
|
{
|
||||||
m_processMsg += "Inventory not created";
|
updateProcessMsg("Inventory not created");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// First Inventory
|
// First Inventory
|
||||||
|
@ -464,6 +499,7 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_inventoryInfo += "," + m_inventoryFrom.getDocumentNo();
|
m_inventoryInfo += "," + m_inventoryFrom.getDocumentNo();
|
||||||
|
m_inventoryDoc.add(m_inventoryFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.isLoggable(Level.INFO)) log.info("createDifferenceDoc - Difference=" + confirm.getDifferenceQty());
|
if (log.isLoggable(Level.INFO)) log.info("createDifferenceDoc - Difference=" + confirm.getDifferenceQty());
|
||||||
|
@ -473,7 +509,7 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
line.setDescription(Msg.translate(getCtx(), "DifferenceQty"));
|
line.setDescription(Msg.translate(getCtx(), "DifferenceQty"));
|
||||||
if (!line.save(get_TrxName()))
|
if (!line.save(get_TrxName()))
|
||||||
{
|
{
|
||||||
m_processMsg += "Inventory Line not created";
|
updateProcessMsg("Inventory Line not created");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
confirm.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
confirm.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
||||||
|
@ -493,9 +529,10 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
MWarehouse wh = MWarehouse.get(getCtx(), loc.getM_Warehouse_ID());
|
MWarehouse wh = MWarehouse.get(getCtx(), loc.getM_Warehouse_ID());
|
||||||
m_inventoryTo = new MInventory (wh, get_TrxName());
|
m_inventoryTo = new MInventory (wh, get_TrxName());
|
||||||
m_inventoryTo.setDescription(Msg.translate(getCtx(), "M_MovementConfirm_ID") + " " + getDocumentNo());
|
m_inventoryTo.setDescription(Msg.translate(getCtx(), "M_MovementConfirm_ID") + " " + getDocumentNo());
|
||||||
|
setInventoryDocType(m_inventoryTo);
|
||||||
if (!m_inventoryTo.save(get_TrxName()))
|
if (!m_inventoryTo.save(get_TrxName()))
|
||||||
{
|
{
|
||||||
m_processMsg += "Inventory not created";
|
updateProcessMsg("Inventory not created");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// First Inventory
|
// First Inventory
|
||||||
|
@ -506,6 +543,7 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_inventoryInfo += "," + m_inventoryTo.getDocumentNo();
|
m_inventoryInfo += "," + m_inventoryTo.getDocumentNo();
|
||||||
|
m_inventoryDoc.add(m_inventoryTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.isLoggable(Level.INFO)) log.info("createDifferenceDoc - Scrapped=" + confirm.getScrappedQty());
|
if (log.isLoggable(Level.INFO)) log.info("createDifferenceDoc - Scrapped=" + confirm.getScrappedQty());
|
||||||
|
@ -515,7 +553,7 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
line.setDescription(Msg.translate(getCtx(), "ScrappedQty"));
|
line.setDescription(Msg.translate(getCtx(), "ScrappedQty"));
|
||||||
if (!line.save(get_TrxName()))
|
if (!line.save(get_TrxName()))
|
||||||
{
|
{
|
||||||
m_processMsg += "Inventory Line not created";
|
updateProcessMsg("Inventory Line not created");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
confirm.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
confirm.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
||||||
|
@ -524,6 +562,36 @@ public class MMovementConfirm extends X_M_MovementConfirm implements DocAction
|
||||||
return true;
|
return true;
|
||||||
} // createDifferenceDoc
|
} // createDifferenceDoc
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void updateProcessMsg(String msg) {
|
||||||
|
if (m_processMsg != null)
|
||||||
|
m_processMsg = m_processMsg + " " + msg;
|
||||||
|
else
|
||||||
|
m_processMsg = msg;
|
||||||
|
ValueNamePair error = CLogger.retrieveError();
|
||||||
|
if (error != null)
|
||||||
|
m_processMsg = m_processMsg + ": " + Msg.getMsg(Env.getCtx(), error.getValue()) + " " + error.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param inventory
|
||||||
|
*/
|
||||||
|
private void setInventoryDocType(MInventory inventory) {
|
||||||
|
MDocType[] doctypes = MDocType.getOfDocBaseType(Env.getCtx(), X_C_DocType.DOCBASETYPE_MaterialPhysicalInventory);
|
||||||
|
for(MDocType doctype : doctypes)
|
||||||
|
{
|
||||||
|
if (X_C_DocType.DOCSUBTYPEINV_PhysicalInventory.equals(doctype.getDocSubTypeInv()))
|
||||||
|
{
|
||||||
|
inventory.setC_DocType_ID(doctype.getC_DocType_ID());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Void Document.
|
* Void Document.
|
||||||
* @return false
|
* @return false
|
||||||
|
|
|
@ -148,10 +148,9 @@ public class MMovementLineConfirm extends X_M_MovementLineConfirm
|
||||||
*/
|
*/
|
||||||
protected boolean beforeSave (boolean newRecord)
|
protected boolean beforeSave (boolean newRecord)
|
||||||
{
|
{
|
||||||
// Calculate Difference = Target - Confirmed - Scrapped
|
// Calculate Difference = Target - Confirmed
|
||||||
BigDecimal difference = getTargetQty();
|
BigDecimal difference = getTargetQty();
|
||||||
difference = difference.subtract(getConfirmedQty());
|
difference = difference.subtract(getConfirmedQty());
|
||||||
difference = difference.subtract(getScrappedQty());
|
|
||||||
setDifferenceQty(difference);
|
setDifferenceQty(difference);
|
||||||
//
|
//
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue