Revert revision 8248 because it was a bad merge.
Manual merge is needed.
This commit is contained in:
parent
3fc69673b4
commit
d1c1d8996a
|
@ -1654,6 +1654,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
|
||||
|
||||
boolean needSave = false;
|
||||
BigDecimal qtyASI = Env.ZERO ;
|
||||
|
||||
MProduct product = line.getProduct();
|
||||
|
||||
|
@ -1693,12 +1694,65 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
else if(getMovementType().compareTo(MInOut.MOVEMENTTYPE_VendorReturns) == 0 || getMovementType().compareTo(MInOut.MOVEMENTTYPE_CustomerShipment) == 0)
|
||||
{
|
||||
String MMPolicy = product.getMMPolicy();
|
||||
Timestamp minGuaranteeDate = getMovementDate();
|
||||
MStorage[] storages = MStorage.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName());
|
||||
MStorage[] storages = MStorage.getAllWithASI(getCtx(),
|
||||
line.getM_Product_ID(), line.getM_Locator_ID(),
|
||||
MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName());
|
||||
BigDecimal qtyToDeliver = line.getMovementQty();
|
||||
/*for (int ii = 0; ii < storages.length; ii++)
|
||||
{
|
||||
MStorage storage = storages[ii];
|
||||
if (ii == 0)
|
||||
{
|
||||
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||
{
|
||||
line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID());
|
||||
needSave = true;
|
||||
log.config("Direct - " + line);
|
||||
qtyToDeliver = Env.ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.config("Split - " + line);
|
||||
MInOutLineMA ma = new MInOutLineMA (line,
|
||||
storage.getM_AttributeSetInstance_ID(),
|
||||
storage.getQtyOnHand());
|
||||
if (!ma.save())
|
||||
;
|
||||
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||
}
|
||||
}
|
||||
else // create addl material allocation
|
||||
{
|
||||
MInOutLineMA ma = new MInOutLineMA (line,
|
||||
storage.getM_AttributeSetInstance_ID(),
|
||||
qtyToDeliver);
|
||||
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||
qtyToDeliver = Env.ZERO;
|
||||
else
|
||||
{
|
||||
ma.setMovementQty(storage.getQtyOnHand());
|
||||
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||
}
|
||||
if (!ma.save())
|
||||
;
|
||||
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||
}
|
||||
if (qtyToDeliver.signum() == 0)
|
||||
break;
|
||||
} // for all storages
|
||||
*/
|
||||
|
||||
for (MStorage storage: storages)
|
||||
{
|
||||
//consume ASI Zero
|
||||
if (storage.getM_AttributeSetInstance_ID() == 0)
|
||||
{
|
||||
qtyASI = qtyASI.add(storage.getQtyOnHand());
|
||||
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||
{
|
||||
MInOutLineMA ma = new MInOutLineMA (line,
|
||||
|
@ -1725,11 +1779,11 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
}
|
||||
|
||||
// No AttributeSetInstance found for remainder
|
||||
if (qtyToDeliver.signum() != 0)
|
||||
if (qtyToDeliver.signum() != 0 || qtyASI.signum() != 0)
|
||||
{
|
||||
MInOutLineMA ma = new MInOutLineMA (line, 0, qtyToDeliver);
|
||||
MInOutLineMA ma = new MInOutLineMA (line, 0, qtyToDeliver.add(qtyASI));
|
||||
if (!ma.save())
|
||||
throw new IllegalStateException("Error try create ASI Reservation");
|
||||
;
|
||||
log.fine("##: " + ma);
|
||||
}
|
||||
} // outgoing Trx
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.logging.Level;
|
|||
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
import org.compiere.report.MReportTree;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
|
@ -37,8 +38,10 @@ import org.compiere.util.Msg;
|
|||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: MInventory.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $
|
||||
* @author victor.perez@e-evolution.com, e-Evolution
|
||||
* @author victor.perez@e-evolution.com, e-Evolution http://www.e-evolution.com
|
||||
* <li>FR [ 1948157 ] Is necessary the reference for document reverse
|
||||
* <li> FR [ 2520591 ] Support multiples calendar for Org
|
||||
* @see http://sourceforge.net/tracker2/?func=detail&atid=879335&aid=2520591&group_id=176962
|
||||
* @author Armen Rizal, Goodwill Consulting
|
||||
* <li>BF [ 1745154 ] Cost in Reversing Material Related Docs
|
||||
* @see http://sourceforge.net/tracker/?func=detail&atid=879335&aid=1948157&group_id=176962
|
||||
|
@ -326,7 +329,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
return DocAction.STATUS_Invalid;
|
||||
|
||||
// Std Period open?
|
||||
if (!MPeriod.isOpen(getCtx(), getMovementDate(), MDocType.DOCBASETYPE_MaterialPhysicalInventory))
|
||||
if (!MPeriod.isOpen(getCtx(), getMovementDate(), MDocType.DOCBASETYPE_MaterialPhysicalInventory, getAD_Org_ID()))
|
||||
{
|
||||
m_processMsg = "@PeriodClosed@";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -467,13 +470,21 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
mtrx = new MTransaction (getCtx(), line.getAD_Org_ID(), m_MovementType,
|
||||
line.getM_Locator_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
|
||||
QtyMA.negate(), getMovementDate(), get_TrxName());
|
||||
|
||||
mtrx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
||||
if (!mtrx.save())
|
||||
{
|
||||
m_processMsg = "Transaction not inserted(2)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
if(QtyMA.signum() != 0)
|
||||
{
|
||||
String err = createCostDetail(line, ma.getM_AttributeSetInstance_ID() , QtyMA.negate());
|
||||
if(err != null && err.length() > 0) return err;
|
||||
}
|
||||
|
||||
qtyDiff = QtyNew;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,10 +532,15 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
m_processMsg = "Transaction not inserted(2)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
}
|
||||
|
||||
if(qtyDiff.signum() != 0)
|
||||
{
|
||||
String err = createCostDetail(line, line.getM_AttributeSetInstance_ID(), qtyDiff);
|
||||
if(err != null && err.length() > 0) return err;
|
||||
}
|
||||
} // Fallback
|
||||
} // stock movement
|
||||
|
||||
|
||||
} // for all lines
|
||||
|
||||
// User Validation
|
||||
|
@ -573,6 +589,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
|
||||
// Check Line
|
||||
boolean needSave = false;
|
||||
BigDecimal qtyASI = Env.ZERO ;
|
||||
// Attribute Set Instance
|
||||
if (line.getM_AttributeSetInstance_ID() == 0)
|
||||
{
|
||||
|
@ -595,12 +612,21 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
else // Outgoing Trx
|
||||
{
|
||||
String MMPolicy = product.getMMPolicy();
|
||||
MStorage[] storages = MStorage.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), 0,
|
||||
null, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName());
|
||||
MStorage[] storages = MStorage.getAllWithASI(getCtx(),
|
||||
line.getM_Product_ID(), line.getM_Locator_ID(),
|
||||
MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName());
|
||||
BigDecimal qtyToDeliver = qtyDiff.negate();
|
||||
|
||||
for (MStorage storage: storages)
|
||||
{
|
||||
//cosume ASI Zero
|
||||
if (storage.getM_AttributeSetInstance_ID() == 0)
|
||||
{
|
||||
qtyASI = qtyASI.add(storage.getQtyOnHand());
|
||||
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||
{
|
||||
MInventoryLineMA ma = new MInventoryLineMA (line,
|
||||
|
@ -629,12 +655,12 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
}
|
||||
|
||||
// No AttributeSetInstance found for remainder
|
||||
if (qtyToDeliver.signum() != 0)
|
||||
if (qtyToDeliver.signum() != 0 || qtyASI.signum() != 0)
|
||||
{
|
||||
MInventoryLineMA ma = new MInventoryLineMA (line, 0 , qtyToDeliver);
|
||||
MInventoryLineMA ma = new MInventoryLineMA (line, 0 , qtyToDeliver.add(qtyASI));
|
||||
|
||||
if (!ma.save())
|
||||
throw new IllegalStateException("Error try create ASI Reservation");
|
||||
;
|
||||
log.fine("##: " + ma);
|
||||
}
|
||||
} // outgoing Trx
|
||||
|
@ -736,7 +762,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
return false;
|
||||
|
||||
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||
if (!MPeriod.isOpen(getCtx(), getMovementDate(), dt.getDocBaseType()))
|
||||
if (!MPeriod.isOpen(getCtx(), getMovementDate(), dt.getDocBaseType(), getAD_Org_ID()))
|
||||
{
|
||||
m_processMsg = "@PeriodClosed@";
|
||||
return false;
|
||||
|
@ -751,6 +777,8 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
reversal.setPosted(false);
|
||||
reversal.setProcessed(false);
|
||||
reversal.addDescription("{->" + getDocumentNo() + ")");
|
||||
//FR1948157
|
||||
reversal.setReversal_ID(getM_Inventory_ID());
|
||||
if (!reversal.save())
|
||||
{
|
||||
m_processMsg = "Could not create Inventory Reversal";
|
||||
|
@ -767,6 +795,10 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
copyValues(oLine, rLine, oLine.getAD_Client_ID(), oLine.getAD_Org_ID());
|
||||
rLine.setM_Inventory_ID(reversal.getM_Inventory_ID());
|
||||
rLine.setParent(reversal);
|
||||
//AZ Goodwill
|
||||
// store original (voided/reversed) document line
|
||||
rLine.setReversalLine_ID(oLine.getM_InventoryLine_ID());
|
||||
//
|
||||
rLine.setQtyBook (oLine.getQtyCount()); // switch
|
||||
rLine.setQtyCount (oLine.getQtyBook());
|
||||
rLine.setQtyInternalUse (oLine.getQtyInternalUse().negate());
|
||||
|
@ -788,7 +820,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
mas[j].getM_AttributeSetInstance_ID(),
|
||||
mas[j].getMovementQty().negate());
|
||||
if (!ma.save())
|
||||
throw new IllegalStateException("Error try create ASI Reservation");
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -811,6 +843,8 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
if (m_processMsg != null)
|
||||
return false;
|
||||
setProcessed(true);
|
||||
//FR1948157
|
||||
setReversal_ID(reversal.getM_Inventory_ID());
|
||||
setDocStatus(DOCSTATUS_Reversed); // may come from void
|
||||
setDocAction(DOCACTION_None);
|
||||
|
||||
|
@ -925,5 +959,54 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
return m_reversal;
|
||||
} // isReversal
|
||||
|
||||
} // MInventory
|
||||
/**
|
||||
* Create Cost Detail
|
||||
* @param line
|
||||
* @param Qty
|
||||
* @return
|
||||
*/
|
||||
private String createCostDetail(MInventoryLine line,int M_AttributeSetInstance_ID, BigDecimal qty)
|
||||
{
|
||||
// Get Account Schemas to create MCostDetail
|
||||
MAcctSchema[] acctschemas = MAcctSchema.getClientAcctSchema(getCtx(), getAD_Client_ID());
|
||||
for(int asn = 0; asn < acctschemas.length; asn++)
|
||||
{
|
||||
MAcctSchema as = acctschemas[asn];
|
||||
|
||||
boolean skip = false;
|
||||
if (as.getAD_OrgOnly_ID() != 0)
|
||||
{
|
||||
if (as.getOnlyOrgs() == null)
|
||||
as.setOnlyOrgs(MReportTree.getChildIDs(getCtx(),
|
||||
0, MAcctSchemaElement.ELEMENTTYPE_Organization,
|
||||
as.getAD_OrgOnly_ID()));
|
||||
|
||||
// Header Level Org
|
||||
skip = as.isSkipOrg(getAD_Org_ID());
|
||||
// Line Level Org
|
||||
skip = as.isSkipOrg(line.getAD_Org_ID());
|
||||
}
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
ProductCost pc = new ProductCost (Env.getCtx(),
|
||||
line.getM_Product_ID(), M_AttributeSetInstance_ID, line.get_TrxName());
|
||||
pc.setQty(qty);
|
||||
BigDecimal costs = pc.getProductCosts(as, line.getAD_Org_ID(), as.getCostingMethod(),
|
||||
0,false);
|
||||
if (costs == null || costs.signum() == 0)
|
||||
{
|
||||
return "No Costs for " + line.getProduct().getName();
|
||||
}
|
||||
|
||||
// Set Total Amount and Total Quantity from Inventory
|
||||
MCostDetail.createInventory(as, line.getAD_Org_ID(),
|
||||
line.getM_Product_ID(), M_AttributeSetInstance_ID,
|
||||
line.getM_InventoryLine_ID(), 0, // no cost element
|
||||
costs.multiply(qty), qty,
|
||||
line.getDescription(), line.get_TrxName());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
} // MInventory
|
||||
|
|
|
@ -658,19 +658,81 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
//{
|
||||
// MMovementLine line = lines[i];
|
||||
boolean needSave = false;
|
||||
BigDecimal qtyASI = Env.ZERO ;
|
||||
|
||||
// Attribute Set Instance
|
||||
if (line.getM_AttributeSetInstance_ID() == 0)
|
||||
{
|
||||
MProduct product = MProduct.get(getCtx(), line.getM_Product_ID());
|
||||
String MMPolicy = product.getMMPolicy();
|
||||
MStorage[] storages = MStorage.getWarehouse(getCtx(), 0, line.getM_Product_ID(), 0,
|
||||
null, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName());
|
||||
|
||||
MStorage[] storages = MStorage.getAllWithASI(getCtx(),
|
||||
line.getM_Product_ID(), line.getM_Locator_ID(),
|
||||
MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName());
|
||||
BigDecimal qtyToDeliver = line.getMovementQty();
|
||||
|
||||
/*for (int ii = 0; ii < storages.length; ii++)
|
||||
{
|
||||
MStorage storage = storages[ii];
|
||||
if (ii == 0)
|
||||
{
|
||||
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||
{
|
||||
line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID());
|
||||
needSave = true;
|
||||
log.config("Direct - " + line);
|
||||
qtyToDeliver = Env.ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.config("Split - " + line);
|
||||
MMovementLineMA ma = new MMovementLineMA (line,
|
||||
storage.getM_AttributeSetInstance_ID(),
|
||||
storage.getQtyOnHand());
|
||||
if (!ma.save())
|
||||
;
|
||||
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||
}
|
||||
}
|
||||
else // create addl material allocation
|
||||
{
|
||||
MMovementLineMA ma = new MMovementLineMA (line,
|
||||
storage.getM_AttributeSetInstance_ID(),
|
||||
qtyToDeliver);
|
||||
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||
qtyToDeliver = Env.ZERO;
|
||||
else
|
||||
{
|
||||
ma.setMovementQty(storage.getQtyOnHand());
|
||||
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||
}
|
||||
if (!ma.save())
|
||||
;
|
||||
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||
}
|
||||
if (qtyToDeliver.signum() == 0)
|
||||
break;
|
||||
} // for all storages
|
||||
|
||||
// No AttributeSetInstance found for remainder
|
||||
if (qtyToDeliver.signum() != 0)
|
||||
{
|
||||
MMovementLineMA ma = new MMovementLineMA (line,
|
||||
0, qtyToDeliver);
|
||||
if (!ma.save())
|
||||
;
|
||||
log.fine("##: " + ma);
|
||||
}*/
|
||||
for (MStorage storage: storages)
|
||||
{
|
||||
//consume ASI Zero
|
||||
if (storage.getM_AttributeSetInstance_ID() == 0)
|
||||
{
|
||||
qtyASI = qtyASI.add(storage.getQtyOnHand());
|
||||
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||
{
|
||||
MMovementLineMA ma = new MMovementLineMA (line,
|
||||
|
@ -699,12 +761,12 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
}
|
||||
|
||||
// No AttributeSetInstance found for remainder
|
||||
if (qtyToDeliver.signum() != 0)
|
||||
if (qtyToDeliver.signum() != 0 || qtyASI.signum() != 0)
|
||||
{
|
||||
MMovementLineMA ma = new MMovementLineMA (line, 0 , qtyToDeliver);
|
||||
MMovementLineMA ma = new MMovementLineMA (line, 0 , qtyToDeliver.add(qtyASI));
|
||||
|
||||
if (!ma.save())
|
||||
throw new IllegalStateException("Error try create ASI Reservation");
|
||||
;
|
||||
log.fine("##: " + ma);
|
||||
}
|
||||
} // attributeSetInstance
|
||||
|
|
|
@ -78,6 +78,7 @@ public class MStorage extends X_M_Storage
|
|||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
pstmt = null;
|
||||
if (retValue == null)
|
||||
s_log.fine("Not Found - M_Locator_ID=" + M_Locator_ID
|
||||
+ ", M_Product_ID=" + M_Product_ID + ", M_AttributeSetInstance_ID=" + M_AttributeSetInstance_ID);
|
||||
|
@ -88,7 +89,7 @@ public class MStorage extends X_M_Storage
|
|||
} // get
|
||||
|
||||
/**
|
||||
* Get all Storages for Product with ASI and QtyOnHand <> 0
|
||||
* Get all Storages for Product with ASI and QtyOnHand > 0
|
||||
* @param ctx context
|
||||
* @param M_Product_ID product
|
||||
* @param M_Locator_ID locator
|
||||
|
@ -102,9 +103,13 @@ public class MStorage extends X_M_Storage
|
|||
ArrayList<MStorage> list = new ArrayList<MStorage>();
|
||||
String sql = "SELECT * FROM M_Storage "
|
||||
+ "WHERE M_Product_ID=? AND M_Locator_ID=?"
|
||||
+ " AND M_AttributeSetInstance_ID > 0 "
|
||||
// Remove for management rightly FIFO/LIFO now you can consume a layer with ASI ID = zero and Qty onhand in negative
|
||||
// + " AND M_AttributeSetInstance_ID > 0"
|
||||
// + " AND QtyOnHand > 0 "
|
||||
+ " AND QtyOnHand <> 0 "
|
||||
+ "ORDER BY M_AttributeSetInstance_ID";
|
||||
if (!FiFo)
|
||||
sql += " DESC";
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
|
@ -125,13 +130,14 @@ public class MStorage extends X_M_Storage
|
|||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
pstmt = null;
|
||||
MStorage[] retValue = new MStorage[list.size()];
|
||||
list.toArray(retValue);
|
||||
return retValue;
|
||||
} // getAllWithASI
|
||||
|
||||
/**
|
||||
* Get all Storages for Product where QtyOnHand <> 0
|
||||
* Get all Storages for Product
|
||||
* @param ctx context
|
||||
* @param M_Product_ID product
|
||||
* @param M_Locator_ID locator
|
||||
|
@ -166,6 +172,7 @@ public class MStorage extends X_M_Storage
|
|||
DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
pstmt = null;
|
||||
MStorage[] retValue = new MStorage[list.size()];
|
||||
list.toArray(retValue);
|
||||
return retValue;
|
||||
|
@ -220,41 +227,23 @@ public class MStorage extends X_M_Storage
|
|||
* @param FiFo first in-first-out
|
||||
* @param trxName transaction
|
||||
* @return existing - ordered by location priority (desc) and/or guarantee date
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public static MStorage[] getWarehouse (Properties ctx, int M_Warehouse_ID,
|
||||
int M_Product_ID, int M_AttributeSetInstance_ID, int M_AttributeSet_ID,
|
||||
boolean allAttributeInstances, Timestamp minGuaranteeDate,
|
||||
boolean FiFo, String trxName)
|
||||
{
|
||||
return getWarehouse(ctx, M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID,
|
||||
minGuaranteeDate, FiFo, false, 0, trxName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Storage Info for Warehouse or locator
|
||||
* @param ctx context
|
||||
* @param M_Warehouse_ID ignore if M_Locator_ID > 0
|
||||
* @param M_Product_ID product
|
||||
* @param M_AttributeSetInstance_ID instance id, 0 to retrieve all instance
|
||||
* @param minGuaranteeDate optional minimum guarantee date if all attribute instances
|
||||
* @param FiFo first in-first-out
|
||||
* @param positiveOnly if true, only return storage records with qtyOnHand > 0
|
||||
* @param M_Locator_ID optional locator id
|
||||
* @param trxName transaction
|
||||
* @return existing - ordered by location priority (desc) and/or guarantee date
|
||||
*/
|
||||
public static MStorage[] getWarehouse (Properties ctx, int M_Warehouse_ID,
|
||||
int M_Product_ID, int M_AttributeSetInstance_ID, Timestamp minGuaranteeDate,
|
||||
boolean FiFo, boolean positiveOnly, int M_Locator_ID, String trxName)
|
||||
{
|
||||
if ((M_Warehouse_ID == 0 && M_Locator_ID == 0) || M_Product_ID == 0)
|
||||
if (M_Warehouse_ID == 0 || M_Product_ID == 0)
|
||||
return new MStorage[0];
|
||||
|
||||
boolean allAttributeInstances = false;
|
||||
if (M_AttributeSetInstance_ID == 0)
|
||||
if (M_AttributeSet_ID == 0)
|
||||
allAttributeInstances = true;
|
||||
else
|
||||
{
|
||||
MAttributeSet mas = MAttributeSet.get(ctx, M_AttributeSet_ID);
|
||||
if (!mas.isInstanceAttribute())
|
||||
allAttributeInstances = true;
|
||||
}
|
||||
|
||||
ArrayList<MStorage> list = new ArrayList<MStorage>();
|
||||
// Specific Attribute Set Instance
|
||||
|
@ -262,18 +251,11 @@ public class MStorage extends X_M_Storage
|
|||
+ "s.AD_Client_ID,s.AD_Org_ID,s.IsActive,s.Created,s.CreatedBy,s.Updated,s.UpdatedBy,"
|
||||
+ "s.QtyOnHand,s.QtyReserved,s.QtyOrdered,s.DateLastInventory "
|
||||
+ "FROM M_Storage s"
|
||||
+ " INNER JOIN M_Locator l ON (l.M_Locator_ID=s.M_Locator_ID) ";
|
||||
if (M_Locator_ID > 0)
|
||||
sql += "WHERE l.M_Locator_ID = ?";
|
||||
else
|
||||
sql += "WHERE l.M_Warehouse_ID=?";
|
||||
sql += " AND s.M_Product_ID=?"
|
||||
+ " AND COALESCE(s.M_AttributeSetInstance_ID,0)=? ";
|
||||
if (positiveOnly)
|
||||
{
|
||||
sql += " AND s.QtyOnHand > 0 ";
|
||||
}
|
||||
sql += "ORDER BY l.PriorityNo DESC, M_AttributeSetInstance_ID";
|
||||
+ " INNER JOIN M_Locator l ON (l.M_Locator_ID=s.M_Locator_ID) "
|
||||
+ "WHERE l.M_Warehouse_ID=?"
|
||||
+ " AND s.M_Product_ID=?"
|
||||
+ " AND COALESCE(s.M_AttributeSetInstance_ID,0)=? "
|
||||
+ "ORDER BY l.PriorityNo DESC, M_AttributeSetInstance_ID";
|
||||
if (!FiFo)
|
||||
sql += " DESC";
|
||||
// All Attribute Set Instances
|
||||
|
@ -284,31 +266,19 @@ public class MStorage extends X_M_Storage
|
|||
+ "s.QtyOnHand,s.QtyReserved,s.QtyOrdered,s.DateLastInventory "
|
||||
+ "FROM M_Storage s"
|
||||
+ " INNER JOIN M_Locator l ON (l.M_Locator_ID=s.M_Locator_ID)"
|
||||
+ " LEFT OUTER JOIN M_AttributeSetInstance asi ON (s.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID) ";
|
||||
if (M_Locator_ID > 0)
|
||||
sql += "WHERE l.M_Locator_ID = ?";
|
||||
else
|
||||
sql += "WHERE l.M_Warehouse_ID=?";
|
||||
sql += " AND s.M_Product_ID=? ";
|
||||
+ " LEFT OUTER JOIN M_AttributeSetInstance asi ON (s.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID) "
|
||||
+ "WHERE l.M_Warehouse_ID=?"
|
||||
+ " AND s.M_Product_ID=? ";
|
||||
if (minGuaranteeDate != null)
|
||||
{
|
||||
sql += "AND (asi.GuaranteeDate IS NULL OR asi.GuaranteeDate>?) ";
|
||||
if (positiveOnly)
|
||||
{
|
||||
sql += " AND s.QtyOnHand > 0 ";
|
||||
}
|
||||
sql += "ORDER BY l.PriorityNo DESC, " +
|
||||
"asi.GuaranteeDate, M_AttributeSetInstance_ID";
|
||||
sql += "AND (asi.GuaranteeDate IS NULL OR asi.GuaranteeDate>?) "
|
||||
+ "ORDER BY asi.GuaranteeDate, M_AttributeSetInstance_ID";
|
||||
if (!FiFo)
|
||||
sql += " DESC";
|
||||
sql += ", s.QtyOnHand DESC";
|
||||
sql += ", l.PriorityNo DESC, s.QtyOnHand DESC";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (positiveOnly)
|
||||
{
|
||||
sql += " AND s.QtyOnHand > 0 ";
|
||||
}
|
||||
sql += "ORDER BY l.PriorityNo DESC, l.M_Locator_ID, s.M_AttributeSetInstance_ID";
|
||||
if (!FiFo)
|
||||
sql += " DESC";
|
||||
|
@ -320,16 +290,12 @@ public class MStorage extends X_M_Storage
|
|||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement(sql, trxName);
|
||||
pstmt.setInt(1, M_Locator_ID > 0 ? M_Locator_ID : M_Warehouse_ID);
|
||||
pstmt.setInt(1, M_Warehouse_ID);
|
||||
pstmt.setInt(2, M_Product_ID);
|
||||
if (!allAttributeInstances)
|
||||
{
|
||||
pstmt.setInt(3, M_AttributeSetInstance_ID);
|
||||
}
|
||||
else if (minGuaranteeDate != null)
|
||||
{
|
||||
pstmt.setTimestamp(3, minGuaranteeDate);
|
||||
}
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next())
|
||||
list.add (new MStorage (ctx, rs, trxName));
|
||||
|
|
|
@ -16,13 +16,25 @@
|
|||
*****************************************************************************/
|
||||
package org.compiere.process;
|
||||
|
||||
import java.math.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.model.*;
|
||||
import org.compiere.util.*;
|
||||
import org.compiere.model.MAttributeSet;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MStorage;
|
||||
import org.compiere.util.AdempiereUserError;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
|
||||
/**
|
||||
* Generate Shipments.
|
||||
|
@ -196,6 +208,7 @@ public class InOutGenerate extends SvrProcess
|
|||
*/
|
||||
private String generate (PreparedStatement pstmt)
|
||||
{
|
||||
MClient client = MClient.get(getCtx());
|
||||
try
|
||||
{
|
||||
ResultSet rs = pstmt.executeQuery ();
|
||||
|
@ -229,7 +242,7 @@ public class InOutGenerate extends SvrProcess
|
|||
+ " INNER JOIN M_InOut io ON (iol.M_InOut_ID=io.M_InOut_ID) "
|
||||
+ "WHERE iol.C_OrderLine_ID=C_OrderLine.C_OrderLine_ID AND io.DocStatus IN ('IP','WC'))";
|
||||
// Deadlock Prevention - Order by M_Product_ID
|
||||
MOrderLine[] lines = order.getLines (where, "ORDER BY C_BPartner_Location_ID, M_Product_ID");
|
||||
MOrderLine[] lines = order.getLines (where, "C_BPartner_Location_ID, M_Product_ID");
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
MOrderLine line = lines[i];
|
||||
|
@ -285,7 +298,9 @@ public class InOutGenerate extends SvrProcess
|
|||
String MMPolicy = product.getMMPolicy();
|
||||
MStorage[] storages = getStorages(line.getM_Warehouse_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy));
|
||||
product.getM_AttributeSet_ID(),
|
||||
line.getM_AttributeSetInstance_ID()==0, minGuaranteeDate,
|
||||
MClient.MMPOLICY_FiFo.equals(MMPolicy));
|
||||
|
||||
for (int j = 0; j < storages.length; j++)
|
||||
{
|
||||
|
@ -367,7 +382,9 @@ public class InOutGenerate extends SvrProcess
|
|||
String MMPolicy = product.getMMPolicy();
|
||||
storages = getStorages(line.getM_Warehouse_ID(),
|
||||
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy));
|
||||
product.getM_AttributeSet_ID(),
|
||||
line.getM_AttributeSetInstance_ID()==0, minGuaranteeDate,
|
||||
MClient.MMPOLICY_FiFo.equals(MMPolicy));
|
||||
}
|
||||
//
|
||||
createLine (order, line, toDeliver, storages, false);
|
||||
|
@ -443,13 +460,21 @@ public class InOutGenerate extends SvrProcess
|
|||
return;
|
||||
}
|
||||
|
||||
// Product
|
||||
MProduct product = orderLine.getProduct();
|
||||
boolean linePerASI = false;
|
||||
if (product.getM_AttributeSet_ID() != 0)
|
||||
{
|
||||
MAttributeSet mas = MAttributeSet.get(getCtx(), product.getM_AttributeSet_ID());
|
||||
linePerASI = mas.isInstanceAttribute();
|
||||
}
|
||||
|
||||
// Inventory Lines
|
||||
ArrayList<MInOutLine> list = new ArrayList<MInOutLine>();
|
||||
BigDecimal toDeliver = qty;
|
||||
for (int i = 0; i < storages.length; i++)
|
||||
{
|
||||
MStorage storage = storages[i];
|
||||
|
||||
BigDecimal deliver = toDeliver;
|
||||
// Not enough On Hand
|
||||
if (deliver.compareTo(storage.getQtyOnHand()) > 0
|
||||
|
@ -464,12 +489,12 @@ public class InOutGenerate extends SvrProcess
|
|||
int M_Locator_ID = storage.getM_Locator_ID();
|
||||
//
|
||||
MInOutLine line = null;
|
||||
if (orderLine.getM_AttributeSetInstance_ID() == 0) // find line with Locator
|
||||
if (!linePerASI) // find line with Locator
|
||||
{
|
||||
for (int ll = 0; ll < list.size(); ll++)
|
||||
{
|
||||
MInOutLine test = (MInOutLine)list.get(ll);
|
||||
if (test.getM_Locator_ID() == M_Locator_ID && test.getM_AttributeSetInstance_ID() == 0)
|
||||
if (test.getM_Locator_ID() == M_Locator_ID)
|
||||
{
|
||||
line = test;
|
||||
break;
|
||||
|
@ -489,33 +514,20 @@ public class InOutGenerate extends SvrProcess
|
|||
line.setQtyEntered(line.getMovementQty().multiply(orderLine.getQtyEntered())
|
||||
.divide(orderLine.getQtyOrdered(), 12, BigDecimal.ROUND_HALF_UP));
|
||||
line.setLine(m_line + orderLine.getLine());
|
||||
|
||||
if (linePerASI)
|
||||
line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID());
|
||||
if (!line.save())
|
||||
throw new IllegalStateException("Could not create Shipment Line");
|
||||
log.fine("ToDeliver=" + qty + "/" + deliver + " - " + line);
|
||||
toDeliver = toDeliver.subtract(deliver);
|
||||
// Temp adjustment, actual update happen in MInOut.completeIt
|
||||
// Temp adjustment
|
||||
storage.setQtyOnHand(storage.getQtyOnHand().subtract(deliver));
|
||||
//
|
||||
if (toDeliver.signum() == 0)
|
||||
break;
|
||||
}
|
||||
if (toDeliver.signum() != 0 )
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
if (toDeliver.signum() != 0)
|
||||
throw new IllegalStateException("Not All Delivered - Remainder=" + toDeliver);
|
||||
}
|
||||
else
|
||||
{
|
||||
MInOutLine line = new MInOutLine (m_shipment);
|
||||
line.setOrderLine(orderLine, 0, order.isSOTrx() ? toDeliver : Env.ZERO);
|
||||
line.setQty(toDeliver);
|
||||
if (!line.save())
|
||||
throw new IllegalStateException("Could not create Shipment Line");
|
||||
|
||||
}
|
||||
}
|
||||
} // createLine
|
||||
|
||||
|
||||
|
@ -524,17 +536,20 @@ public class InOutGenerate extends SvrProcess
|
|||
* @param M_Warehouse_ID
|
||||
* @param M_Product_ID
|
||||
* @param M_AttributeSetInstance_ID
|
||||
* @param M_AttributeSet_ID
|
||||
* @param allAttributeInstances
|
||||
* @param minGuaranteeDate
|
||||
* @param FiFo
|
||||
* @return storages
|
||||
*/
|
||||
private MStorage[] getStorages(int M_Warehouse_ID,
|
||||
int M_Product_ID, int M_AttributeSetInstance_ID,
|
||||
Timestamp minGuaranteeDate, boolean FiFo)
|
||||
int M_Product_ID, int M_AttributeSetInstance_ID, int M_AttributeSet_ID,
|
||||
boolean allAttributeInstances, Timestamp minGuaranteeDate,
|
||||
boolean FiFo)
|
||||
{
|
||||
m_lastPP = new SParameter(M_Warehouse_ID,
|
||||
M_Product_ID, M_AttributeSetInstance_ID,
|
||||
minGuaranteeDate, FiFo);
|
||||
M_Product_ID, M_AttributeSetInstance_ID, M_AttributeSet_ID,
|
||||
allAttributeInstances, minGuaranteeDate, FiFo);
|
||||
//
|
||||
m_lastStorages = m_map.get(m_lastPP);
|
||||
|
||||
|
@ -542,7 +557,8 @@ public class InOutGenerate extends SvrProcess
|
|||
{
|
||||
m_lastStorages = MStorage.getWarehouse(getCtx(),
|
||||
M_Warehouse_ID, M_Product_ID, M_AttributeSetInstance_ID,
|
||||
minGuaranteeDate, FiFo, true, 0 , get_TrxName());
|
||||
M_AttributeSet_ID, allAttributeInstances, minGuaranteeDate,
|
||||
FiFo, get_TrxName());
|
||||
m_map.put(m_lastPP, m_lastStorages);
|
||||
}
|
||||
return m_lastStorages;
|
||||
|
@ -563,11 +579,9 @@ public class InOutGenerate extends SvrProcess
|
|||
//
|
||||
addLog(m_shipment.getM_InOut_ID(), m_shipment.getMovementDate(), null, m_shipment.getDocumentNo());
|
||||
m_created++;
|
||||
|
||||
//reset storage cache as MInOut.completeIt will update m_storage
|
||||
m_map = new HashMap<SParameter,MStorage[]>();
|
||||
m_lastPP = null;
|
||||
m_lastStorages = null;
|
||||
if (m_lastPP != null && m_lastStorages != null)
|
||||
m_map.put(m_lastPP, m_lastStorages);
|
||||
}
|
||||
m_shipment = null;
|
||||
m_line = 0;
|
||||
|
@ -583,16 +597,21 @@ public class InOutGenerate extends SvrProcess
|
|||
* @param p_Warehouse_ID warehouse
|
||||
* @param p_Product_ID
|
||||
* @param p_AttributeSetInstance_ID
|
||||
* @param p_AttributeSet_ID
|
||||
* @param p_allAttributeInstances
|
||||
* @param p_minGuaranteeDate
|
||||
* @param p_FiFo
|
||||
*/
|
||||
protected SParameter (int p_Warehouse_ID,
|
||||
int p_Product_ID, int p_AttributeSetInstance_ID,
|
||||
Timestamp p_minGuaranteeDate, boolean p_FiFo)
|
||||
int p_Product_ID, int p_AttributeSetInstance_ID, int p_AttributeSet_ID,
|
||||
boolean p_allAttributeInstances, Timestamp p_minGuaranteeDate,
|
||||
boolean p_FiFo)
|
||||
{
|
||||
this.M_Warehouse_ID = p_Warehouse_ID;
|
||||
this.M_Product_ID = p_Product_ID;
|
||||
this.M_AttributeSetInstance_ID = p_AttributeSetInstance_ID;
|
||||
this.M_AttributeSet_ID = p_AttributeSet_ID;
|
||||
this.allAttributeInstances = p_allAttributeInstances;
|
||||
this.minGuaranteeDate = p_minGuaranteeDate;
|
||||
this.FiFo = p_FiFo;
|
||||
}
|
||||
|
@ -675,4 +694,3 @@ public class InOutGenerate extends SvrProcess
|
|||
} // Parameter
|
||||
|
||||
} // InOutGenerate
|
||||
|
||||
|
|
Loading…
Reference in New Issue