FR3004020 - Delivery Policy.
This is a slightly large commit affecting the core functionality of shipments so I'm happy for all eyeballs I can get on this code. I've tested as thorough one person can do. If there are no undiscovered bugs this doesn't change current functionality unless you change the new setting of "Delivery Policy" available on Client Info and Organization Info. See also http://www.adempiere.com/index.php/Delivery_Policy Link to SF Tracker: http://sourceforge.net/support/tracker.php?aid=3004020
This commit is contained in:
parent
2a64502984
commit
984f2b35b7
|
@ -0,0 +1,227 @@
|
|||
package org.adempiere.process;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MOrgInfo;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MClientInfo;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.process.ProcessInfoParameter;
|
||||
import org.compiere.process.SvrProcess;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
|
||||
/**
|
||||
* This process finds all complete sales orders that has physical items yet to
|
||||
* deliver and tries to allocate items from the items on hand.
|
||||
*
|
||||
* @author daniel.tamm
|
||||
*
|
||||
*/
|
||||
public class AllocateSalesOrders extends SvrProcess {
|
||||
|
||||
private int m_warehouseId;
|
||||
|
||||
public static class StockInfo {
|
||||
|
||||
public int productId;
|
||||
public BigDecimal qtyOnHand;
|
||||
public BigDecimal qtyAvailable;
|
||||
public BigDecimal qtyReserved;
|
||||
public BigDecimal qtyAllocated;
|
||||
|
||||
public StockInfo() {}
|
||||
|
||||
}
|
||||
|
||||
private static final String
|
||||
query = "select C_OrderLine.* from C_OrderLine " +
|
||||
"JOIN C_Order ON C_OrderLine.C_Order_ID=C_Order.C_Order_ID " +
|
||||
"JOIN M_Product ON C_OrderLine.M_Product_ID=M_Product.M_Product_ID " +
|
||||
"where C_Order.IsSOTrx='Y' AND C_Order.DocStatus='CO' AND QtyAllocated<(QtyOrdered-QtyDelivered) " +
|
||||
"AND M_Product.M_Product_ID=? " +
|
||||
"order by PriorityRule, C_OrderLine.Created ";
|
||||
|
||||
|
||||
@Override
|
||||
protected void prepare() {
|
||||
|
||||
m_warehouseId = 1000000; // TODO: Should be mandatory in the process definition
|
||||
|
||||
ProcessInfoParameter[] para = getParameter();
|
||||
for (int i = 0; i < para.length; i++) {
|
||||
String name = para[i].getParameterName();
|
||||
if (para[i].getParameter() == null);
|
||||
else if (name.equals("M_Warehouse_ID")) {
|
||||
m_warehouseId = para[i].getParameterAsInt();
|
||||
} else {
|
||||
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all order lines that contains not yet delivered physical items of a specific product.
|
||||
*
|
||||
* @param conn An open connection.
|
||||
* @param productId The product id being allocated
|
||||
* @return Order lines to allocate products to.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Vector<MOrderLine> getOrderLinesToAllocate(Connection conn, int productId, String trxName) throws SQLException {
|
||||
Vector<MOrderLine> result = new Vector<MOrderLine>();
|
||||
Properties ctx = Env.getCtx();
|
||||
MOrderLine line;
|
||||
PreparedStatement ps = conn.prepareStatement(query);
|
||||
ps.setInt(1, productId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while(rs.next()) {
|
||||
line = new MOrderLine(ctx, rs, trxName);
|
||||
result.add(line);
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all products that can be allocated. A product can be allocated if there are more items
|
||||
* on hand than what is already allocated. To be allocated the item must also be in demand
|
||||
* (reserved < allocated)
|
||||
*
|
||||
* @param conn
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Vector<StockInfo> getProductsToAllocate(Connection conn, int WarehouseID) throws SQLException {
|
||||
|
||||
Vector<StockInfo> result = new Vector<StockInfo>();
|
||||
StockInfo si;
|
||||
String query1 = "select M_Product_ID, sum(qtyonhand), sum(qtyreserved), sum(m_Product_Stock_v.qtyallocated) " +
|
||||
"from M_Product_Stock_v " +
|
||||
"WHERE M_Warehouse_ID=? AND M_Product_ID in " +
|
||||
"(select DISTINCT C_OrderLine.M_Product_ID FROM C_OrderLine " +
|
||||
"JOIN C_Order ON C_OrderLine.C_Order_ID=C_Order.C_Order_ID " +
|
||||
"JOIN M_Product ON C_OrderLine.M_Product_ID=M_Product.M_Product_ID " +
|
||||
"JOIN M_Product_Stock_v ON C_OrderLine.M_Product_ID=M_Product_Stock_v.M_Product_ID " +
|
||||
"WHERE " +
|
||||
"C_Order.IsSOTrx='Y' AND C_Order.DocStatus='CO' AND C_OrderLine.M_Warehouse_ID=? AND " +
|
||||
"(QtyOrdered-QtyDelivered)>0 AND (QtyOrdered-QtyDelivered)>C_OrderLine.QtyAllocated)" +
|
||||
"group by M_Product_ID " +
|
||||
"order by M_Product_ID";
|
||||
|
||||
PreparedStatement ps = conn.prepareStatement(query1);
|
||||
ps.setInt(1, WarehouseID);
|
||||
ps.setInt(2, WarehouseID);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
while(rs.next()) {
|
||||
si = new StockInfo();
|
||||
si.productId = rs.getInt(1);
|
||||
si.qtyOnHand = rs.getBigDecimal(2);
|
||||
si.qtyReserved = rs.getBigDecimal(3);
|
||||
si.qtyAvailable = si.qtyOnHand.subtract(si.qtyReserved);
|
||||
si.qtyAllocated = rs.getBigDecimal(4);
|
||||
result.add(si);
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
return(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doIt() throws Exception {
|
||||
|
||||
Connection conn = DB.getConnectionRO();
|
||||
Vector<StockInfo> products = AllocateSalesOrders.getProductsToAllocate(conn, m_warehouseId);
|
||||
conn.close();
|
||||
Vector<MOrderLine> lines;
|
||||
MOrderLine line;
|
||||
BigDecimal lineAllocate;
|
||||
BigDecimal toAllocate;
|
||||
BigDecimal onHand;
|
||||
BigDecimal allocated;
|
||||
BigDecimal qtyAvailable;
|
||||
BigDecimal willAllocate;
|
||||
StockInfo si;
|
||||
|
||||
// Make sure we have settings that needs allocation
|
||||
MWarehouse warehouse = new MWarehouse(getCtx(), m_warehouseId, get_TrxName());
|
||||
MOrgInfo orgInfo = MOrgInfo.get(getCtx(), warehouse.getAD_Org_ID(), get_TrxName());
|
||||
if (!orgInfo.getDeliveryPolicy().equals(MClientInfo.DELIVERY_POLICY_STRICT_ORDER)) {
|
||||
return "The current delivery policy of the warehouse doesn't use allocation.";
|
||||
}
|
||||
|
||||
if (products.size()==0) {
|
||||
log.info("There are no products to allocate.");
|
||||
return "";
|
||||
}
|
||||
|
||||
/** Iterate through all products to allocate */
|
||||
for (Iterator<StockInfo> it = products.iterator(); it.hasNext();) {
|
||||
|
||||
MProduct product = null;
|
||||
si = it.next();
|
||||
conn = DB.getConnectionRO();
|
||||
// Get all lines to allocate
|
||||
lines = AllocateSalesOrders.getOrderLinesToAllocate(conn, si.productId, get_TrxName());
|
||||
conn.close();
|
||||
|
||||
// Check if there are any lines to allocate
|
||||
// and create a log.
|
||||
if (lines.size()>0) {
|
||||
product = lines.get(0).getProduct();
|
||||
line = lines.get(0);
|
||||
qtyAvailable = si.qtyAvailable;
|
||||
onHand = si.qtyOnHand;
|
||||
// TO allocate = Min (qtyOnHand - qtyAllocated, qtyReserved - qtyAllocated)
|
||||
toAllocate = si.qtyOnHand.subtract(si.qtyAllocated).min(si.qtyReserved.subtract(si.qtyAllocated));
|
||||
if (toAllocate.signum()>0) {
|
||||
log.info("Allocating " + product.getValue() + " : " + product.getName() + " Avail: " + qtyAvailable + " On hand: " + onHand + " To alloc: " + toAllocate);
|
||||
log.info(lines.size() + " lines to allocate.");
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
allocated = BigDecimal.ZERO;
|
||||
|
||||
// When we are here we know what product, qty available and we have the lines
|
||||
// that need to be allocated.
|
||||
for (Iterator<MOrderLine> it2 = lines.iterator(); it2.hasNext(); ) {
|
||||
line = it2.next();
|
||||
|
||||
// Calculate what to allocate (what we want)
|
||||
lineAllocate = line.getQtyOrdered().subtract(line.getQtyDelivered()).subtract(line.getQtyAllocated());
|
||||
willAllocate = lineAllocate.min(toAllocate);
|
||||
if (willAllocate.signum()==1) {
|
||||
willAllocate = line.allocateOnHand(willAllocate, get_TrxName());
|
||||
allocated = allocated.add(willAllocate);
|
||||
toAllocate = toAllocate.subtract(willAllocate);
|
||||
log.info("Allocated " + willAllocate + " to order " + line.getC_Order().getDocumentNo() + " " + toAllocate + " left to allocate.");
|
||||
if (toAllocate.equals(BigDecimal.ZERO))
|
||||
break;
|
||||
} else {
|
||||
log.info("Skipping allocation of order " + line.getC_Order().getDocumentNo());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return("");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package org.adempiere.validator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.adempiere.process.AllocateSalesOrders;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.ModelValidationEngine;
|
||||
import org.compiere.model.ModelValidator;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Trx;
|
||||
|
||||
/**
|
||||
* Validator that allocates products as soon as they hit the warehouse.
|
||||
* Not yet activated but will be in upcoming revisions.
|
||||
*
|
||||
* @author Daniel Tamm
|
||||
*
|
||||
*/
|
||||
public class MaterialReceiptModelValidator implements ModelValidator {
|
||||
|
||||
private static final CLogger logger = CLogger.getCLogger(MaterialReceiptModelValidator.class);
|
||||
|
||||
private int ad_Client_ID = -1;
|
||||
|
||||
@Override
|
||||
public int getAD_Client_ID() {
|
||||
return ad_Client_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ModelValidationEngine engine, MClient client) {
|
||||
|
||||
if (client != null) {
|
||||
ad_Client_ID = client.getAD_Client_ID();
|
||||
}
|
||||
engine.addDocValidate(MInOut.Table_Name, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String docValidate(PO po, int timing) {
|
||||
if (timing == ModelValidator.TIMING_AFTER_COMPLETE) {
|
||||
MInOut io = (MInOut)po;
|
||||
// We only allocate incoming material
|
||||
if (!io.isSOTrx()) {
|
||||
MInOutLine[] lines = io.getLines();
|
||||
MInOutLine line;
|
||||
|
||||
try {
|
||||
String trxName = Trx.createTrxName();
|
||||
Trx trx = Trx.get(trxName, true);
|
||||
Connection conn = trx.getConnection();
|
||||
|
||||
for (int i=0; i<lines.length; i++) {
|
||||
line = lines[i];
|
||||
try {
|
||||
allocateProducts(conn, trxName, line);
|
||||
trx.commit();
|
||||
trx.close();
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
trx.rollback();
|
||||
trx.close();
|
||||
conn.close();
|
||||
return(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException ee) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void allocateProducts(Connection conn, String trxName, MInOutLine iol) throws SQLException {
|
||||
|
||||
BigDecimal qty = iol.getMovementQty();
|
||||
|
||||
// Make sure we have a positive amount
|
||||
if (qty.signum()>0) {
|
||||
|
||||
Vector<MOrderLine> lines = AllocateSalesOrders.getOrderLinesToAllocate(conn, iol.getProduct().get_ID(), trxName);
|
||||
|
||||
MOrderLine line;
|
||||
BigDecimal receivedQty = iol.getMovementQty();
|
||||
BigDecimal toAllocate;
|
||||
BigDecimal willAllocate;
|
||||
|
||||
for (Iterator<MOrderLine> it = lines.iterator(); it.hasNext(); ) {
|
||||
line = it.next();
|
||||
// Calculate what to allocate (what we want)
|
||||
toAllocate = line.getQtyOrdered().subtract(line.getQtyDelivered());
|
||||
// What we got (minimum of what was received and what we want)
|
||||
willAllocate = toAllocate.min(receivedQty);
|
||||
line.setQtyAllocated(willAllocate);
|
||||
line.saveEx(trxName);
|
||||
logger.info("Allocated " + willAllocate + " to order " + line.getC_Order().getDocumentNo());
|
||||
receivedQty = receivedQty.subtract(willAllocate);
|
||||
if (receivedQty.equals(BigDecimal.ZERO))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public String login(final int AD_Org_ID, final int AD_Role_ID,
|
||||
final int AD_User_ID) {
|
||||
|
||||
logger.info("AD_Org_ID=" + AD_Org_ID + "; AD_Role_ID=" + AD_Role_ID
|
||||
+ "; AD_User_ID=" + AD_User_ID);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelChange(PO po, int type) throws Exception {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -273,6 +273,21 @@ public interface I_AD_ClientInfo
|
|||
|
||||
public I_C_UOM getC_UOM_Time() throws RuntimeException;
|
||||
|
||||
/** Column name C_UOM_Weight_ID */
|
||||
public static final String COLUMNNAME_C_UOM_Weight_ID = "C_UOM_Weight_ID";
|
||||
|
||||
/** Set UOM for Weight.
|
||||
* Standard Unit of Measure for Weight
|
||||
*/
|
||||
public void setC_UOM_Weight_ID (int C_UOM_Weight_ID);
|
||||
|
||||
/** Get UOM for Weight.
|
||||
* Standard Unit of Measure for Weight
|
||||
*/
|
||||
public int getC_UOM_Weight_ID();
|
||||
|
||||
public I_C_UOM getC_UOM_Weight() throws RuntimeException;
|
||||
|
||||
/** Column name C_UOM_Volume_ID */
|
||||
public static final String COLUMNNAME_C_UOM_Volume_ID = "C_UOM_Volume_ID";
|
||||
|
||||
|
@ -288,20 +303,18 @@ public interface I_AD_ClientInfo
|
|||
|
||||
public I_C_UOM getC_UOM_Volume() throws RuntimeException;
|
||||
|
||||
/** Column name C_UOM_Weight_ID */
|
||||
public static final String COLUMNNAME_C_UOM_Weight_ID = "C_UOM_Weight_ID";
|
||||
/** Column name DeliveryPolicy */
|
||||
public static final String COLUMNNAME_DeliveryPolicy = "DeliveryPolicy";
|
||||
|
||||
/** Set UOM for Weight.
|
||||
* Standard Unit of Measure for Weight
|
||||
/** Set Delivery Policy.
|
||||
* Delivery Policy
|
||||
*/
|
||||
public void setC_UOM_Weight_ID (int C_UOM_Weight_ID);
|
||||
public void setDeliveryPolicy (String DeliveryPolicy);
|
||||
|
||||
/** Get UOM for Weight.
|
||||
* Standard Unit of Measure for Weight
|
||||
/** Get Delivery Policy.
|
||||
* Delivery Policy
|
||||
*/
|
||||
public int getC_UOM_Weight_ID();
|
||||
|
||||
public I_C_UOM getC_UOM_Weight() throws RuntimeException;
|
||||
public String getDeliveryPolicy();
|
||||
|
||||
/** Column name IsActive */
|
||||
public static final String COLUMNNAME_IsActive = "IsActive";
|
||||
|
|
|
@ -123,6 +123,19 @@ public interface I_AD_OrgInfo
|
|||
*/
|
||||
public int getCreatedBy();
|
||||
|
||||
/** Column name DeliveryPolicy */
|
||||
public static final String COLUMNNAME_DeliveryPolicy = "DeliveryPolicy";
|
||||
|
||||
/** Set Delivery Policy.
|
||||
* Delivery Policy
|
||||
*/
|
||||
public void setDeliveryPolicy (String DeliveryPolicy);
|
||||
|
||||
/** Get Delivery Policy.
|
||||
* Delivery Policy
|
||||
*/
|
||||
public String getDeliveryPolicy();
|
||||
|
||||
/** Column name DropShip_Warehouse_ID */
|
||||
public static final String COLUMNNAME_DropShip_Warehouse_ID = "DropShip_Warehouse_ID";
|
||||
|
||||
|
|
|
@ -602,6 +602,19 @@ public interface I_C_OrderLine
|
|||
*/
|
||||
public boolean isProcessed();
|
||||
|
||||
/** Column name QtyAllocated */
|
||||
public static final String COLUMNNAME_QtyAllocated = "QtyAllocated";
|
||||
|
||||
/** Set Qty Allocated.
|
||||
* Allocated quantity
|
||||
*/
|
||||
public void setQtyAllocated (BigDecimal QtyAllocated);
|
||||
|
||||
/** Get Qty Allocated.
|
||||
* Allocated quantity
|
||||
*/
|
||||
public BigDecimal getQtyAllocated();
|
||||
|
||||
/** Column name QtyDelivered */
|
||||
public static final String COLUMNNAME_QtyDelivered = "QtyDelivered";
|
||||
|
||||
|
|
|
@ -149,6 +149,19 @@ public interface I_M_Storage
|
|||
|
||||
public I_M_Product getM_Product() throws RuntimeException;
|
||||
|
||||
/** Column name QtyAllocated */
|
||||
public static final String COLUMNNAME_QtyAllocated = "QtyAllocated";
|
||||
|
||||
/** Set Qty Allocated.
|
||||
* Allocated quantity
|
||||
*/
|
||||
public void setQtyAllocated (BigDecimal QtyAllocated);
|
||||
|
||||
/** Get Qty Allocated.
|
||||
* Allocated quantity
|
||||
*/
|
||||
public BigDecimal getQtyAllocated();
|
||||
|
||||
/** Column name QtyOnHand */
|
||||
public static final String COLUMNNAME_QtyOnHand = "QtyOnHand";
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ public class MClientInfo extends X_AD_ClientInfo
|
|||
*/
|
||||
private static final long serialVersionUID = 4861006368856890116L;
|
||||
|
||||
public static final String DELIVERY_POLICY_STRICT_ORDER = "O";
|
||||
public static final String DELIVERY_POLICY_NO_HOLD = "N";
|
||||
|
||||
/**
|
||||
* Get Client Info
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Properties;
|
|||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.exceptions.AdempiereException;
|
||||
import org.adempiere.process.AllocateSalesOrders;
|
||||
import org.compiere.print.ReportEngine;
|
||||
import org.compiere.process.DocAction;
|
||||
import org.compiere.process.DocumentEngine;
|
||||
|
@ -64,6 +65,8 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
/**
|
||||
* Create Shipment From Order
|
||||
* @param order order
|
||||
* @param oLines order lines to use when creating the shipment. If null all lines
|
||||
* from the order is used.
|
||||
* @param movementDate optional movement date
|
||||
* @param forceDelivery ignore order delivery rule
|
||||
* @param allAttributeInstances if true, all attribute set instances
|
||||
|
@ -72,10 +75,10 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
* @param trxName transaction
|
||||
* @return Shipment or null
|
||||
*/
|
||||
public static MInOut createFrom (MOrder order, Timestamp movementDate,
|
||||
boolean forceDelivery, boolean allAttributeInstances, Timestamp minGuaranteeDate,
|
||||
boolean complete, String trxName)
|
||||
{
|
||||
public static MInOut createFrom (MOrder order, MOrderLine[] oLines, Timestamp movementDate,
|
||||
boolean forceDelivery, boolean allAttributeInstances, Timestamp minGuaranteeDate,
|
||||
boolean complete, String trxName) {
|
||||
|
||||
if (order == null)
|
||||
throw new IllegalArgumentException("No Order");
|
||||
//
|
||||
|
@ -88,10 +91,16 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
MInOut retValue = new MInOut (order, 0, movementDate);
|
||||
retValue.setDocAction(complete ? DOCACTION_Complete : DOCACTION_Prepare);
|
||||
|
||||
// Check if we can create the lines
|
||||
MOrderLine[] oLines = order.getLines(true, "M_Product_ID");
|
||||
if (oLines == null) {
|
||||
oLines = order.getLines(true, "M_Product_ID");
|
||||
}
|
||||
for (int i = 0; i < oLines.length; i++)
|
||||
{
|
||||
if (oLines[i].getC_Order_ID()!=order.get_ID()) {
|
||||
// If the orderline ID and order ID doesn't match, skip the line
|
||||
continue;
|
||||
}
|
||||
// Calculate how much is left to deliver (ordered - delivered)
|
||||
BigDecimal qty = oLines[i].getQtyOrdered().subtract(oLines[i].getQtyDelivered());
|
||||
// Nothing to deliver
|
||||
if (qty.signum() == 0)
|
||||
|
@ -99,6 +108,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
// Stock Info
|
||||
MStorage[] storages = null;
|
||||
MProduct product = oLines[i].getProduct();
|
||||
// If the order line is a product (not a charge) and the product is stocked, find the locators
|
||||
if (product != null && product.get_ID() != 0 && product.isStocked())
|
||||
{
|
||||
String MMPolicy = product.getMMPolicy();
|
||||
|
@ -106,9 +116,11 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
oLines[i].getM_Product_ID(), oLines[i].getM_AttributeSetInstance_ID(),
|
||||
minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, 0, trxName);
|
||||
} else {
|
||||
// If the order is a charge or the product is not stocked, don't try to deliver it.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Unless the order is force delivery then check delivery rule
|
||||
if (!forceDelivery)
|
||||
{
|
||||
BigDecimal maxQty = Env.ZERO;
|
||||
|
@ -119,9 +131,11 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
if (maxQty.compareTo(qty) < 0)
|
||||
qty = maxQty;
|
||||
}
|
||||
else if (DELIVERYRULE_CompleteLine.equals(order.getDeliveryRule()))
|
||||
else if (DELIVERYRULE_CompleteLine.equals(order.getDeliveryRule())
|
||||
|| DELIVERYRULE_CompleteOrder.equals(order.getDeliveryRule()))
|
||||
{
|
||||
if (maxQty.compareTo(qty) < 0)
|
||||
// Not enough to deliver the complete line
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -129,9 +143,12 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
if (retValue.get_ID() == 0) // not saved yet
|
||||
retValue.save(trxName);
|
||||
// Create a line until qty is reached
|
||||
// There will be one line per storage (if there items are stored in more than one storage)
|
||||
for (int ll = 0; ll < storages.length; ll++)
|
||||
{
|
||||
// Set lineQty to what's available in the storage
|
||||
BigDecimal lineQty = storages[ll].getQtyOnHand();
|
||||
// If lineQty is more than enough, set lineQty to original qty to be delivered.
|
||||
if (lineQty.compareTo(qty) > 0)
|
||||
lineQty = qty;
|
||||
MInOutLine line = new MInOutLine (retValue);
|
||||
|
@ -142,6 +159,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
line.setQtyEntered(lineQty
|
||||
.multiply(oLines[i].getQtyEntered())
|
||||
.divide(oLines[i].getQtyOrdered(), 12, BigDecimal.ROUND_HALF_UP));
|
||||
// Set project ID if any
|
||||
line.setC_Project_ID(oLines[i].getC_Project_ID());
|
||||
line.save(trxName);
|
||||
// Delivered everything ?
|
||||
|
@ -158,6 +176,27 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
return null;
|
||||
|
||||
return retValue;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Shipment From Order (using all order lines)
|
||||
* @param order order
|
||||
* @param movementDate optional movement date
|
||||
* @param forceDelivery ignore order delivery rule
|
||||
* @param allAttributeInstances if true, all attribute set instances
|
||||
* @param minGuaranteeDate optional minimum guarantee date if all attribute instances
|
||||
* @param complete complete document (Process if false, Complete if true)
|
||||
* @param trxName transaction
|
||||
* @return Shipment or null
|
||||
*/
|
||||
public static MInOut createFrom (MOrder order, Timestamp movementDate,
|
||||
boolean forceDelivery, boolean allAttributeInstances, Timestamp minGuaranteeDate,
|
||||
boolean complete, String trxName)
|
||||
{
|
||||
// Select all lines of the order
|
||||
MOrderLine[] oLines = order.getLines(true, "M_Product_ID");
|
||||
return createFrom(order, oLines, movementDate, forceDelivery, allAttributeInstances, minGuaranteeDate,complete,trxName);
|
||||
} // createFrom
|
||||
|
||||
/**
|
||||
|
@ -1278,6 +1317,10 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
|
||||
log.info("Line=" + sLine.getLine() + " - Qty=" + sLine.getMovementQty());
|
||||
|
||||
// Check delivery policy
|
||||
MOrgInfo orgInfo = MOrgInfo.get(getCtx(), sLine.getAD_Org_ID(), get_TrxName());
|
||||
boolean isStrictOrder = MClientInfo.DELIVERY_POLICY_STRICT_ORDER.equalsIgnoreCase(orgInfo.getDeliveryPolicy());
|
||||
|
||||
// Stock Movement - Counterpart MOrder.reserveStock
|
||||
if (product != null
|
||||
&& product.isStocked() )
|
||||
|
@ -1311,10 +1354,13 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
QtyMA = QtyMA.negate();
|
||||
BigDecimal reservedDiff = Env.ZERO;
|
||||
BigDecimal orderedDiff = Env.ZERO;
|
||||
BigDecimal allocatedDiff = Env.ZERO;
|
||||
if (sLine.getC_OrderLine_ID() != 0)
|
||||
{
|
||||
if (isSOTrx())
|
||||
if (isSOTrx()) {
|
||||
reservedDiff = ma.getMovementQty().negate();
|
||||
allocatedDiff = ma.getMovementQty().negate();
|
||||
}
|
||||
else
|
||||
orderedDiff = ma.getMovementQty().negate();
|
||||
}
|
||||
|
@ -1328,6 +1374,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
QtyMA,
|
||||
sameWarehouse ? reservedDiff : Env.ZERO,
|
||||
sameWarehouse ? orderedDiff : Env.ZERO,
|
||||
sameWarehouse && isStrictOrder ? allocatedDiff : Env.ZERO,
|
||||
get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA)";
|
||||
|
@ -1340,7 +1387,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
wh.getDefaultLocator().getM_Locator_ID(),
|
||||
sLine.getM_Product_ID(),
|
||||
ma.getM_AttributeSetInstance_ID(), reservationAttributeSetInstance_ID,
|
||||
Env.ZERO, reservedDiff, orderedDiff, get_TrxName()))
|
||||
Env.ZERO, reservedDiff, orderedDiff, allocatedDiff, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA) in order warehouse";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -1364,13 +1411,14 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
{
|
||||
BigDecimal reservedDiff = sameWarehouse ? QtySO.negate() : Env.ZERO;
|
||||
BigDecimal orderedDiff = sameWarehouse ? QtyPO.negate(): Env.ZERO;
|
||||
BigDecimal allocatedDiff = isStrictOrder ? reservedDiff : Env.ZERO;
|
||||
|
||||
// Fallback: Update Storage - see also VMatch.createMatchRecord
|
||||
if (!MStorage.add(getCtx(), getM_Warehouse_ID(),
|
||||
sLine.getM_Locator_ID(),
|
||||
sLine.getM_Product_ID(),
|
||||
sLine.getM_AttributeSetInstance_ID(), reservationAttributeSetInstance_ID,
|
||||
Qty, reservedDiff, orderedDiff, get_TrxName()))
|
||||
Qty, reservedDiff, orderedDiff, allocatedDiff, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -1382,7 +1430,7 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
wh.getDefaultLocator().getM_Locator_ID(),
|
||||
sLine.getM_Product_ID(),
|
||||
sLine.getM_AttributeSetInstance_ID(), reservationAttributeSetInstance_ID,
|
||||
Env.ZERO, QtySO.negate(), QtyPO.negate(), get_TrxName()))
|
||||
Env.ZERO, QtySO.negate(), QtyPO.negate(), allocatedDiff, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -1412,10 +1460,15 @@ public class MInOut extends X_M_InOut implements DocAction
|
|||
if (isSOTrx() // PO is done by Matching
|
||||
|| sLine.getM_Product_ID() == 0) // PO Charges, empty lines
|
||||
{
|
||||
if (isSOTrx())
|
||||
if (isSOTrx()) {
|
||||
oLine.setQtyDelivered(oLine.getQtyDelivered().subtract(Qty));
|
||||
else
|
||||
// Adjust allocated on order line
|
||||
if (isStrictOrder && product.isStocked()) oLine.setQtyAllocated(oLine.getQtyAllocated().add(Qty));
|
||||
} else {
|
||||
oLine.setQtyDelivered(oLine.getQtyDelivered().add(Qty));
|
||||
// Adjust allocated on order line
|
||||
if (isStrictOrder && product.isStocked()) oLine.setQtyAllocated(oLine.getQtyAllocated().subtract(Qty));
|
||||
}
|
||||
oLine.setDateDelivered(getMovementDate()); // overwrite=last
|
||||
}
|
||||
if (!oLine.save())
|
||||
|
|
|
@ -431,7 +431,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
line.getM_Locator_ID(),
|
||||
line.getM_Product_ID(),
|
||||
ma.getM_AttributeSetInstance_ID(), 0,
|
||||
QtyMA.negate(), Env.ZERO, Env.ZERO, get_TrxName()))
|
||||
QtyMA.negate(), Env.ZERO, Env.ZERO, Env.ZERO, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -489,7 +489,7 @@ public class MInventory extends X_M_Inventory implements DocAction
|
|||
line.getM_Locator_ID(),
|
||||
line.getM_Product_ID(),
|
||||
line.getM_AttributeSetInstance_ID(), 0,
|
||||
qtyDiff, Env.ZERO, Env.ZERO, get_TrxName()))
|
||||
qtyDiff, Env.ZERO, Env.ZERO, Env.ZERO, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
|
|
@ -403,7 +403,7 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
line.getM_Locator_ID(),
|
||||
line.getM_Product_ID(),
|
||||
ma.getM_AttributeSetInstance_ID(), 0,
|
||||
ma.getMovementQty().negate(), Env.ZERO , Env.ZERO , get_TrxName()))
|
||||
ma.getMovementQty().negate(), Env.ZERO , Env.ZERO , Env.ZERO, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -420,7 +420,7 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
line.getM_LocatorTo_ID(),
|
||||
line.getM_Product_ID(),
|
||||
M_AttributeSetInstanceTo_ID, 0,
|
||||
ma.getMovementQty(), Env.ZERO , Env.ZERO , get_TrxName()))
|
||||
ma.getMovementQty(), Env.ZERO , Env.ZERO , Env.ZERO, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -459,7 +459,7 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
line.getM_Locator_ID(),
|
||||
line.getM_Product_ID(),
|
||||
line.getM_AttributeSetInstance_ID(), 0,
|
||||
line.getMovementQty().negate(), Env.ZERO , Env.ZERO , get_TrxName()))
|
||||
line.getMovementQty().negate(), Env.ZERO , Env.ZERO , Env.ZERO, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
@ -470,7 +470,7 @@ public class MMovement extends X_M_Movement implements DocAction
|
|||
line.getM_LocatorTo_ID(),
|
||||
line.getM_Product_ID(),
|
||||
line.getM_AttributeSetInstanceTo_ID(), 0,
|
||||
line.getMovementQty(), Env.ZERO , Env.ZERO , get_TrxName()))
|
||||
line.getMovementQty(), Env.ZERO , Env.ZERO , Env.ZERO, get_TrxName()))
|
||||
{
|
||||
m_processMsg = "Cannot correct Inventory (MA)";
|
||||
return DocAction.STATUS_Invalid;
|
||||
|
|
|
@ -1391,7 +1391,7 @@ public class MOrder extends X_C_Order implements DocAction
|
|||
* @param lines order lines (ordered by M_Product_ID for deadlock prevention)
|
||||
* @return true if (un) reserved
|
||||
*/
|
||||
private boolean reserveStock (MDocType dt, MOrderLine[] lines)
|
||||
public boolean reserveStock (MDocType dt, MOrderLine[] lines)
|
||||
{
|
||||
if (dt == null)
|
||||
dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||
|
@ -1415,6 +1415,7 @@ public class MOrder extends X_C_Order implements DocAction
|
|||
|
||||
BigDecimal Volume = Env.ZERO;
|
||||
BigDecimal Weight = Env.ZERO;
|
||||
BigDecimal diffQtyAllocated = Env.ZERO;
|
||||
|
||||
// Always check and (un) Reserve Inventory
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
|
@ -1480,15 +1481,28 @@ public class MOrder extends X_C_Order implements DocAction
|
|||
M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
|
||||
}
|
||||
}
|
||||
// Update Storage
|
||||
// == Update Storage
|
||||
// reserve but don't allocate if quantity is increased.
|
||||
// If quantity is decreased, release allocation.
|
||||
if (reserved.signum()<0) {
|
||||
// Decreasing reservation, check if allocation should be released
|
||||
diffQtyAllocated = target.subtract(line.getQtyAllocated());
|
||||
diffQtyAllocated = diffQtyAllocated.min(BigDecimal.ZERO);
|
||||
} else {
|
||||
diffQtyAllocated = BigDecimal.ZERO;
|
||||
}
|
||||
if (!MStorage.add(getCtx(), line.getM_Warehouse_ID(), M_Locator_ID,
|
||||
line.getM_Product_ID(),
|
||||
line.getM_AttributeSetInstance_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
Env.ZERO, reserved, ordered, get_TrxName()))
|
||||
Env.ZERO, reserved, ordered, diffQtyAllocated, get_TrxName()))
|
||||
return false;
|
||||
// == End of update storage
|
||||
} // stockec
|
||||
// update line
|
||||
line.setQtyReserved(line.getQtyReserved().add(difference));
|
||||
if (diffQtyAllocated.signum()!=0) {
|
||||
line.setQtyAllocated(line.getQtyAllocated().add(diffQtyAllocated));
|
||||
}
|
||||
if (!line.save(get_TrxName()))
|
||||
return false;
|
||||
//
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.compiere.util.CLogger;
|
|||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Trx;
|
||||
|
||||
/**
|
||||
* Order Line Model.
|
||||
|
@ -118,6 +119,7 @@ public class MOrderLine extends X_C_OrderLine
|
|||
return retValue;
|
||||
} // getNotReserved
|
||||
|
||||
|
||||
/** Logger */
|
||||
private static CLogger s_log = CLogger.getCLogger (MOrderLine.class);
|
||||
|
||||
|
@ -574,6 +576,97 @@ public class MOrderLine extends X_C_OrderLine
|
|||
return true;
|
||||
} // canChangeWarehouse
|
||||
|
||||
/**
|
||||
* Allocates at most 'toAllocate' number of items.
|
||||
* If the toAllocate is a negative number material is unallocated.
|
||||
*
|
||||
* @return Number allocated
|
||||
*/
|
||||
public BigDecimal allocateOnHand(BigDecimal toAllocate, String trxName) {
|
||||
|
||||
if (BigDecimal.ZERO.equals(toAllocate))
|
||||
return BigDecimal.ZERO;
|
||||
|
||||
boolean reverse = toAllocate.signum()<0;
|
||||
|
||||
BigDecimal allocated = BigDecimal.ZERO;
|
||||
MProduct product = getProduct();
|
||||
boolean fifo = MClient.MMPOLICY_FiFo.equals(product.getMMPolicy());
|
||||
// Find storages
|
||||
MStorage[] storages = MStorage.getWarehouse(
|
||||
getCtx(),
|
||||
getM_Warehouse_ID(),
|
||||
getM_Product_ID(),
|
||||
getM_AttributeSetInstance_ID(),
|
||||
null, // TODO: Min Guarantee date
|
||||
fifo, // Material policy
|
||||
!reverse, // Return positive only unless this is a reverse allocation.
|
||||
0, // Optional Locator ID (check all locators)
|
||||
trxName);
|
||||
|
||||
MStorage s;
|
||||
BigDecimal unallocated;
|
||||
BigDecimal allocate;
|
||||
if (!reverse) {
|
||||
// Normal allocation
|
||||
// Iterate through the storages and allocate
|
||||
for (int i = 0; i<storages.length; i++) {
|
||||
s = storages[i];
|
||||
if (s.getQtyOnHand().signum()<=0) break; // Nothing to allocate.
|
||||
unallocated = s.getQtyOnHand().subtract(s.getQtyAllocated());
|
||||
if (unallocated.signum()>0) {
|
||||
allocate = toAllocate.min(unallocated); // Allocate all unallocated or max of what we want to allocate.
|
||||
allocated = allocated.add(allocate);
|
||||
// Update storage
|
||||
s.setQtyAllocated(s.getQtyAllocated().add(allocate));
|
||||
s.saveEx(trxName); // Save storage
|
||||
// Update order line
|
||||
setQtyAllocated(getQtyAllocated().add(allocate));
|
||||
// Adjust toAllocate
|
||||
toAllocate = toAllocate.subtract(allocate);
|
||||
// If what we have allocated now is what we want to allocate then
|
||||
// exit this loop.
|
||||
if (toAllocate.signum()<=0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Reverse allocation
|
||||
BigDecimal currentlyAllocated;
|
||||
BigDecimal unallocate;
|
||||
BigDecimal toUnallocate = toAllocate.abs();
|
||||
unallocated = BigDecimal.ZERO;
|
||||
for (int i = 0; i<storages.length; i++) {
|
||||
s = storages[i];
|
||||
currentlyAllocated = s.getQtyAllocated();
|
||||
if (currentlyAllocated.signum()>0) {
|
||||
unallocate = currentlyAllocated.min(toUnallocate);
|
||||
unallocated = unallocated.add(unallocate);
|
||||
// Update storage
|
||||
s.setQtyAllocated(currentlyAllocated.subtract(unallocate));
|
||||
s.saveEx(trxName);
|
||||
// Update order line
|
||||
setQtyAllocated(getQtyAllocated().subtract(unallocate));
|
||||
// Adjust toUnallocate
|
||||
toUnallocate = toUnallocate.subtract(unallocate);
|
||||
// If we have unallocated all, exit this loop
|
||||
if (toUnallocate.signum()<=0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
allocated = unallocated.negate();
|
||||
}
|
||||
if (allocated.signum()!=0) {
|
||||
// Save order line
|
||||
saveEx(trxName);
|
||||
}
|
||||
|
||||
return(allocated);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get C_Project_ID
|
||||
* @return project
|
||||
|
@ -936,9 +1029,18 @@ public class MOrderLine extends X_C_OrderLine
|
|||
}
|
||||
if (Env.ZERO.compareTo(getQtyReserved()) != 0)
|
||||
{
|
||||
// Unreserve
|
||||
setQty(BigDecimal.ZERO);
|
||||
((MOrder)getC_Order()).reserveStock(null, new MOrderLine[]{this});
|
||||
// For PO should be On Order
|
||||
log.saveError("DeleteError", Msg.translate(getCtx(), "QtyReserved") + "=" + getQtyReserved());
|
||||
return false;
|
||||
if (!getQtyReserved().equals(BigDecimal.ZERO)) {
|
||||
log.saveError("DeleteError", Msg.translate(getCtx(), "QtyReserved") + "=" + getQtyReserved());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Env.ZERO.compareTo(getQtyAllocated()) != 0) {
|
||||
// Unallocate
|
||||
allocateOnHand(getQtyAllocated().negate(), get_TrxName());
|
||||
}
|
||||
|
||||
// UnLink All Requisitions
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.sql.ResultSet;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.Env;
|
||||
|
||||
/**
|
||||
* Organization Info Model
|
||||
|
@ -100,4 +101,19 @@ public class MOrgInfo extends X_AD_OrgInfo
|
|||
setTaxID ("?");
|
||||
} // MOrgInfo
|
||||
|
||||
/**
|
||||
* Returns the delivery policy of this organization. If no specific organization is set
|
||||
* the delivery policy of the client is returned
|
||||
*/
|
||||
@Override
|
||||
public String getDeliveryPolicy() {
|
||||
String orgDeliveryPolicy = super.getDeliveryPolicy();
|
||||
if (orgDeliveryPolicy!=null && orgDeliveryPolicy.trim().length()>0) {
|
||||
return(orgDeliveryPolicy);
|
||||
}
|
||||
// Get the client's delivery policy
|
||||
MClientInfo info = MClientInfo.get(Env.getCtx(), getAD_Client_ID());
|
||||
return(info.getDeliveryPolicy());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ public class MProjectIssue extends X_C_ProjectIssue
|
|||
MLocator loc = MLocator.get(getCtx(), getM_Locator_ID());
|
||||
if (MStorage.add(getCtx(), loc.getM_Warehouse_ID(), getM_Locator_ID(),
|
||||
getM_Product_ID(), getM_AttributeSetInstance_ID(), getM_AttributeSetInstance_ID(),
|
||||
getMovementQty().negate(), null, null, get_TrxName()))
|
||||
getMovementQty().negate(), null, null, null, get_TrxName()))
|
||||
{
|
||||
if (mTrx.save(get_TrxName()))
|
||||
{
|
||||
|
|
|
@ -267,7 +267,7 @@ public class MStorage extends X_M_Storage
|
|||
// Specific Attribute Set Instance
|
||||
String sql = "SELECT s.M_Product_ID,s.M_Locator_ID,s.M_AttributeSetInstance_ID,"
|
||||
+ "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 "
|
||||
+ "s.QtyOnHand,s.QtyReserved,s.QtyOrdered,s.QtyAllocated,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)
|
||||
|
@ -292,7 +292,7 @@ public class MStorage extends X_M_Storage
|
|||
{
|
||||
sql = "SELECT s.M_Product_ID,s.M_Locator_ID,s.M_AttributeSetInstance_ID,"
|
||||
+ "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 "
|
||||
+ "s.QtyOnHand,s.QtyReserved,s.QtyOrdered,s.QtyAllocated,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) ";
|
||||
|
@ -413,7 +413,10 @@ public class MStorage extends X_M_Storage
|
|||
public static boolean add (Properties ctx, int M_Warehouse_ID, int M_Locator_ID,
|
||||
int M_Product_ID, int M_AttributeSetInstance_ID, int reservationAttributeSetInstance_ID,
|
||||
BigDecimal diffQtyOnHand,
|
||||
BigDecimal diffQtyReserved, BigDecimal diffQtyOrdered, String trxName)
|
||||
BigDecimal diffQtyReserved,
|
||||
BigDecimal diffQtyOrdered,
|
||||
BigDecimal diffQtyAllocated,
|
||||
String trxName)
|
||||
{
|
||||
MStorage storage = null;
|
||||
StringBuffer diffText = new StringBuffer("(");
|
||||
|
@ -478,6 +481,15 @@ public class MStorage extends X_M_Storage
|
|||
diffText.append(" Ordered=").append(diffQtyOrdered);
|
||||
changed = true;
|
||||
}
|
||||
if (diffQtyAllocated !=null && diffQtyAllocated.signum() != 0)
|
||||
{
|
||||
if (storage0 == null)
|
||||
storage.setQtyAllocated(storage.getQtyAllocated().add(diffQtyAllocated));
|
||||
else
|
||||
storage0.setQtyAllocated(storage0.getQtyAllocated().add(diffQtyAllocated));
|
||||
diffText.append(" Allocated=").append(diffQtyAllocated);
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
diffText.append(") -> ").append(storage.toString());
|
||||
|
@ -611,6 +623,47 @@ public class MStorage extends X_M_Storage
|
|||
return retValue;
|
||||
} // getQtyAvailable
|
||||
|
||||
/**
|
||||
* Get Warehouse/Locator on hand Qty.
|
||||
* The call is accurate only if there is a storage record
|
||||
* and assumes that the product is stocked
|
||||
* @param M_Warehouse_ID wh (if the M_Locator_ID!=0 then M_Warehouse_ID is ignored)
|
||||
* @param M_Locator_ID locator (if 0, the whole warehouse will be evaluated)
|
||||
* @param M_Product_ID product
|
||||
* @param M_AttributeSetInstance_ID masi
|
||||
* @param trxName transaction
|
||||
* @return qty on hand (QtyOnHand) or null if error
|
||||
*/
|
||||
public static BigDecimal getQtyOnHand (int M_Warehouse_ID, int M_Locator_ID,
|
||||
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
|
||||
{
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
StringBuffer sql = new StringBuffer("SELECT COALESCE(SUM(s.QtyOnHand),0)")
|
||||
.append(" FROM M_Storage s")
|
||||
.append(" WHERE s.M_Product_ID=?");
|
||||
params.add(M_Product_ID);
|
||||
// Warehouse level
|
||||
if (M_Locator_ID == 0) {
|
||||
sql.append(" AND EXISTS (SELECT 1 FROM M_Locator l WHERE s.M_Locator_ID=l.M_Locator_ID AND l.M_Warehouse_ID=?)");
|
||||
params.add(M_Warehouse_ID);
|
||||
}
|
||||
// Locator level
|
||||
else {
|
||||
sql.append(" AND s.M_Locator_ID=?");
|
||||
params.add(M_Locator_ID);
|
||||
}
|
||||
// With ASI
|
||||
if (M_AttributeSetInstance_ID != 0) {
|
||||
sql.append(" AND s.M_AttributeSetInstance_ID=?");
|
||||
params.add(M_AttributeSetInstance_ID);
|
||||
}
|
||||
//
|
||||
BigDecimal retValue = DB.getSQLValueBD(trxName, sql.toString(), params);
|
||||
if (CLogMgt.isLevelFine())
|
||||
s_log.fine("M_Warehouse_ID=" + M_Warehouse_ID + ", M_Locator_ID=" + M_Locator_ID
|
||||
+ ",M_Product_ID=" + M_Product_ID + " = " + retValue);
|
||||
return retValue;
|
||||
} // getQtyAvailable
|
||||
|
||||
/**************************************************************************
|
||||
* Persistency Constructor
|
||||
|
|
|
@ -29,7 +29,7 @@ public class X_AD_ClientInfo extends PO implements I_AD_ClientInfo, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20100614L;
|
||||
private static final long serialVersionUID = 20100622L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_AD_ClientInfo (Properties ctx, int AD_ClientInfo_ID, String trxName)
|
||||
|
@ -433,6 +433,34 @@ public class X_AD_ClientInfo extends PO implements I_AD_ClientInfo, I_Persistent
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
public I_C_UOM getC_UOM_Weight() throws RuntimeException
|
||||
{
|
||||
return (I_C_UOM)MTable.get(getCtx(), I_C_UOM.Table_Name)
|
||||
.getPO(getC_UOM_Weight_ID(), get_TrxName()); }
|
||||
|
||||
/** Set UOM for Weight.
|
||||
@param C_UOM_Weight_ID
|
||||
Standard Unit of Measure for Weight
|
||||
*/
|
||||
public void setC_UOM_Weight_ID (int C_UOM_Weight_ID)
|
||||
{
|
||||
if (C_UOM_Weight_ID < 1)
|
||||
set_Value (COLUMNNAME_C_UOM_Weight_ID, null);
|
||||
else
|
||||
set_Value (COLUMNNAME_C_UOM_Weight_ID, Integer.valueOf(C_UOM_Weight_ID));
|
||||
}
|
||||
|
||||
/** Get UOM for Weight.
|
||||
@return Standard Unit of Measure for Weight
|
||||
*/
|
||||
public int getC_UOM_Weight_ID ()
|
||||
{
|
||||
Integer ii = (Integer)get_Value(COLUMNNAME_C_UOM_Weight_ID);
|
||||
if (ii == null)
|
||||
return 0;
|
||||
return ii.intValue();
|
||||
}
|
||||
|
||||
public I_C_UOM getC_UOM_Volume() throws RuntimeException
|
||||
{
|
||||
return (I_C_UOM)MTable.get(getCtx(), I_C_UOM.Table_Name)
|
||||
|
@ -461,32 +489,28 @@ public class X_AD_ClientInfo extends PO implements I_AD_ClientInfo, I_Persistent
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
public I_C_UOM getC_UOM_Weight() throws RuntimeException
|
||||
{
|
||||
return (I_C_UOM)MTable.get(getCtx(), I_C_UOM.Table_Name)
|
||||
.getPO(getC_UOM_Weight_ID(), get_TrxName()); }
|
||||
|
||||
/** Set UOM for Weight.
|
||||
@param C_UOM_Weight_ID
|
||||
Standard Unit of Measure for Weight
|
||||
/** DeliveryPolicy AD_Reference_ID=53355 */
|
||||
public static final int DELIVERYPOLICY_AD_Reference_ID=53355;
|
||||
/** No Hold = N */
|
||||
public static final String DELIVERYPOLICY_NoHold = "N";
|
||||
/** Strict order = O */
|
||||
public static final String DELIVERYPOLICY_StrictOrder = "O";
|
||||
/** Set Delivery Policy.
|
||||
@param DeliveryPolicy
|
||||
Delivery Policy
|
||||
*/
|
||||
public void setC_UOM_Weight_ID (int C_UOM_Weight_ID)
|
||||
public void setDeliveryPolicy (String DeliveryPolicy)
|
||||
{
|
||||
if (C_UOM_Weight_ID < 1)
|
||||
set_Value (COLUMNNAME_C_UOM_Weight_ID, null);
|
||||
else
|
||||
set_Value (COLUMNNAME_C_UOM_Weight_ID, Integer.valueOf(C_UOM_Weight_ID));
|
||||
|
||||
set_Value (COLUMNNAME_DeliveryPolicy, DeliveryPolicy);
|
||||
}
|
||||
|
||||
/** Get UOM for Weight.
|
||||
@return Standard Unit of Measure for Weight
|
||||
/** Get Delivery Policy.
|
||||
@return Delivery Policy
|
||||
*/
|
||||
public int getC_UOM_Weight_ID ()
|
||||
public String getDeliveryPolicy ()
|
||||
{
|
||||
Integer ii = (Integer)get_Value(COLUMNNAME_C_UOM_Weight_ID);
|
||||
if (ii == null)
|
||||
return 0;
|
||||
return ii.intValue();
|
||||
return (String)get_Value(COLUMNNAME_DeliveryPolicy);
|
||||
}
|
||||
|
||||
/** Set Discount calculated from Line Amounts.
|
||||
|
|
|
@ -29,7 +29,7 @@ public class X_AD_OrgInfo extends PO implements I_AD_OrgInfo, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20100614L;
|
||||
private static final long serialVersionUID = 20100622L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_AD_OrgInfo (Properties ctx, int AD_OrgInfo_ID, String trxName)
|
||||
|
@ -156,6 +156,30 @@ public class X_AD_OrgInfo extends PO implements I_AD_OrgInfo, I_Persistent
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
/** DeliveryPolicy AD_Reference_ID=53355 */
|
||||
public static final int DELIVERYPOLICY_AD_Reference_ID=53355;
|
||||
/** No Hold = N */
|
||||
public static final String DELIVERYPOLICY_NoHold = "N";
|
||||
/** Strict order = O */
|
||||
public static final String DELIVERYPOLICY_StrictOrder = "O";
|
||||
/** Set Delivery Policy.
|
||||
@param DeliveryPolicy
|
||||
Delivery Policy
|
||||
*/
|
||||
public void setDeliveryPolicy (String DeliveryPolicy)
|
||||
{
|
||||
|
||||
set_Value (COLUMNNAME_DeliveryPolicy, DeliveryPolicy);
|
||||
}
|
||||
|
||||
/** Get Delivery Policy.
|
||||
@return Delivery Policy
|
||||
*/
|
||||
public String getDeliveryPolicy ()
|
||||
{
|
||||
return (String)get_Value(COLUMNNAME_DeliveryPolicy);
|
||||
}
|
||||
|
||||
public I_M_Warehouse getDropShip_Warehouse() throws RuntimeException
|
||||
{
|
||||
return (I_M_Warehouse)MTable.get(getCtx(), I_M_Warehouse.Table_Name)
|
||||
|
|
|
@ -33,7 +33,7 @@ public class X_C_OrderLine extends PO implements I_C_OrderLine, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20100614L;
|
||||
private static final long serialVersionUID = 20100622L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_C_OrderLine (Properties ctx, int C_OrderLine_ID, String trxName)
|
||||
|
@ -998,6 +998,26 @@ public class X_C_OrderLine extends PO implements I_C_OrderLine, I_Persistent
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Set Qty Allocated.
|
||||
@param QtyAllocated
|
||||
Allocated quantity
|
||||
*/
|
||||
public void setQtyAllocated (BigDecimal QtyAllocated)
|
||||
{
|
||||
set_Value (COLUMNNAME_QtyAllocated, QtyAllocated);
|
||||
}
|
||||
|
||||
/** Get Qty Allocated.
|
||||
@return Allocated quantity
|
||||
*/
|
||||
public BigDecimal getQtyAllocated ()
|
||||
{
|
||||
BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_QtyAllocated);
|
||||
if (bd == null)
|
||||
return Env.ZERO;
|
||||
return bd;
|
||||
}
|
||||
|
||||
/** Set Delivered Quantity.
|
||||
@param QtyDelivered
|
||||
Delivered Quantity
|
||||
|
|
|
@ -32,7 +32,7 @@ public class X_M_Storage extends PO implements I_M_Storage, I_Persistent
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 20100614L;
|
||||
private static final long serialVersionUID = 20100622L;
|
||||
|
||||
/** Standard Constructor */
|
||||
public X_M_Storage (Properties ctx, int M_Storage_ID, String trxName)
|
||||
|
@ -178,6 +178,26 @@ public class X_M_Storage extends PO implements I_M_Storage, I_Persistent
|
|||
return ii.intValue();
|
||||
}
|
||||
|
||||
/** Set Qty Allocated.
|
||||
@param QtyAllocated
|
||||
Allocated quantity
|
||||
*/
|
||||
public void setQtyAllocated (BigDecimal QtyAllocated)
|
||||
{
|
||||
set_Value (COLUMNNAME_QtyAllocated, QtyAllocated);
|
||||
}
|
||||
|
||||
/** Get Qty Allocated.
|
||||
@return Allocated quantity
|
||||
*/
|
||||
public BigDecimal getQtyAllocated ()
|
||||
{
|
||||
BigDecimal bd = (BigDecimal)get_Value(COLUMNNAME_QtyAllocated);
|
||||
if (bd == null)
|
||||
return Env.ZERO;
|
||||
return bd;
|
||||
}
|
||||
|
||||
/** Set On Hand Quantity.
|
||||
@param QtyOnHand
|
||||
On Hand Quantity
|
||||
|
|
|
@ -24,13 +24,17 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.process.AllocateSalesOrders;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MClientInfo;
|
||||
import org.compiere.model.MInOut;
|
||||
import org.compiere.model.MInOutLine;
|
||||
import org.compiere.model.MOrder;
|
||||
import org.compiere.model.MOrderLine;
|
||||
import org.compiere.model.MOrgInfo;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MStorage;
|
||||
import org.compiere.model.MWarehouse;
|
||||
import org.compiere.util.AdempiereUserError;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
|
@ -75,6 +79,11 @@ public class InOutGenerate extends SvrProcess
|
|||
/** The Query sql */
|
||||
private String m_sql = null;
|
||||
|
||||
/** Strict order flag */
|
||||
private boolean m_strictOrder = false;
|
||||
|
||||
/** Warehouse */
|
||||
private MWarehouse m_warehouse;
|
||||
|
||||
/** Storages temp space */
|
||||
private HashMap<SParameter,MStorage[]> m_map = new HashMap<SParameter,MStorage[]>();
|
||||
|
@ -89,6 +98,7 @@ public class InOutGenerate extends SvrProcess
|
|||
*/
|
||||
protected void prepare()
|
||||
{
|
||||
|
||||
ProcessInfoParameter[] para = getParameter();
|
||||
for (int i = 0; i < para.length; i++)
|
||||
{
|
||||
|
@ -125,6 +135,8 @@ public class InOutGenerate extends SvrProcess
|
|||
if (!DocAction.ACTION_Complete.equals(p_docAction))
|
||||
p_docAction = DocAction.ACTION_Prepare;
|
||||
}
|
||||
|
||||
|
||||
} // prepare
|
||||
|
||||
/**
|
||||
|
@ -144,6 +156,11 @@ public class InOutGenerate extends SvrProcess
|
|||
if (p_M_Warehouse_ID == 0)
|
||||
throw new AdempiereUserError("@NotFound@ @M_Warehouse_ID@");
|
||||
|
||||
// Get client info for warehouse
|
||||
m_warehouse = new MWarehouse(this.getCtx(), p_M_Warehouse_ID, this.get_TrxName());
|
||||
MOrgInfo orgInfo = MOrgInfo.get(getCtx(), m_warehouse.getAD_Org_ID(), get_TrxName());
|
||||
m_strictOrder = MClientInfo.DELIVERY_POLICY_STRICT_ORDER.equalsIgnoreCase(orgInfo.getDeliveryPolicy());
|
||||
|
||||
if (p_Selection) // VInOutGen
|
||||
{
|
||||
m_sql = "SELECT C_Order.* FROM C_Order, T_Selection "
|
||||
|
@ -164,6 +181,10 @@ public class InOutGenerate extends SvrProcess
|
|||
// Open Order Lines with Warehouse
|
||||
+ " AND EXISTS (SELECT * FROM C_OrderLine ol "
|
||||
+ "WHERE ol.M_Warehouse_ID=?"; // #1
|
||||
// And the lines have allocated stock
|
||||
if (m_strictOrder) {
|
||||
m_sql += " AND (ol.qtyAllocated>0 OR (SELECT IsShippable(ol.M_Product_ID))='N')";
|
||||
}
|
||||
if (p_DatePromised != null)
|
||||
m_sql += " AND TRUNC(ol.DatePromised)<=?"; // #2
|
||||
m_sql += " AND o.C_Order_ID=ol.C_Order_ID AND ol.QtyOrdered<>ol.QtyDelivered)";
|
||||
|
@ -229,6 +250,10 @@ public class InOutGenerate extends SvrProcess
|
|||
if (p_DatePromised != null)
|
||||
where += " AND (TRUNC(DatePromised)<=" + DB.TO_DATE(p_DatePromised, true)
|
||||
+ " OR DatePromised IS NULL)";
|
||||
// Strict order
|
||||
if (m_strictOrder) {
|
||||
where += " AND (QtyAllocated>0 OR (SELECT IsShippable(M_Product_ID))='N')";
|
||||
}
|
||||
// Exclude Auto Delivery if not Force
|
||||
if (!MOrder.DELIVERYRULE_Force.equals(order.getDeliveryRule()))
|
||||
where += " AND (C_OrderLine.M_Product_ID IS NULL"
|
||||
|
@ -251,6 +276,9 @@ public class InOutGenerate extends SvrProcess
|
|||
BigDecimal onHand = Env.ZERO;
|
||||
BigDecimal toDeliver = line.getQtyOrdered()
|
||||
.subtract(line.getQtyDelivered());
|
||||
|
||||
BigDecimal qtyAllocated = (BigDecimal)line.getQtyAllocated();
|
||||
|
||||
MProduct product = line.getProduct();
|
||||
// Nothing to Deliver
|
||||
if (product != null && toDeliver.signum() == 0)
|
||||
|
@ -305,13 +333,14 @@ public class InOutGenerate extends SvrProcess
|
|||
MStorage storage = storages[j];
|
||||
onHand = onHand.add(storage.getQtyOnHand());
|
||||
}
|
||||
boolean fullLine = onHand.compareTo(toDeliver) >= 0
|
||||
|| toDeliver.signum() < 0;
|
||||
boolean fullLine = m_strictOrder ? (qtyAllocated.compareTo(toDeliver)>=0 || toDeliver.signum() < 0)
|
||||
: (onHand.compareTo(toDeliver) >= 0 || toDeliver.signum() < 0);
|
||||
|
||||
// Complete Order
|
||||
if (completeOrder && !fullLine)
|
||||
{
|
||||
log.fine("Failed CompleteOrder - OnHand=" + onHand
|
||||
+ " Allocated=" + qtyAllocated
|
||||
+ " (Unconfirmed=" + unconfirmedShippedQty
|
||||
+ "), ToDeliver=" + toDeliver + " - " + line);
|
||||
completeOrder = false;
|
||||
|
@ -328,10 +357,10 @@ public class InOutGenerate extends SvrProcess
|
|||
}
|
||||
// Availability
|
||||
else if (MOrder.DELIVERYRULE_Availability.equals(order.getDeliveryRule())
|
||||
&& (onHand.signum() > 0
|
||||
&& (onHand.signum() > 0 && ((m_strictOrder && qtyAllocated.signum() > 0) || !m_strictOrder)
|
||||
|| toDeliver.signum() < 0))
|
||||
{
|
||||
BigDecimal deliver = toDeliver;
|
||||
BigDecimal deliver = m_strictOrder ? qtyAllocated : toDeliver;
|
||||
if (deliver.compareTo(onHand) > 0)
|
||||
deliver = onHand;
|
||||
log.fine("Available - OnHand=" + onHand
|
||||
|
@ -372,7 +401,11 @@ public class InOutGenerate extends SvrProcess
|
|||
if (line.getM_Warehouse_ID() != p_M_Warehouse_ID)
|
||||
continue;
|
||||
MProduct product = line.getProduct();
|
||||
BigDecimal toDeliver = line.getQtyOrdered().subtract(line.getQtyDelivered());
|
||||
BigDecimal toDeliver;
|
||||
if (m_strictOrder && product.isStocked())
|
||||
toDeliver = (BigDecimal)line.getQtyAllocated();
|
||||
else
|
||||
toDeliver = line.getQtyOrdered().subtract(line.getQtyDelivered());
|
||||
//
|
||||
MStorage[] storages = null;
|
||||
if (product != null && product.isStocked())
|
||||
|
|
|
@ -160,6 +160,7 @@ public class M_Production_Run extends SvrProcess {
|
|||
MovementQty,
|
||||
Env.ZERO,
|
||||
Env.ZERO,
|
||||
Env.ZERO,
|
||||
get_TrxName()))
|
||||
{
|
||||
raiseError("Cannot correct Inventory", "");
|
||||
|
|
|
@ -17,16 +17,24 @@
|
|||
package org.compiere.process;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MLocator;
|
||||
import org.compiere.model.MMovement;
|
||||
import org.compiere.model.MMovementLine;
|
||||
import org.compiere.model.MProduct;
|
||||
import org.compiere.model.MRefList;
|
||||
import org.compiere.model.MStorage;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
|
||||
|
@ -98,15 +106,18 @@ public class StorageCleanup extends SvrProcess
|
|||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
int lines = 0;
|
||||
int allocationLines = 0;
|
||||
try
|
||||
{
|
||||
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||
/** pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||
pstmt.setInt(1, Env.getAD_Client_ID(getCtx()));
|
||||
rs = pstmt.executeQuery ();
|
||||
while (rs.next ())
|
||||
{
|
||||
lines += move (new MStorage(getCtx(), rs, get_TrxName()));
|
||||
}
|
||||
} */
|
||||
// Clean up allocations
|
||||
allocationLines = cleanupAllocations();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -114,13 +125,125 @@ public class StorageCleanup extends SvrProcess
|
|||
}
|
||||
finally
|
||||
{
|
||||
DB.close(rs, pstmt);
|
||||
// DB.close(rs, pstmt);
|
||||
rs = null; pstmt = null;
|
||||
}
|
||||
|
||||
return "#" + lines;
|
||||
return "#" + lines + ", # " + allocationLines + " cleared allocations.";
|
||||
} // doIt
|
||||
|
||||
/**
|
||||
* This method cleans up allocations in storages. Currently it only cleans up allocations
|
||||
* of products where no product is reserved. If there are storages with more than 0 items
|
||||
* allocated of a specific product and nothing is reserved then the storages' allocation
|
||||
* is set to zero.
|
||||
*/
|
||||
private int cleanupAllocations() throws Exception {
|
||||
|
||||
// TODO: Fix this method. It must be able to both clean up allocations that should
|
||||
// be zero and storages that are "over allocated".
|
||||
|
||||
// Find all allocations that should be zero
|
||||
|
||||
String query = "SELECT M_Product_ID, M_Warehouse_ID FROM M_Product_Stock_v WHERE " +
|
||||
"(QtyAllocated>0 and " +
|
||||
"(select sum(QtyReserved) from M_Product_Stock_v WHERE M_Product_ID=M_Product_ID and M_Warehouse_ID=M_Warehouse_ID)<=0) " +
|
||||
"OR qtyAllocated<0";
|
||||
Statement stmt = DB.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, get_TrxName());
|
||||
ResultSet rs = null;
|
||||
List<MStorage> storages;
|
||||
int productId, warehouseId;
|
||||
MProduct product;
|
||||
MStorage storage;
|
||||
int adjustmentCounter = 0;
|
||||
/**
|
||||
rs = stmt.executeQuery(query);
|
||||
|
||||
while(rs.next()) {
|
||||
productId = rs.getInt(1);
|
||||
warehouseId = rs.getInt(2);
|
||||
product = new MProduct(getCtx(),productId,get_TrxName());
|
||||
storages = new Query(getCtx(), MStorage.Table_Name, "M_Product_ID=? and (select M_Warehouse_ID from M_Locator where M_Storage.M_Locator_ID=M_Locator_ID) in (?) and QtyAllocated<>0", get_TrxName())
|
||||
.setParameters(new Object[]{productId, warehouseId})
|
||||
.list();
|
||||
// Iterate through storages
|
||||
for (Iterator<MStorage> it = storages.iterator(); it.hasNext();) {
|
||||
storage = it.next();
|
||||
storage.setQtyAllocated(Env.ZERO);
|
||||
storage.saveEx(get_TrxName());
|
||||
log.info("Ajusted allocation for product " + product.getValue() + " " + product.getName());
|
||||
adjustmentCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stmt.close();
|
||||
rs.close();
|
||||
*/
|
||||
BigDecimal allocatedStorage;
|
||||
BigDecimal allocatedOrder;
|
||||
BigDecimal diff;
|
||||
BigDecimal tmpQty;
|
||||
// stmt = DB.createStatement();
|
||||
|
||||
// Find all storages that have more items allocated than what is allocated on order level
|
||||
query = "SELECT M_Product_ID, M_Warehouse_ID, QtyAllocated, get_allocated_on_order(M_Product_ID, M_Warehouse_ID) FROM M_Product_Stock_v WHERE " +
|
||||
"QtyAllocated>(select get_allocated_on_order(M_Product_ID, M_Warehouse_ID))";
|
||||
|
||||
rs = stmt.executeQuery(query);
|
||||
String where = "M_Product_ID=? and (select M_Warehouse_ID from M_Locator where M_Storage.M_Locator_ID=M_Locator_ID) in (?) and QtyAllocated<>0";
|
||||
String q2 = "select * from M_Storage where " + where;
|
||||
ResultSet rs2;
|
||||
PreparedStatement ps;
|
||||
while(rs.next()) {
|
||||
productId = rs.getInt(1);
|
||||
warehouseId = rs.getInt(2);
|
||||
allocatedStorage = rs.getBigDecimal(3);
|
||||
allocatedOrder = rs.getBigDecimal(4);
|
||||
diff = allocatedStorage.subtract(allocatedOrder);
|
||||
product = new MProduct(getCtx(),productId,get_TrxName());
|
||||
|
||||
storages = new Query(getCtx(), MStorage.Table_Name, where , get_TrxName())
|
||||
.setParameters(new Object[]{productId, warehouseId})
|
||||
.list();
|
||||
if (storages.size()==0) {
|
||||
Connection conn = DB.getConnectionRO();
|
||||
ps = conn.prepareStatement(q2);
|
||||
ps.setInt(1, productId);
|
||||
ps.setInt(2, warehouseId);
|
||||
rs2 = ps.executeQuery();
|
||||
storages = new Vector<MStorage>();
|
||||
while(rs2.next()) {
|
||||
storage = new MStorage(getCtx(), rs2, get_TrxName());
|
||||
storages.add(storage);
|
||||
}
|
||||
rs2.close();
|
||||
ps.close();
|
||||
conn.close();
|
||||
}
|
||||
|
||||
// Iterate through storages
|
||||
for (Iterator<MStorage> it = storages.iterator(); it.hasNext() && diff.signum()>0;) {
|
||||
storage = it.next();
|
||||
tmpQty = storage.getQtyAllocated();
|
||||
tmpQty = tmpQty.min(diff);
|
||||
if (tmpQty.signum()!=0) {
|
||||
storage.setQtyAllocated(storage.getQtyAllocated().subtract(tmpQty));
|
||||
storage.saveEx(get_TrxName());
|
||||
// Decrease difference
|
||||
diff = diff.subtract(tmpQty);
|
||||
log.info("Ajusted allocation for product " + product.getValue() + " " + product.getName() + " Changed: " + tmpQty);
|
||||
adjustmentCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DB.close(rs, stmt);
|
||||
return(adjustmentCounter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Move stock to location
|
||||
* @param target target storage
|
||||
|
@ -183,6 +306,7 @@ public class StorageCleanup extends SvrProcess
|
|||
|
||||
/**
|
||||
* Eliminate Reserved/Ordered
|
||||
* Allocation is left untouched.
|
||||
* @param target target Storage
|
||||
*/
|
||||
private void eliminateReservation(MStorage target)
|
||||
|
@ -217,12 +341,12 @@ public class StorageCleanup extends SvrProcess
|
|||
if (MStorage.add(getCtx(), target.getM_Warehouse_ID(), target.getM_Locator_ID(),
|
||||
target.getM_Product_ID(),
|
||||
target.getM_AttributeSetInstance_ID(), target.getM_AttributeSetInstance_ID(),
|
||||
Env.ZERO, reserved.negate(), ordered.negate(), get_TrxName()))
|
||||
Env.ZERO, reserved.negate(), ordered.negate(), Env.ZERO, get_TrxName()))
|
||||
{
|
||||
if (MStorage.add(getCtx(), storage0.getM_Warehouse_ID(), storage0.getM_Locator_ID(),
|
||||
storage0.getM_Product_ID(),
|
||||
storage0.getM_AttributeSetInstance_ID(), storage0.getM_AttributeSetInstance_ID(),
|
||||
Env.ZERO, reserved, ordered, get_TrxName()))
|
||||
Env.ZERO, reserved, ordered, Env.ZERO, get_TrxName()))
|
||||
log.info("Reserved=" + reserved + ",Ordered=" + ordered);
|
||||
else
|
||||
log.warning("Failed Storage0 Update");
|
||||
|
|
|
@ -689,17 +689,13 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
|||
{
|
||||
if (is_ValueChanged(columnName))
|
||||
{
|
||||
final String whereClause = I_DD_Order.COLUMNNAME_DD_Order_ID + "=?";
|
||||
List<MDDOrderLine> lines = new Query (getCtx(), I_DD_OrderLine.Table_Name, whereClause, get_TrxName())
|
||||
.setParameters(getDD_Order_ID())
|
||||
.list();
|
||||
|
||||
for (MDDOrderLine line : lines)
|
||||
{
|
||||
line.set_ValueOfColumn(columnName, get_Value(columnName));
|
||||
line.saveEx();
|
||||
log.fine(columnName + " Lines -> #" + get_Value(columnName));
|
||||
}
|
||||
String sql = "UPDATE DD_OrderLine ol"
|
||||
+ " SET " + columnName + " ="
|
||||
+ "(SELECT " + columnName
|
||||
+ " FROM DD_Order o WHERE ol.DD_Order_ID=o.DD_Order_ID) "
|
||||
+ "WHERE DD_Order_ID=" + getDD_Order_ID();
|
||||
int no = DB.executeUpdate(sql, get_TrxName());
|
||||
log.fine(columnName + " Lines -> #" + no);
|
||||
}
|
||||
} // afterSaveSync
|
||||
|
||||
|
@ -844,6 +840,7 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
|||
|
||||
/**
|
||||
* Reserve Inventory.
|
||||
* No allocation is done.
|
||||
* Counterpart: MMovement.completeIt()
|
||||
* @param lines distribution order lines (ordered by M_Product_ID for deadlock prevention)
|
||||
* @return true if (un) reserved
|
||||
|
@ -886,7 +883,7 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
|||
if (!MStorage.add(getCtx(), locator_to.getM_Warehouse_ID(), locator_to.getM_Locator_ID(),
|
||||
line.getM_Product_ID(),
|
||||
line.getM_AttributeSetInstance_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
Env.ZERO, Env.ZERO , reserved_ordered , get_TrxName()))
|
||||
Env.ZERO, Env.ZERO , reserved_ordered , Env.ZERO, get_TrxName()))
|
||||
{
|
||||
throw new AdempiereException();
|
||||
}
|
||||
|
@ -894,7 +891,7 @@ public class MDDOrder extends X_DD_Order implements DocAction
|
|||
if (!MStorage.add(getCtx(), locator_from.getM_Warehouse_ID(), locator_from.getM_Locator_ID(),
|
||||
line.getM_Product_ID(),
|
||||
line.getM_AttributeSetInstanceTo_ID(), line.getM_AttributeSetInstance_ID(),
|
||||
Env.ZERO, reserved_ordered, Env.ZERO , get_TrxName()))
|
||||
Env.ZERO, reserved_ordered, Env.ZERO , Env.ZERO, get_TrxName()))
|
||||
{
|
||||
throw new AdempiereException();
|
||||
}
|
||||
|
|
|
@ -469,7 +469,7 @@ public class Match
|
|||
sLine.getM_Locator_ID(),
|
||||
sLine.getM_Product_ID(),
|
||||
sLine.getM_AttributeSetInstance_ID(), oLine.getM_AttributeSetInstance_ID(),
|
||||
null, null, qty.negate(), trxName);
|
||||
null, null, qty.negate(), Env.ZERO, trxName);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/************************************************************************
|
||||
* Function Is_InOut_Candidate_Order - Return Y or N depending if
|
||||
* this order can be shipped or not.
|
||||
* Delivery Policy, Shipping rule etc is considered.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_order
|
||||
(
|
||||
p_order_id IN NUMBER
|
||||
)
|
||||
RETURN CHAR AS
|
||||
|
||||
v_lines_ready NUMBER;
|
||||
v_lines_total NUMBER;
|
||||
v_deliveryRule CHAR;
|
||||
BEGIN
|
||||
|
||||
-- Get order info
|
||||
-- Only orders that are complete, not delivered, delivery rule anything else than manual and is a sales order
|
||||
-- can be inout candidates
|
||||
select DeliveryRule INTO v_deliveryRule FROM C_Order WHERE
|
||||
c_order_id=p_order_id AND
|
||||
docstatus = 'CO' AND
|
||||
isdelivered = 'N' AND
|
||||
deliveryrule <> 'M' AND
|
||||
(c_doctype_id IN ( SELECT c_doctype.c_doctype_id FROM c_doctype
|
||||
WHERE c_doctype.docbasetype = 'SOO' AND c_doctype.docsubtypeso NOT IN('ON','OB','WR')));
|
||||
|
||||
IF v_deliveryRule IS NULL THEN
|
||||
RETURN 'N';
|
||||
END IF;
|
||||
|
||||
IF v_deliveryRule='F' THEN RETURN 'Y'; END IF; -- Force
|
||||
|
||||
-- Check lines
|
||||
SELECT sum(is_inout_candidate_orderline(c_orderline_id)), sum(1)
|
||||
INTO v_lines_ready, v_lines_total
|
||||
FROM c_orderline where c_order_id=p_order_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF v_lines_ready > 0 THEN RETURN 'Y'; END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_lines_ready > 0 THEN RETURN 'Y'; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_lines_ready = v_lines_total THEN RETURN 'Y'; END IF;
|
||||
END CASE;
|
||||
|
||||
return 'N';
|
||||
END;
|
||||
/
|
|
@ -0,0 +1,128 @@
|
|||
/************************************************************************
|
||||
* Function Is_InOut_Candidate_OrderLine - Return Y or N depending if
|
||||
* order line can be shipped or not.
|
||||
* Delivery Policy, Shipping rule etc is considered.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_orderline
|
||||
(
|
||||
c_order_line_id IN NUMBER
|
||||
)
|
||||
RETURN NUMBER AS
|
||||
|
||||
v_qtyordered NUMBER;
|
||||
v_qtydelivered NUMBER;
|
||||
v_qtyallocated NUMBER;
|
||||
v_qtyonhand NUMBER;
|
||||
v_qtytodeliver NUMBER;
|
||||
v_qtyreserved NUMBER;
|
||||
v_order_id NUMBER;
|
||||
v_inoutExists NUMBER;
|
||||
v_warehouse_id NUMBER;
|
||||
v_product_id NUMBER;
|
||||
v_orderReady NUMBER;
|
||||
v_isShippable CHAR;
|
||||
v_deliveryRule CHAR;
|
||||
v_deliveryPolicy CHAR;
|
||||
v_return CHAR;
|
||||
|
||||
BEGIN
|
||||
SELECT qtyordered, qtydelivered, qtyallocated, qtyreserved, c_order_id,
|
||||
get_delivery_policy(m_warehouse_id), isshippable(m_product_id),
|
||||
m_warehouse_id, m_product_id
|
||||
INTO
|
||||
v_qtyordered, v_qtydelivered, v_qtyallocated, v_qtyreserved, v_order_id,
|
||||
v_deliveryPolicy, v_isShippable,
|
||||
v_warehouse_id, v_product_id
|
||||
FROM
|
||||
C_OrderLine where C_OrderLine_ID=c_order_line_id;
|
||||
|
||||
-- If all is already delivered then it's not a candidate
|
||||
IF v_qtyordered = v_qtydelivered THEN
|
||||
-- RAISE NOTICE 'All is delivered';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Non shippable (ie non physical items) are always inout candidate
|
||||
IF v_isShippable='N' THEN
|
||||
-- RAISE NOTICE 'Non physical item, always deliverable';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
|
||||
SELECT 1 INTO v_inoutExists FROM m_inoutline iol
|
||||
JOIN m_inout io ON iol.m_inout_id = io.m_inout_id
|
||||
WHERE iol.c_orderline_id = c_order_line_id AND (io.docstatus IN ('IP', 'WC', 'IN'));
|
||||
|
||||
-- If an in-out line is in progress this is not a candidate
|
||||
IF v_inoutExists = 1 THEN
|
||||
-- RAISE NOTICE 'Already being shipped';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Check delivery rule
|
||||
SELECT DeliveryRule INTO
|
||||
v_deliveryRule
|
||||
FROM
|
||||
C_Order where C_Order_ID=v_order_id;
|
||||
|
||||
IF v_deliveryRule='F' THEN
|
||||
-- RAISE NOTICE 'Delivery rule = Force';
|
||||
RETURN 1;
|
||||
END IF; -- Force
|
||||
|
||||
v_qtytodeliver := v_qtyordered - v_qtydelivered;
|
||||
IF v_qtytodeliver = 0 THEN
|
||||
-- RAISE NOTICE 'Nothing to deliver';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'O' THEN -- Deliver in strict order, compare with qty allocated
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = Strict order';
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF v_qtytodeliver = v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Quantity to deliver = qty allocated';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver > v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Not enough allocated for complete order';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyallocated > 0 THEN
|
||||
-- RAISE NOTICE 'Something to deliver';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
END CASE;
|
||||
-- RAISE NOTICE 'No inout candidate';
|
||||
RETURN 0;
|
||||
|
||||
END;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'N' THEN -- No hold, only compare with on hand
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = No hold';
|
||||
SELECT qtyonhand INTO
|
||||
v_qtyonhand
|
||||
FROM m_product_stock_v
|
||||
WHERE M_Product_ID=v_product_id AND M_Warehouse_ID=v_warehouse_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF (v_qtytodeliver = v_qtyreserved AND v_qtytodeliver <= v_qtyonhand) THEN RETURN 1; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver < v_qtyreserved OR v_qtytodeliver >= v_qtyonhand THEN RETURN 0; END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyonhand > 0 THEN RETURN 1; END IF;
|
||||
END CASE;
|
||||
END;
|
||||
END IF;
|
||||
|
||||
-- RAISE NOTICE 'Default answer, something to deliver';
|
||||
return 1;
|
||||
END;
|
||||
/
|
|
@ -0,0 +1,24 @@
|
|||
/************************************************************************
|
||||
* Function Get_Allocated_On_Order - Return number of allocated products
|
||||
* of the specific product in the given warehouse.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION get_allocated_on_order
|
||||
(
|
||||
p_product_id IN NUMBER,
|
||||
p_warehouse_id IN NUMBER)
|
||||
RETURN NUMBER AS
|
||||
|
||||
v_sum NUMBER;
|
||||
|
||||
BEGIN
|
||||
-- Get Product Attribute Set Instance
|
||||
SELECT sum(qtyallocated) into v_sum from C_OrderLine ol
|
||||
JOIN C_Order o on (o.C_Order_ID=ol.C_Order_ID)
|
||||
WHERE
|
||||
M_Product_ID=p_product_id AND
|
||||
COALESCE(ol.M_Warehouse_ID, o.M_Warehouse_ID)=p_warehouse_id;
|
||||
|
||||
RETURN v_sum;
|
||||
END get_allocated_on_order;
|
||||
/
|
|
@ -0,0 +1,27 @@
|
|||
/************************************************************************
|
||||
* Function Get_Delivery_Policy - Return delivery policy of warehouse
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION get_delivery_policy
|
||||
(
|
||||
warehouse_id IN NUMBER
|
||||
)
|
||||
RETURN CHAR AS
|
||||
v_orgId NUMBER;
|
||||
v_clientId NUMBER;
|
||||
v_return CHAR;
|
||||
BEGIN
|
||||
SELECT ad_client_id, ad_org_id INTO
|
||||
v_clientId, v_orgId FROM
|
||||
M_Warehouse WHERE M_Warehouse_ID=warehouse_id;
|
||||
|
||||
SELECT COALESCE(ad_orginfo.deliverypolicy, ad_clientinfo.deliverypolicy) INTO
|
||||
v_return
|
||||
FROM AD_ClientInfo
|
||||
JOIN AD_OrgInfo ON (AD_ClientInfo.AD_Client_ID=AD_OrgInfo.AD_Client_ID)
|
||||
WHERE AD_ClientInfo.AD_Client_ID = v_clientId AND
|
||||
AD_OrgInfo.AD_Org_ID = v_orgId;
|
||||
|
||||
return v_return;
|
||||
END get_delivery_policy;
|
||||
/
|
|
@ -0,0 +1,32 @@
|
|||
/************************************************************************
|
||||
* Function IsShippable - Return Y or N depending if this is a physical
|
||||
* 'shippable' product or not.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION isshippable
|
||||
(
|
||||
product_id IN NUMBER
|
||||
)
|
||||
RETURN CHAR AS
|
||||
v_IsStocked CHAR;
|
||||
v_IsBom CHAR;
|
||||
v_ProductType CHAR;
|
||||
v_return CHAR;
|
||||
BEGIN
|
||||
IF product_id = NULL THEN
|
||||
return 'N';
|
||||
END IF;
|
||||
|
||||
SELECT IsStocked, IsBom, ProductType
|
||||
INTO v_IsStocked, v_IsBom, v_ProductType
|
||||
FROM M_Product WHERE M_Product_ID=product_id;
|
||||
|
||||
IF (v_IsStocked='Y' AND v_ProductType='I' AND v_IsBom='N') THEN
|
||||
v_return := 'Y';
|
||||
ELSE
|
||||
v_return := 'N';
|
||||
END IF;
|
||||
|
||||
return v_return;
|
||||
END isshippable;
|
||||
/
|
|
@ -1,37 +1,26 @@
|
|||
CREATE OR REPLACE VIEW M_INOUT_CANDIDATE_V
|
||||
(AD_CLIENT_ID, AD_ORG_ID, C_BPARTNER_ID, C_ORDER_ID, DOCUMENTNO,
|
||||
DATEORDERED, C_DOCTYPE_ID, POREFERENCE, DESCRIPTION, SALESREP_ID,
|
||||
M_WAREHOUSE_ID, TOTALLINES)
|
||||
AS
|
||||
CREATE OR REPLACE VIEW m_inout_candidate_v AS
|
||||
SELECT
|
||||
o.AD_Client_ID, o.AD_Org_ID, o.C_BPartner_ID, o.C_Order_ID,
|
||||
o.DocumentNo, o.DateOrdered, o.C_DocType_ID,
|
||||
o.POReference, o.Description, o.SalesRep_ID,
|
||||
l.M_Warehouse_ID,
|
||||
SUM((l.QtyOrdered-l.QtyDelivered)*l.PriceActual) AS TotalLines
|
||||
FROM C_Order o
|
||||
INNER JOIN C_OrderLine l ON (o.C_Order_ID=l.C_Order_ID)
|
||||
WHERE (o.DocStatus = 'CO' AND o.IsDelivered='N') -- Status must be CO - not CL/RE
|
||||
-- not Offers and open Walkin-Receipts
|
||||
AND o.C_DocType_ID IN (SELECT C_DocType_ID FROM C_DocType
|
||||
WHERE DocBaseType='SOO' AND DocSubTypeSO NOT IN ('ON','OB','WR'))
|
||||
-- Delivery Rule - not manual
|
||||
AND o.DeliveryRule<>'M'
|
||||
AND (l.M_Product_ID IS NULL OR EXISTS
|
||||
(SELECT * FROM M_Product p
|
||||
WHERE l.M_Product_ID=p.M_Product_ID AND p.IsExcludeAutoDelivery='N'))
|
||||
-- we need to ship
|
||||
AND l.QtyOrdered <> l.QtyDelivered
|
||||
AND o.IsDropShip='N'
|
||||
AND (l.M_Product_ID IS NOT NULL OR l.C_Charge_ID IS NOT NULL)
|
||||
-- Not confirmed shipment
|
||||
AND NOT EXISTS (SELECT * FROM M_InOutLine iol
|
||||
INNER JOIN M_InOut io ON (iol.M_InOut_ID=io.M_InOut_ID)
|
||||
WHERE iol.C_OrderLine_ID=l.C_OrderLine_ID AND io.DocStatus IN ('IP','WC'))
|
||||
--
|
||||
GROUP BY o.AD_Client_ID, o.AD_Org_ID, o.C_BPartner_ID, o.C_Order_ID,
|
||||
o.DocumentNo, o.DateOrdered, o.C_DocType_ID,
|
||||
o.POReference, o.Description, o.SalesRep_ID, l.M_Warehouse_ID;
|
||||
o.ad_client_id,
|
||||
o.ad_org_id,
|
||||
o.c_bpartner_id,
|
||||
o.c_order_id,
|
||||
o.documentno,
|
||||
o.dateordered,
|
||||
o.c_doctype_id,
|
||||
o.poreference,
|
||||
o.description,
|
||||
o.salesrep_id,
|
||||
l.m_warehouse_id,
|
||||
sum((l.qtyordered - l.qtydelivered) * l.priceactual) AS totallines
|
||||
|
||||
FROM c_order o
|
||||
JOIN c_orderline l ON o.c_order_id = l.c_order_id
|
||||
WHERE
|
||||
(l.m_product_id IS NULL OR (EXISTS ( SELECT 1
|
||||
FROM m_product p
|
||||
WHERE l.m_product_id = p.m_product_id AND p.isexcludeautodelivery = 'N'))) AND
|
||||
(l.m_product_id IS NOT NULL OR l.c_charge_id IS NOT NULL) AND
|
||||
is_inout_candidate_order(o.c_order_id) = 'Y'
|
||||
|
||||
GROUP BY o.ad_client_id, o.ad_org_id, o.c_bpartner_id, o.c_order_id, o.documentno, o.dateordered, o.c_doctype_id, o.poreference, o.description, o.salesrep_id, l.m_warehouse_id;
|
||||
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
--create views
|
||||
CREATE OR REPLACE VIEW M_PRODUCT_STOCK_V
|
||||
AS
|
||||
SELECT
|
||||
ms.IsActive, ms.Created, ms.CreatedBy, ms.Updated, ms.UpdatedBy,
|
||||
mp.VALUE, mp.help, (ms.qtyonhand - ms.qtyreserved) AS qtyavailable, ms.qtyonhand,
|
||||
ms.qtyreserved, mp.description, mw.NAME AS warehouse, mw.m_warehouse_id, mw.ad_client_id,
|
||||
mw.ad_org_id, mp.documentnote
|
||||
FROM M_STORAGE ms
|
||||
JOIN M_PRODUCT mp ON ms.m_product_id = mp.m_product_id
|
||||
JOIN M_LOCATOR ml ON ms.m_locator_id = ml.m_locator_id
|
||||
JOIN M_WAREHOUSE mw ON ml.m_warehouse_id = mw.m_warehouse_id
|
||||
ORDER BY mw.NAME;
|
||||
CREATE OR REPLACE VIEW m_product_stock_v AS
|
||||
SELECT ms.isactive, ms.created, ms.createdby, ms.updated, ms.updatedby,
|
||||
ms.m_product_id, mp.value, mp.name, mp.help,
|
||||
ms.qtyonhand - ms.qtyreserved AS qtyavailable,
|
||||
ms.qtyonhand, ms.qtyreserved,
|
||||
ms.qtyallocated,
|
||||
mp.description,
|
||||
mw.name AS warehouse,
|
||||
mw.m_warehouse_id,
|
||||
mw.ad_client_id,
|
||||
mw.ad_org_id,
|
||||
mp.documentnote
|
||||
FROM m_storage ms
|
||||
JOIN m_product mp ON ms.m_product_id = mp.m_product_id
|
||||
JOIN m_locator ml ON ms.m_locator_id = ml.m_locator_id
|
||||
JOIN m_warehouse mw ON ml.m_warehouse_id = mw.m_warehouse_id
|
||||
ORDER BY mw.name;
|
|
@ -0,0 +1,49 @@
|
|||
/************************************************************************
|
||||
* Function Is_InOut_Candidate_Order - Return Y or N depending if
|
||||
* this order can be shipped or not.
|
||||
* Delivery Policy, Shipping rule etc is considered.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_order(p_order_id numeric)
|
||||
RETURNS character AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_lines_ready numeric;
|
||||
v_lines_total numeric;
|
||||
v_deliveryRule character(1);
|
||||
BEGIN
|
||||
|
||||
-- Get order info
|
||||
-- Only orders that are complete, not delivered, delivery rule anything else than manual and is a sales order
|
||||
-- can be inout candidates
|
||||
select DeliveryRule INTO v_deliveryRule FROM C_Order WHERE
|
||||
c_order_id=p_order_id AND
|
||||
docstatus = 'CO'::bpchar AND
|
||||
isdelivered = 'N'::bpchar AND
|
||||
deliveryrule <> 'M'::bpchar AND
|
||||
(c_doctype_id IN ( SELECT c_doctype.c_doctype_id FROM c_doctype
|
||||
WHERE c_doctype.docbasetype = 'SOO'::bpchar AND (c_doctype.docsubtypeso <> ALL (ARRAY['ON'::bpchar, 'OB'::bpchar, 'WR'::bpchar]))));
|
||||
|
||||
IF v_deliveryRule IS NULL THEN
|
||||
RETURN 'N';
|
||||
END IF;
|
||||
|
||||
IF v_deliveryRule='F' THEN RETURN 'Y'; END IF; -- Force
|
||||
|
||||
-- Check lines
|
||||
SELECT sum(is_inout_candidate_orderline(c_orderline_id)), sum(1)
|
||||
INTO v_lines_ready, v_lines_total
|
||||
FROM c_orderline where c_order_id=p_order_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L','A' THEN -- Complete line and Availability
|
||||
IF v_lines_ready > 0 THEN RETURN 'Y'; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_lines_ready = v_lines_total THEN RETURN 'Y'; END IF;
|
||||
END CASE;
|
||||
|
||||
return 'N';
|
||||
END
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
|
@ -0,0 +1,127 @@
|
|||
/************************************************************************
|
||||
* Function Is_InOut_Candidate_OrderLine - Return Y or N depending if
|
||||
* order line can be shipped or not.
|
||||
* Delivery Policy, Shipping rule etc is considered.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_orderline(c_order_line_id numeric)
|
||||
RETURNS numeric AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_qtyordered numeric;
|
||||
v_qtydelivered numeric;
|
||||
v_qtyallocated numeric;
|
||||
v_qtyonhand numeric;
|
||||
v_qtytodeliver numeric;
|
||||
v_qtyreserved numeric;
|
||||
v_order_id numeric;
|
||||
v_inoutExists numeric;
|
||||
v_warehouse_id numeric;
|
||||
v_product_id numeric;
|
||||
v_orderReady numeric;
|
||||
v_isShippable character(1);
|
||||
v_deliveryRule character(1);
|
||||
v_deliveryPolicy character(1);
|
||||
v_return character(1);
|
||||
BEGIN
|
||||
SELECT qtyordered, qtydelivered, qtyallocated, qtyreserved, c_order_id,
|
||||
get_delivery_policy(m_warehouse_id), isshippable(m_product_id),
|
||||
m_warehouse_id, m_product_id
|
||||
INTO
|
||||
v_qtyordered, v_qtydelivered, v_qtyallocated, v_qtyreserved, v_order_id,
|
||||
v_deliveryPolicy, v_isShippable,
|
||||
v_warehouse_id, v_product_id
|
||||
FROM
|
||||
C_OrderLine where C_OrderLine_ID=c_order_line_id;
|
||||
|
||||
-- If all is already delivered then it's not a candidate
|
||||
IF v_qtyordered = v_qtydelivered THEN
|
||||
-- RAISE NOTICE 'All is delivered';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Non shippable (ie non physical items) are always inout candidate
|
||||
IF v_isShippable='N' THEN
|
||||
-- RAISE NOTICE 'Non physical item, always deliverable';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
|
||||
SELECT 1 INTO v_inoutExists FROM m_inoutline iol
|
||||
JOIN m_inout io ON iol.m_inout_id = io.m_inout_id
|
||||
WHERE iol.c_orderline_id = c_order_line_id AND (io.docstatus = ANY (ARRAY['IP'::bpchar, 'WC'::bpchar, 'IN'::bpchar]));
|
||||
|
||||
-- If an in-out line is in progress this is not a candidate
|
||||
IF v_inoutExists = 1 THEN
|
||||
-- RAISE NOTICE 'Already being shipped';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Check delivery rule
|
||||
SELECT DeliveryRule INTO
|
||||
v_deliveryRule
|
||||
FROM
|
||||
C_Order where C_Order_ID=v_order_id;
|
||||
|
||||
IF v_deliveryRule='F' THEN
|
||||
-- RAISE NOTICE 'Delivery rule = Force';
|
||||
RETURN 1;
|
||||
END IF; -- Force
|
||||
|
||||
v_qtytodeliver := v_qtyordered - v_qtydelivered;
|
||||
IF v_qtytodeliver = 0 THEN
|
||||
-- RAISE NOTICE 'Nothing to deliver';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'O' THEN -- Deliver in strict order, compare with qty allocated
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = Strict order';
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF v_qtytodeliver = v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Quantity to deliver = qty allocated';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver > v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Not enough allocated for complete order';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyallocated > 0 THEN
|
||||
-- RAISE NOTICE 'Something to deliver';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
END CASE;
|
||||
-- RAISE NOTICE 'No inout candidate';
|
||||
RETURN 0;
|
||||
|
||||
END;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'N' THEN -- No hold, only compare with on hand
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = No hold';
|
||||
SELECT qtyonhand INTO
|
||||
v_qtyonhand
|
||||
FROM m_product_stock_v
|
||||
WHERE M_Product_ID=v_product_id AND M_Warehouse_ID=v_warehouse_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF (v_qtytodeliver = v_qtyreserved AND v_qtytodeliver <= v_qtyonhand) THEN RETURN 1; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver < v_qtyreserved OR v_qtytodeliver >= v_qtyonhand THEN RETURN 0; END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyonhand > 0 THEN RETURN 1; END IF;
|
||||
END CASE;
|
||||
END;
|
||||
END IF;
|
||||
|
||||
-- RAISE NOTICE 'Default answer, something to deliver';
|
||||
return 1;
|
||||
END
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
|
@ -0,0 +1,26 @@
|
|||
/************************************************************************
|
||||
* Function Get_Allocated_On_Order - Return number of allocated products
|
||||
* of the specific product in the given warehouse.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION get_allocated_on_order(p_product_id numeric, p_warehouse_id numeric)
|
||||
RETURNS numeric AS
|
||||
$BODY$
|
||||
|
||||
DECLARE
|
||||
|
||||
v_sum numeric;
|
||||
|
||||
BEGIN
|
||||
-- Get Product Attribute Set Instance
|
||||
SELECT sum(qtyallocated) into v_sum from C_OrderLine ol
|
||||
JOIN C_Order o on (o.C_Order_ID=ol.C_Order_ID)
|
||||
WHERE
|
||||
M_Product_ID=p_product_id AND
|
||||
COALESCE(ol.M_Warehouse_ID, o.M_Warehouse_ID)=p_warehouse_id;
|
||||
|
||||
RETURN v_sum;
|
||||
END;
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
|
@ -0,0 +1,29 @@
|
|||
/************************************************************************
|
||||
* Function Get_Delivery_Policy - Return delivery policy of warehouse
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION get_delivery_policy(warehouse_id numeric)
|
||||
RETURNS character AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_orgId numeric;
|
||||
v_clientId numeric;
|
||||
v_return character(1);
|
||||
BEGIN
|
||||
SELECT ad_client_id, ad_org_id INTO
|
||||
v_clientId, v_orgId FROM
|
||||
M_Warehouse WHERE M_Warehouse_ID=warehouse_id;
|
||||
|
||||
SELECT COALESCE(ad_orginfo.deliverypolicy, ad_clientinfo.deliverypolicy) INTO
|
||||
v_return
|
||||
FROM AD_ClientInfo
|
||||
JOIN AD_OrgInfo ON (AD_ClientInfo.AD_Client_ID=AD_OrgInfo.AD_Client_ID)
|
||||
WHERE AD_ClientInfo.AD_Client_ID = v_clientId AND
|
||||
AD_OrgInfo.AD_Org_ID = v_orgId;
|
||||
|
||||
return v_return;
|
||||
END;
|
||||
$BODY$
|
||||
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
|
@ -0,0 +1,33 @@
|
|||
/************************************************************************
|
||||
* Function IsShippable - Return Y or N depending if this is a physical
|
||||
* 'shippable' product or not.
|
||||
* Author: Daniel Tamm (usrdno)
|
||||
************************************************************************/
|
||||
CREATE OR REPLACE FUNCTION isshippable(product_id numeric)
|
||||
RETURNS character AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_IsStocked character(1);
|
||||
v_IsBom character(1);
|
||||
v_ProductType character(1);
|
||||
v_return character(1);
|
||||
BEGIN
|
||||
IF product_id = NULL THEN
|
||||
return 'N';
|
||||
END IF;
|
||||
|
||||
SELECT IsStocked, IsBom, ProductType
|
||||
INTO v_IsStocked, v_IsBom, v_ProductType
|
||||
FROM M_Product WHERE M_Product_ID=product_id;
|
||||
|
||||
IF (v_IsStocked='Y' AND v_ProductType='I' AND v_IsBom='N') THEN
|
||||
v_return := 'Y';
|
||||
ELSE
|
||||
v_return := 'N';
|
||||
END IF;
|
||||
|
||||
return v_return;
|
||||
END;
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
|
@ -1,37 +1,28 @@
|
|||
CREATE OR REPLACE VIEW M_INOUT_CANDIDATE_V
|
||||
(AD_CLIENT_ID, AD_ORG_ID, C_BPARTNER_ID, C_ORDER_ID, DOCUMENTNO,
|
||||
DATEORDERED, C_DOCTYPE_ID, POREFERENCE, DESCRIPTION, SALESREP_ID,
|
||||
M_WAREHOUSE_ID, TOTALLINES)
|
||||
AS
|
||||
CREATE OR REPLACE VIEW m_inout_candidate_v AS
|
||||
SELECT
|
||||
o.AD_Client_ID, o.AD_Org_ID, o.C_BPartner_ID, o.C_Order_ID,
|
||||
o.DocumentNo, o.DateOrdered, o.C_DocType_ID,
|
||||
o.POReference, o.Description, o.SalesRep_ID,
|
||||
l.M_Warehouse_ID,
|
||||
SUM((l.QtyOrdered-l.QtyDelivered)*l.PriceActual) AS TotalLines
|
||||
FROM C_Order o
|
||||
INNER JOIN C_OrderLine l ON (o.C_Order_ID=l.C_Order_ID)
|
||||
WHERE (o.DocStatus = 'CO' AND o.IsDelivered='N') -- Status must be CO - not CL/RE
|
||||
-- not Offers and open Walkin-Receipts
|
||||
AND o.C_DocType_ID IN (SELECT C_DocType_ID FROM C_DocType
|
||||
WHERE DocBaseType='SOO' AND DocSubTypeSO NOT IN ('ON','OB','WR'))
|
||||
-- Delivery Rule - not manual
|
||||
AND o.DeliveryRule<>'M'
|
||||
AND (l.M_Product_ID IS NULL OR EXISTS
|
||||
(SELECT * FROM M_Product p
|
||||
WHERE l.M_Product_ID=p.M_Product_ID AND p.IsExcludeAutoDelivery='N'))
|
||||
-- we need to ship
|
||||
AND l.QtyOrdered <> l.QtyDelivered
|
||||
AND o.IsDropShip='N'
|
||||
AND (l.M_Product_ID IS NOT NULL OR l.C_Charge_ID IS NOT NULL)
|
||||
-- Not confirmed shipment
|
||||
AND NOT EXISTS (SELECT * FROM M_InOutLine iol
|
||||
INNER JOIN M_InOut io ON (iol.M_InOut_ID=io.M_InOut_ID)
|
||||
WHERE iol.C_OrderLine_ID=l.C_OrderLine_ID AND io.DocStatus IN ('IP','WC'))
|
||||
--
|
||||
GROUP BY o.AD_Client_ID, o.AD_Org_ID, o.C_BPartner_ID, o.C_Order_ID,
|
||||
o.DocumentNo, o.DateOrdered, o.C_DocType_ID,
|
||||
o.POReference, o.Description, o.SalesRep_ID, l.M_Warehouse_ID;
|
||||
|
||||
o.ad_client_id,
|
||||
o.ad_org_id,
|
||||
o.c_bpartner_id,
|
||||
o.c_order_id,
|
||||
o.documentno,
|
||||
o.dateordered,
|
||||
o.c_doctype_id,
|
||||
o.poreference,
|
||||
o.description,
|
||||
o.salesrep_id,
|
||||
l.m_warehouse_id,
|
||||
sum((l.qtyordered - l.qtydelivered) * l.priceactual) AS totallines
|
||||
|
||||
FROM c_order o
|
||||
JOIN c_orderline l ON o.c_order_id = l.c_order_id
|
||||
WHERE
|
||||
(l.m_product_id IS NULL OR (EXISTS ( SELECT 1
|
||||
FROM m_product p
|
||||
WHERE l.m_product_id = p.m_product_id AND p.isexcludeautodelivery = 'N'::bpchar))) AND
|
||||
(l.m_product_id IS NOT NULL OR l.c_charge_id IS NOT NULL) AND
|
||||
is_inout_candidate_order(o.c_order_id) = 'Y'
|
||||
|
||||
GROUP BY o.ad_client_id, o.ad_org_id, o.c_bpartner_id, o.c_order_id, o.documentno, o.dateordered, o.c_doctype_id, o.poreference, o.description, o.salesrep_id, l.m_warehouse_id;
|
||||
ALTER TABLE m_inout_candidate_v OWNER TO adempiere;
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
--create views
|
||||
CREATE OR REPLACE VIEW M_PRODUCT_STOCK_V
|
||||
AS
|
||||
SELECT
|
||||
ms.IsActive, ms.Created, ms.CreatedBy, ms.Updated, ms.UpdatedBy,
|
||||
mp.VALUE, mp.help, (ms.qtyonhand - ms.qtyreserved) AS qtyavailable, ms.qtyonhand,
|
||||
ms.qtyreserved, mp.description, mw.NAME AS warehouse, mw.m_warehouse_id, mw.ad_client_id,
|
||||
mw.ad_org_id, mp.documentnote
|
||||
FROM M_STORAGE ms
|
||||
JOIN M_PRODUCT mp ON ms.m_product_id = mp.m_product_id
|
||||
JOIN M_LOCATOR ml ON ms.m_locator_id = ml.m_locator_id
|
||||
JOIN M_WAREHOUSE mw ON ml.m_warehouse_id = mw.m_warehouse_id
|
||||
ORDER BY mw.NAME;
|
||||
DROP VIEW IF EXISTS m_product_stock_v;
|
||||
CREATE OR REPLACE VIEW m_product_stock_v AS
|
||||
SELECT ms.isactive, ms.created, ms.createdby, ms.updated, ms.updatedby,
|
||||
ms.m_product_id, mp.value, mp.name, mp.help,
|
||||
ms.qtyonhand - ms.qtyreserved AS qtyavailable,
|
||||
ms.qtyonhand, ms.qtyreserved,
|
||||
ms.qtyallocated,
|
||||
mp.description,
|
||||
mw.name AS warehouse,
|
||||
mw.m_warehouse_id,
|
||||
mw.ad_client_id,
|
||||
mw.ad_org_id,
|
||||
mp.documentnote
|
||||
FROM m_storage ms
|
||||
JOIN m_product mp ON ms.m_product_id = mp.m_product_id
|
||||
JOIN m_locator ml ON ms.m_locator_id = ml.m_locator_id
|
||||
JOIN m_warehouse mw ON ml.m_warehouse_id = mw.m_warehouse_id
|
||||
ORDER BY mw.name;
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
-- 2010-maj-19 14:36:56 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element (AD_Client_ID,AD_Element_ID,AD_Org_ID,ColumnName,Created,CreatedBy,Description,EntityType,Help,IsActive,Name,PrintName,Updated,UpdatedBy) VALUES (0,54156,0,'QtyAllocated',TO_DATE('2010-05-19 14:36:56','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity','D','Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Qty Allocated','Qty Allocated',TO_DATE('2010-05-19 14:36:56','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:36:56 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element_Trl (AD_Language,AD_Element_ID, Description,Help,Name,PO_Description,PO_Help,PO_Name,PO_PrintName,PrintName, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Element_ID, t.Description,t.Help,t.Name,t.PO_Description,t.PO_Help,t.PO_Name,t.PO_PrintName,t.PrintName, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Element t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Element_ID=54156 AND NOT EXISTS (SELECT * FROM AD_Element_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Element_ID=t.AD_Element_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:42:55 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element (AD_Client_ID,AD_Element_ID,AD_Org_ID,ColumnName,Created,CreatedBy,Description,EntityType,Help,IsActive,Name,PrintName,Updated,UpdatedBy) VALUES (0,54157,0,'DeliveryPolicy',TO_DATE('2010-05-19 14:42:55','YYYY-MM-DD HH24:MI:SS'),100,'Delivery Policy','D','The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Delivery Policy','Delivery Policy',TO_DATE('2010-05-19 14:42:55','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:42:55 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element_Trl (AD_Language,AD_Element_ID, Description,Help,Name,PO_Description,PO_Help,PO_Name,PO_PrintName,PrintName, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Element_ID, t.Description,t.Help,t.Name,t.PO_Description,t.PO_Help,t.PO_Name,t.PO_PrintName,t.PrintName, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Element t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Element_ID=54157 AND NOT EXISTS (SELECT * FROM AD_Element_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Element_ID=t.AD_Element_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:43:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Reference (AD_Client_ID,AD_Org_ID,AD_Reference_ID,Created,CreatedBy,Description,EntityType,IsActive,IsOrderByValue,Name,Updated,UpdatedBy,ValidationType) VALUES (0,0,53355,TO_DATE('2010-05-19 14:43:59','YYYY-MM-DD HH24:MI:SS'),100,'List of Delivery Policies','D','Y','N','DeliveryPolicies',TO_DATE('2010-05-19 14:43:59','YYYY-MM-DD HH24:MI:SS'),100,'L')
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:43:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Reference_Trl (AD_Language,AD_Reference_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Reference_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Reference t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Reference_ID=53355 AND NOT EXISTS (SELECT * FROM AD_Reference_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Reference_ID=t.AD_Reference_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:44:40 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List (AD_Client_ID,AD_Org_ID,AD_Reference_ID,AD_Ref_List_ID,Created,CreatedBy,Description,EntityType,IsActive,Name,Updated,UpdatedBy,Value) VALUES (0,0,53355,53581,TO_DATE('2010-05-19 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,'Default delivery policy - deliver as soon as orders are fulfilled according to delivery rule','D','Y','No Hold',TO_DATE('2010-05-19 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,'N')
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:44:40 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List_Trl (AD_Language,AD_Ref_List_ID, Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Ref_List_ID, t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Ref_List t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Ref_List_ID=53581 AND NOT EXISTS (SELECT * FROM AD_Ref_List_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Ref_List_ID=t.AD_Ref_List_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:45:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List (AD_Client_ID,AD_Org_ID,AD_Reference_ID,AD_Ref_List_ID,Created,CreatedBy,Description,EntityType,IsActive,Name,Updated,UpdatedBy,Value) VALUES (0,0,53355,53582,TO_DATE('2010-05-19 14:45:59','YYYY-MM-DD HH24:MI:SS'),100,'Allocate items to orders and fulfill them in strict order.','D','Y','Strict order',TO_DATE('2010-05-19 14:45:59','YYYY-MM-DD HH24:MI:SS'),100,'O')
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:45:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List_Trl (AD_Language,AD_Ref_List_ID, Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Ref_List_ID, t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Ref_List t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Ref_List_ID=53582 AND NOT EXISTS (SELECT * FROM AD_Ref_List_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Ref_List_ID=t.AD_Ref_List_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:47:45 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Table_ID,ColumnName,Created,CreatedBy,DefaultValue,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59188,54156,0,29,260,'QtyAllocated',TO_DATE('2010-05-19 14:47:45','YYYY-MM-DD HH24:MI:SS'),100,'0','Allocated quantity','D',22,'Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Qty Allocated',0,TO_DATE('2010-05-19 14:47:45','YYYY-MM-DD HH24:MI:SS'),100,1.000000000000)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:47:45 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59188 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:48:05 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE C_OrderLine ADD QtyAllocated NUMBER DEFAULT 0
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Table_ID,ColumnName,Created,CreatedBy,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59189,54156,0,29,250,'QtyAllocated',TO_DATE('2010-05-19 14:49:07','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity','D',22,'Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Qty Allocated',0,TO_DATE('2010-05-19 14:49:07','YYYY-MM-DD HH24:MI:SS'),100,1.000000000000)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59189 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:18 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE M_Storage ADD QtyAllocated NUMBER DEFAULT 0
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:28 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Column SET DefaultValue='0',Updated=TO_DATE('2010-05-19 14:49:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=59189
|
||||
;
|
||||
|
||||
|
||||
-- 2010-maj-19 14:54:08 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_FieldGroup_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,Description,DisplayLength,DisplayLogic,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,Updated,UpdatedBy) VALUES (0,59188,102,58877,0,187,TO_DATE('2010-05-19 14:54:08','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity',26,'@OrderType@=''OB'' | @OrderType@=''SO'' | @Processed@=''Y''','D','Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','Y','N','N','N','Y','N','Qty Allocated',190,TO_DATE('2010-05-19 14:54:08','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:08 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58877 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=210,IsDisplayed='Y' WHERE AD_Field_ID=58877
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=220,IsDisplayed='Y' WHERE AD_Field_ID=1135
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=230,IsDisplayed='Y' WHERE AD_Field_ID=10829
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=240,IsDisplayed='Y' WHERE AD_Field_ID=1138
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=250,IsDisplayed='Y' WHERE AD_Field_ID=1137
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=260,IsDisplayed='Y' WHERE AD_Field_ID=2115
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=270,IsDisplayed='Y' WHERE AD_Field_ID=1141
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=280,IsDisplayed='Y' WHERE AD_Field_ID=3124
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=290,IsDisplayed='Y' WHERE AD_Field_ID=12745
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=300,IsDisplayed='Y' WHERE AD_Field_ID=13644
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=310,IsDisplayed='Y' WHERE AD_Field_ID=13645
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=320,IsDisplayed='Y' WHERE AD_Field_ID=13691
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=330,IsDisplayed='Y' WHERE AD_Field_ID=13650
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=340,IsDisplayed='Y' WHERE AD_Field_ID=13651
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=350,IsDisplayed='Y' WHERE AD_Field_ID=2880
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=360,IsDisplayed='Y' WHERE AD_Field_ID=12744
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=370,IsDisplayed='Y' WHERE AD_Field_ID=10332
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:55:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET Name='Allocated Quantity',Updated=TO_DATE('2010-05-19 14:55:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=58877
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:55:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field_Trl SET IsTranslated='N' WHERE AD_Field_ID=58877
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:56:52 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,Description,DisplayLength,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,SortNo,Updated,UpdatedBy) VALUES (0,59189,58878,0,179,TO_DATE('2010-05-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity',26,'D','Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','Y','N','N','N','N','N','Qty Allocated',110,0,TO_DATE('2010-05-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:56:52 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58878 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:57:28 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET Name='Allocated Quantity',Updated=TO_DATE('2010-05-19 14:57:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=58878
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:57:28 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field_Trl SET IsTranslated='N' WHERE AD_Field_ID=58878
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:02:03 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,ColumnName,Created,CreatedBy,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59190,54157,0,17,53355,228,'DeliveryPolicy',TO_DATE('2010-05-19 15:02:03','YYYY-MM-DD HH24:MI:SS'),100,'Delivery Policy','D',1,'The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Delivery Policy',0,TO_DATE('2010-05-19 15:02:03','YYYY-MM-DD HH24:MI:SS'),100,0)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:02:03 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59190 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:02:11 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Column SET Version=1.000000000000,Updated=TO_DATE('2010-05-19 15:02:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=59190
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:02:18 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE AD_OrgInfo ADD DeliveryPolicy CHAR(1) DEFAULT NULL
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:06:47 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,ColumnName,Created,CreatedBy,DefaultValue,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59191,54157,0,17,53355,227,'DeliveryPolicy',TO_DATE('2010-05-19 15:06:46','YYYY-MM-DD HH24:MI:SS'),100,'N','Delivery Policy','D',1,'The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Delivery Policy',0,TO_DATE('2010-05-19 15:06:46','YYYY-MM-DD HH24:MI:SS'),100,1.000000000000)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:06:47 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59191 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:06:53 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE AD_ClientInfo ADD DeliveryPolicy CHAR(1) DEFAULT 'N'
|
||||
;
|
||||
|
||||
-- Add field to Client Info Window
|
||||
|
||||
-- 2010-maj-19 15:10:10 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_FieldGroup_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,DefaultValue,Description,DisplayLength,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,Updated,UpdatedBy) VALUES (0,59191,118,58879,0,169,TO_DATE('2010-05-19 15:10:10','YYYY-MM-DD HH24:MI:SS'),100,'N','Delivery Policy',14,'U','The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','Y','N','N','N','N','Y','Delivery Policy',155,TO_DATE('2010-05-19 15:10:10','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:10:10 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58879 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:12:01 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,Description,DisplayLength,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,SortNo,Updated,UpdatedBy) VALUES (0,59190,58880,0,170,TO_DATE('2010-05-19 15:12:01','YYYY-MM-DD HH24:MI:SS'),100,'Delivery Policy',0,'D','The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','Y','N','N','N','N','N','Delivery Policy',85,0,TO_DATE('2010-05-19 15:12:01','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:12:01 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58880 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:12:11 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET DisplayLength=22,Updated=TO_DATE('2010-05-19 15:12:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=58880
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:47:33 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process (AccessLevel,AD_Client_ID,AD_Org_ID,AD_Process_ID,Classname,CopyFromProcess,Created,CreatedBy,Description,EntityType,Help,IsActive,IsBetaFunctionality,IsDirectPrint,IsReport,IsServerProcess,Name,ShowHelp,Statistic_Count,Statistic_Seconds,Updated,UpdatedBy,Value) VALUES ('3',0,0,53217,'org.adempiere.process.AllocateSalesOrders','N',TO_DATE('2010-06-22 13:47:31','YYYY-MM-DD HH24:MI:SS'),100,'Allocate available on hand stock to sales orders','D','This process is only necessary for delivery policy = Strict order','Y','N','N','N','N','Allocate Sales Orders','Y',0,0,TO_DATE('2010-06-22 13:47:31','YYYY-MM-DD HH24:MI:SS'),100,'AllocateSalesOrders')
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:47:33 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process_Trl (AD_Language,AD_Process_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Process_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Process t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_ID=53217 AND NOT EXISTS (SELECT * FROM AD_Process_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_ID=t.AD_Process_ID)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:48:24 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process_Para (AD_Client_ID,AD_Element_ID,AD_Org_ID,AD_Process_ID,AD_Process_Para_ID,AD_Reference_ID,ColumnName,Created,CreatedBy,Description,EntityType,FieldLength,IsActive,IsCentrallyMaintained,IsMandatory,IsRange,Name,SeqNo,Updated,UpdatedBy) VALUES (0,459,0,53217,53422,18,'M_Warehouse_ID',TO_DATE('2010-06-22 13:48:23','YYYY-MM-DD HH24:MI:SS'),100,'Warehouse where allocation should be executed.','D',0,'Y','Y','N','N','Warehouse',10,TO_DATE('2010-06-22 13:48:23','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:48:24 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process_Para_Trl (AD_Language,AD_Process_Para_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Process_Para_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Process_Para t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_Para_ID=53422 AND NOT EXISTS (SELECT * FROM AD_Process_Para_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_Para_ID=t.AD_Process_Para_ID)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:05 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Menu (Action,AD_Client_ID,AD_Menu_ID,AD_Org_ID,AD_Process_ID,Created,CreatedBy,Description,EntityType,IsActive,IsCentrallyMaintained,IsReadOnly,IsSOTrx,IsSummary,Name,Updated,UpdatedBy) VALUES ('P',0,53283,0,53217,TO_DATE('2010-06-22 13:49:04','YYYY-MM-DD HH24:MI:SS'),100,'Allocate available on hand stock to sales orders','D','Y','Y','N','N','N','Allocate Sales Orders',TO_DATE('2010-06-22 13:49:04','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:05 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Menu_Trl (AD_Language,AD_Menu_ID, Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Menu_ID, t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Menu t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Menu_ID=53283 AND NOT EXISTS (SELECT * FROM AD_Menu_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Menu_ID=t.AD_Menu_ID)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:05 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo) SELECT t.AD_Client_ID, 0, 'Y', SysDate, 100, SysDate, 100,t.AD_Tree_ID, 53283, 0, 999 FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=53283)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=0, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53283
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=1, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=346
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=2, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53132
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=3, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=193
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=4, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=180
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=5, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=494
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=6, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=444
|
||||
;
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
-- Adjust, alter view M_Product_Stock_v
|
||||
CREATE OR REPLACE VIEW m_product_stock_v AS
|
||||
SELECT ms.isactive, ms.created, ms.createdby, ms.updated, ms.updatedby,
|
||||
ms.m_product_id, mp.value, mp.name, mp.help,
|
||||
ms.qtyonhand - ms.qtyreserved AS qtyavailable,
|
||||
ms.qtyonhand, ms.qtyreserved,
|
||||
ms.qtyallocated,
|
||||
mp.description,
|
||||
mw.name AS warehouse,
|
||||
mw.m_warehouse_id,
|
||||
mw.ad_client_id,
|
||||
mw.ad_org_id,
|
||||
mp.documentnote
|
||||
FROM m_storage ms
|
||||
JOIN m_product mp ON ms.m_product_id = mp.m_product_id
|
||||
JOIN m_locator ml ON ms.m_locator_id = ml.m_locator_id
|
||||
JOIN m_warehouse mw ON ml.m_warehouse_id = mw.m_warehouse_id
|
||||
ORDER BY mw.name;
|
||||
|
||||
|
||||
-- Create function isShippable
|
||||
CREATE OR REPLACE FUNCTION isshippable
|
||||
(
|
||||
product_id IN NUMBER
|
||||
)
|
||||
RETURN CHAR AS
|
||||
v_IsStocked CHAR;
|
||||
v_IsBom CHAR;
|
||||
v_ProductType CHAR;
|
||||
v_return CHAR;
|
||||
BEGIN
|
||||
IF product_id = NULL THEN
|
||||
return 'N';
|
||||
END IF;
|
||||
|
||||
SELECT IsStocked, IsBom, ProductType
|
||||
INTO v_IsStocked, v_IsBom, v_ProductType
|
||||
FROM M_Product WHERE M_Product_ID=product_id;
|
||||
|
||||
IF (v_IsStocked='Y' AND v_ProductType='I' AND v_IsBom='N') THEN
|
||||
v_return := 'Y';
|
||||
ELSE
|
||||
v_return := 'N';
|
||||
END IF;
|
||||
|
||||
return v_return;
|
||||
END isshippable;
|
||||
/
|
||||
|
||||
-- Function to get delivery policy
|
||||
|
||||
CREATE OR REPLACE FUNCTION get_delivery_policy
|
||||
(
|
||||
warehouse_id IN NUMBER
|
||||
)
|
||||
RETURN CHAR AS
|
||||
v_orgId NUMBER;
|
||||
v_clientId NUMBER;
|
||||
v_return CHAR;
|
||||
BEGIN
|
||||
SELECT ad_client_id, ad_org_id INTO
|
||||
v_clientId, v_orgId FROM
|
||||
M_Warehouse WHERE M_Warehouse_ID=warehouse_id;
|
||||
|
||||
SELECT COALESCE(ad_orginfo.deliverypolicy, ad_clientinfo.deliverypolicy) INTO
|
||||
v_return
|
||||
FROM AD_ClientInfo
|
||||
JOIN AD_OrgInfo ON (AD_ClientInfo.AD_Client_ID=AD_OrgInfo.AD_Client_ID)
|
||||
WHERE AD_ClientInfo.AD_Client_ID = v_clientId AND
|
||||
AD_OrgInfo.AD_Org_ID = v_orgId;
|
||||
|
||||
return v_return;
|
||||
END get_delivery_policy;
|
||||
/
|
||||
|
||||
-- Get allocated on order
|
||||
|
||||
CREATE OR REPLACE FUNCTION get_allocated_on_order
|
||||
(
|
||||
p_product_id IN NUMBER,
|
||||
p_warehouse_id IN NUMBER)
|
||||
RETURN NUMBER AS
|
||||
|
||||
v_sum NUMBER;
|
||||
|
||||
BEGIN
|
||||
-- Get Product Attribute Set Instance
|
||||
SELECT sum(qtyallocated) into v_sum from C_OrderLine ol
|
||||
JOIN C_Order o on (o.C_Order_ID=ol.C_Order_ID)
|
||||
WHERE
|
||||
M_Product_ID=p_product_id AND
|
||||
COALESCE(ol.M_Warehouse_ID, o.M_Warehouse_ID)=p_warehouse_id;
|
||||
|
||||
RETURN v_sum;
|
||||
END get_allocated_on_order;
|
||||
/
|
||||
|
||||
-- IN OUT CANDIDATE ORDERLINE
|
||||
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_orderline
|
||||
(
|
||||
c_order_line_id IN NUMBER
|
||||
)
|
||||
RETURN NUMBER AS
|
||||
|
||||
v_qtyordered NUMBER;
|
||||
v_qtydelivered NUMBER;
|
||||
v_qtyallocated NUMBER;
|
||||
v_qtyonhand NUMBER;
|
||||
v_qtytodeliver NUMBER;
|
||||
v_qtyreserved NUMBER;
|
||||
v_order_id NUMBER;
|
||||
v_inoutExists NUMBER;
|
||||
v_warehouse_id NUMBER;
|
||||
v_product_id NUMBER;
|
||||
v_orderReady NUMBER;
|
||||
v_isShippable CHAR;
|
||||
v_deliveryRule CHAR;
|
||||
v_deliveryPolicy CHAR;
|
||||
v_return CHAR;
|
||||
|
||||
BEGIN
|
||||
SELECT qtyordered, qtydelivered, qtyallocated, qtyreserved, c_order_id,
|
||||
get_delivery_policy(m_warehouse_id), isshippable(m_product_id),
|
||||
m_warehouse_id, m_product_id
|
||||
INTO
|
||||
v_qtyordered, v_qtydelivered, v_qtyallocated, v_qtyreserved, v_order_id,
|
||||
v_deliveryPolicy, v_isShippable,
|
||||
v_warehouse_id, v_product_id
|
||||
FROM
|
||||
C_OrderLine where C_OrderLine_ID=c_order_line_id;
|
||||
|
||||
-- If all is already delivered then it's not a candidate
|
||||
IF v_qtyordered = v_qtydelivered THEN
|
||||
-- RAISE NOTICE 'All is delivered';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Non shippable (ie non physical items) are always inout candidate
|
||||
IF v_isShippable='N' THEN
|
||||
-- RAISE NOTICE 'Non physical item, always deliverable';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
|
||||
SELECT 1 INTO v_inoutExists FROM m_inoutline iol
|
||||
JOIN m_inout io ON iol.m_inout_id = io.m_inout_id
|
||||
WHERE iol.c_orderline_id = c_order_line_id AND (io.docstatus IN ('IP', 'WC', 'IN'));
|
||||
|
||||
-- If an in-out line is in progress this is not a candidate
|
||||
IF v_inoutExists = 1 THEN
|
||||
-- RAISE NOTICE 'Already being shipped';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Check delivery rule
|
||||
SELECT DeliveryRule INTO
|
||||
v_deliveryRule
|
||||
FROM
|
||||
C_Order where C_Order_ID=v_order_id;
|
||||
|
||||
IF v_deliveryRule='F' THEN
|
||||
-- RAISE NOTICE 'Delivery rule = Force';
|
||||
RETURN 1;
|
||||
END IF; -- Force
|
||||
|
||||
v_qtytodeliver := v_qtyordered - v_qtydelivered;
|
||||
IF v_qtytodeliver = 0 THEN
|
||||
-- RAISE NOTICE 'Nothing to deliver';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'O' THEN -- Deliver in strict order, compare with qty allocated
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = Strict order';
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF v_qtytodeliver = v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Quantity to deliver = qty allocated';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver > v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Not enough allocated for complete order';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyallocated > 0 THEN
|
||||
-- RAISE NOTICE 'Something to deliver';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
END CASE;
|
||||
-- RAISE NOTICE 'No inout candidate';
|
||||
RETURN 0;
|
||||
END;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'N' THEN -- No hold, only compare with on hand
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = No hold';
|
||||
SELECT qtyonhand INTO
|
||||
v_qtyonhand
|
||||
FROM m_product_stock_v
|
||||
WHERE M_Product_ID=v_product_id AND M_Warehouse_ID=v_warehouse_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF (v_qtytodeliver = v_qtyreserved AND v_qtytodeliver <= v_qtyonhand) THEN RETURN 1; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver < v_qtyreserved OR v_qtytodeliver >= v_qtyonhand THEN RETURN 0; END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyonhand > 0 THEN RETURN 1; END IF;
|
||||
END CASE;
|
||||
END;
|
||||
END IF;
|
||||
|
||||
-- RAISE NOTICE 'Default answer, something to deliver';
|
||||
return 1;
|
||||
END;
|
||||
/
|
||||
|
||||
-- INOUT CANDIDATE ORDER
|
||||
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_order
|
||||
(
|
||||
p_order_id IN NUMBER
|
||||
)
|
||||
RETURN CHAR AS
|
||||
|
||||
v_lines_ready NUMBER;
|
||||
v_lines_total NUMBER;
|
||||
v_deliveryRule CHAR;
|
||||
BEGIN
|
||||
|
||||
-- Get order info
|
||||
-- Only orders that are complete, not delivered, delivery rule anything else than manual and is a sales order
|
||||
-- can be inout candidates
|
||||
select DeliveryRule INTO v_deliveryRule FROM C_Order WHERE
|
||||
c_order_id=p_order_id AND
|
||||
docstatus = 'CO' AND
|
||||
isdelivered = 'N' AND
|
||||
deliveryrule <> 'M' AND
|
||||
(c_doctype_id IN ( SELECT c_doctype.c_doctype_id FROM c_doctype
|
||||
WHERE c_doctype.docbasetype = 'SOO' AND c_doctype.docsubtypeso NOT IN('ON','OB','WR')));
|
||||
|
||||
IF v_deliveryRule IS NULL THEN
|
||||
RETURN 'N';
|
||||
END IF;
|
||||
|
||||
IF v_deliveryRule='F' THEN RETURN 'Y'; END IF; -- Force
|
||||
|
||||
-- Check lines
|
||||
SELECT sum(is_inout_candidate_orderline(c_orderline_id)), sum(1)
|
||||
INTO v_lines_ready, v_lines_total
|
||||
FROM c_orderline where c_order_id=p_order_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF v_lines_ready > 0 THEN RETURN 'Y'; END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_lines_ready > 0 THEN RETURN 'Y'; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_lines_ready = v_lines_total THEN RETURN 'Y'; END IF;
|
||||
END CASE;
|
||||
|
||||
return 'N';
|
||||
END;
|
||||
/
|
||||
|
||||
-- INOUT CANDIDATE
|
||||
|
||||
CREATE OR REPLACE VIEW m_inout_candidate_v AS
|
||||
SELECT
|
||||
o.ad_client_id,
|
||||
o.ad_org_id,
|
||||
o.c_bpartner_id,
|
||||
o.c_order_id,
|
||||
o.documentno,
|
||||
o.dateordered,
|
||||
o.c_doctype_id,
|
||||
o.poreference,
|
||||
o.description,
|
||||
o.salesrep_id,
|
||||
l.m_warehouse_id,
|
||||
sum((l.qtyordered - l.qtydelivered) * l.priceactual) AS totallines
|
||||
|
||||
FROM c_order o
|
||||
JOIN c_orderline l ON o.c_order_id = l.c_order_id
|
||||
WHERE
|
||||
(l.m_product_id IS NULL OR (EXISTS ( SELECT 1
|
||||
FROM m_product p
|
||||
WHERE l.m_product_id = p.m_product_id AND p.isexcludeautodelivery = 'N'))) AND
|
||||
(l.m_product_id IS NOT NULL OR l.c_charge_id IS NOT NULL) AND
|
||||
is_inout_candidate_order(o.c_order_id) = 'Y'
|
||||
|
||||
GROUP BY o.ad_client_id, o.ad_org_id, o.c_bpartner_id, o.c_order_id, o.documentno, o.dateordered, o.c_doctype_id, o.poreference, o.description, o.salesrep_id, l.m_warehouse_id;
|
|
@ -0,0 +1,360 @@
|
|||
-- 2010-maj-19 14:36:56 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element (AD_Client_ID,AD_Element_ID,AD_Org_ID,ColumnName,Created,CreatedBy,Description,EntityType,Help,IsActive,Name,PrintName,Updated,UpdatedBy) VALUES (0,54156,0,'QtyAllocated',TO_TIMESTAMP('2010-05-19 14:36:56','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity','D','Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Qty Allocated','Qty Allocated',TO_TIMESTAMP('2010-05-19 14:36:56','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:36:56 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element_Trl (AD_Language,AD_Element_ID, Description,Help,Name,PO_Description,PO_Help,PO_Name,PO_PrintName,PrintName, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Element_ID, t.Description,t.Help,t.Name,t.PO_Description,t.PO_Help,t.PO_Name,t.PO_PrintName,t.PrintName, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Element t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Element_ID=54156 AND NOT EXISTS (SELECT * FROM AD_Element_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Element_ID=t.AD_Element_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:42:55 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element (AD_Client_ID,AD_Element_ID,AD_Org_ID,ColumnName,Created,CreatedBy,Description,EntityType,Help,IsActive,Name,PrintName,Updated,UpdatedBy) VALUES (0,54157,0,'DeliveryPolicy',TO_TIMESTAMP('2010-05-19 14:42:55','YYYY-MM-DD HH24:MI:SS'),100,'Delivery Policy','D','The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Delivery Policy','Delivery Policy',TO_TIMESTAMP('2010-05-19 14:42:55','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:42:55 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Element_Trl (AD_Language,AD_Element_ID, Description,Help,Name,PO_Description,PO_Help,PO_Name,PO_PrintName,PrintName, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Element_ID, t.Description,t.Help,t.Name,t.PO_Description,t.PO_Help,t.PO_Name,t.PO_PrintName,t.PrintName, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Element t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Element_ID=54157 AND NOT EXISTS (SELECT * FROM AD_Element_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Element_ID=t.AD_Element_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:43:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Reference (AD_Client_ID,AD_Org_ID,AD_Reference_ID,Created,CreatedBy,Description,EntityType,IsActive,IsOrderByValue,Name,Updated,UpdatedBy,ValidationType) VALUES (0,0,53355,TO_TIMESTAMP('2010-05-19 14:43:59','YYYY-MM-DD HH24:MI:SS'),100,'List of Delivery Policies','D','Y','N','DeliveryPolicies',TO_TIMESTAMP('2010-05-19 14:43:59','YYYY-MM-DD HH24:MI:SS'),100,'L')
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:43:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Reference_Trl (AD_Language,AD_Reference_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Reference_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Reference t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Reference_ID=53355 AND NOT EXISTS (SELECT * FROM AD_Reference_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Reference_ID=t.AD_Reference_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:44:40 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List (AD_Client_ID,AD_Org_ID,AD_Reference_ID,AD_Ref_List_ID,Created,CreatedBy,Description,EntityType,IsActive,Name,Updated,UpdatedBy,Value) VALUES (0,0,53355,53581,TO_TIMESTAMP('2010-05-19 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,'Default delivery policy - deliver as soon as orders are fulfilled according to delivery rule','D','Y','No Hold',TO_TIMESTAMP('2010-05-19 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,'N')
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:44:40 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List_Trl (AD_Language,AD_Ref_List_ID, Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Ref_List_ID, t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Ref_List t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Ref_List_ID=53581 AND NOT EXISTS (SELECT * FROM AD_Ref_List_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Ref_List_ID=t.AD_Ref_List_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:45:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List (AD_Client_ID,AD_Org_ID,AD_Reference_ID,AD_Ref_List_ID,Created,CreatedBy,Description,EntityType,IsActive,Name,Updated,UpdatedBy,Value) VALUES (0,0,53355,53582,TO_TIMESTAMP('2010-05-19 14:45:59','YYYY-MM-DD HH24:MI:SS'),100,'Allocate items to orders and fulfill them in strict order.','D','Y','Strict order',TO_TIMESTAMP('2010-05-19 14:45:59','YYYY-MM-DD HH24:MI:SS'),100,'O')
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:45:59 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Ref_List_Trl (AD_Language,AD_Ref_List_ID, Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Ref_List_ID, t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Ref_List t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Ref_List_ID=53582 AND NOT EXISTS (SELECT * FROM AD_Ref_List_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Ref_List_ID=t.AD_Ref_List_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:47:45 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Table_ID,ColumnName,Created,CreatedBy,DefaultValue,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59188,54156,0,29,260,'QtyAllocated',TO_TIMESTAMP('2010-05-19 14:47:45','YYYY-MM-DD HH24:MI:SS'),100,'0','Allocated quantity','D',22,'Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Qty Allocated',0,TO_TIMESTAMP('2010-05-19 14:47:45','YYYY-MM-DD HH24:MI:SS'),100,1.000000000000)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:47:45 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59188 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:48:05 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE C_OrderLine ADD COLUMN QtyAllocated NUMERIC DEFAULT '0'
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Table_ID,ColumnName,Created,CreatedBy,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59189,54156,0,29,250,'QtyAllocated',TO_TIMESTAMP('2010-05-19 14:49:07','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity','D',22,'Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Qty Allocated',0,TO_TIMESTAMP('2010-05-19 14:49:07','YYYY-MM-DD HH24:MI:SS'),100,1.000000000000)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59189 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:18 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE M_Storage ADD COLUMN QtyAllocated NUMERIC DEFAULT '0'
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:49:28 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Column SET DefaultValue='0',Updated=TO_TIMESTAMP('2010-05-19 14:49:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=59189
|
||||
;
|
||||
|
||||
-- Add field QtyAllocated to Sales Order Line
|
||||
|
||||
-- 2010-maj-19 14:54:08 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_FieldGroup_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,Description,DisplayLength,DisplayLogic,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,Updated,UpdatedBy) VALUES (0,59188,102,58877,0,187,TO_TIMESTAMP('2010-05-19 14:54:08','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity',26,'@OrderType@=''OB'' | @OrderType@=''SO'' | @Processed@=''Y''','D','Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','Y','N','N','N','Y','N','Qty Allocated',190,TO_TIMESTAMP('2010-05-19 14:54:08','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:08 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58877 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=210,IsDisplayed='Y' WHERE AD_Field_ID=58877
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=220,IsDisplayed='Y' WHERE AD_Field_ID=1135
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=230,IsDisplayed='Y' WHERE AD_Field_ID=10829
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=240,IsDisplayed='Y' WHERE AD_Field_ID=1138
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=250,IsDisplayed='Y' WHERE AD_Field_ID=1137
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=260,IsDisplayed='Y' WHERE AD_Field_ID=2115
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=270,IsDisplayed='Y' WHERE AD_Field_ID=1141
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=280,IsDisplayed='Y' WHERE AD_Field_ID=3124
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=290,IsDisplayed='Y' WHERE AD_Field_ID=12745
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=300,IsDisplayed='Y' WHERE AD_Field_ID=13644
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=310,IsDisplayed='Y' WHERE AD_Field_ID=13645
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=320,IsDisplayed='Y' WHERE AD_Field_ID=13691
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=330,IsDisplayed='Y' WHERE AD_Field_ID=13650
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=340,IsDisplayed='Y' WHERE AD_Field_ID=13651
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=350,IsDisplayed='Y' WHERE AD_Field_ID=2880
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=360,IsDisplayed='Y' WHERE AD_Field_ID=12744
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:54:35 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET SeqNo=370,IsDisplayed='Y' WHERE AD_Field_ID=10332
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:55:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET Name='Allocated Quantity',Updated=TO_TIMESTAMP('2010-05-19 14:55:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=58877
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:55:07 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field_Trl SET IsTranslated='N' WHERE AD_Field_ID=58877
|
||||
;
|
||||
|
||||
-- Add field QtyAllocated to MStorage
|
||||
|
||||
-- 2010-maj-19 14:56:52 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,Description,DisplayLength,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,SortNo,Updated,UpdatedBy) VALUES (0,59189,58878,0,179,TO_TIMESTAMP('2010-05-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100,'Allocated quantity',26,'D','Allocated quantity is the quantity that is actually reserved for a specific customer. The customer "owns" this quantity. The allocated quantity can never be more than what''s in stock (as opposed to resevedQty).','Y','Y','Y','N','N','N','N','N','Qty Allocated',110,0,TO_TIMESTAMP('2010-05-19 14:56:52','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:56:52 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58878 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:57:28 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET Name='Allocated Quantity',Updated=TO_TIMESTAMP('2010-05-19 14:57:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=58878
|
||||
;
|
||||
|
||||
-- 2010-maj-19 14:57:28 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field_Trl SET IsTranslated='N' WHERE AD_Field_ID=58878
|
||||
;
|
||||
|
||||
-- Add column Delivery Policy to OrganizationInfo
|
||||
|
||||
-- 2010-maj-19 15:02:03 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,ColumnName,Created,CreatedBy,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59190,54157,0,17,53355,228,'DeliveryPolicy',TO_TIMESTAMP('2010-05-19 15:02:03','YYYY-MM-DD HH24:MI:SS'),100,'Delivery Policy','D',1,'The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Delivery Policy',0,TO_TIMESTAMP('2010-05-19 15:02:03','YYYY-MM-DD HH24:MI:SS'),100,0)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:02:03 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59190 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:02:11 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Column SET Version=1.000000000000,Updated=TO_TIMESTAMP('2010-05-19 15:02:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=59190
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:02:18 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE AD_OrgInfo ADD COLUMN DeliveryPolicy CHAR(1) DEFAULT NULL
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:06:47 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column (AD_Client_ID,AD_Column_ID,AD_Element_ID,AD_Org_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,ColumnName,Created,CreatedBy,DefaultValue,Description,EntityType,FieldLength,Help,IsActive,IsAllowLogging,IsAlwaysUpdateable,IsAutocomplete,IsEncrypted,IsIdentifier,IsKey,IsMandatory,IsParent,IsSelectionColumn,IsSyncDatabase,IsTranslated,IsUpdateable,Name,SeqNo,Updated,UpdatedBy,Version) VALUES (0,59191,54157,0,17,53355,227,'DeliveryPolicy',TO_TIMESTAMP('2010-05-19 15:06:46','YYYY-MM-DD HH24:MI:SS'),100,'N','Delivery Policy','D',1,'The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','N','N','N','N','N','N','N','N','N','N','Y','Delivery Policy',0,TO_TIMESTAMP('2010-05-19 15:06:46','YYYY-MM-DD HH24:MI:SS'),100,1.000000000000)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:06:47 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=59191 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:06:53 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
ALTER TABLE AD_ClientInfo ADD COLUMN DeliveryPolicy CHAR(1) DEFAULT 'N'
|
||||
;
|
||||
|
||||
-- Add field to Client Info Window
|
||||
|
||||
-- 2010-maj-19 15:10:10 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_FieldGroup_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,DefaultValue,Description,DisplayLength,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,Updated,UpdatedBy) VALUES (0,59191,118,58879,0,169,TO_TIMESTAMP('2010-05-19 15:10:10','YYYY-MM-DD HH24:MI:SS'),100,'N','Delivery Policy',14,'U','The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','Y','N','N','N','N','Y','Delivery Policy',155,TO_TIMESTAMP('2010-05-19 15:10:10','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:10:10 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58879 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- Add DeliveryPolicy field to Organization Window
|
||||
|
||||
-- 2010-maj-19 15:12:01 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field (AD_Client_ID,AD_Column_ID,AD_Field_ID,AD_Org_ID,AD_Tab_ID,Created,CreatedBy,Description,DisplayLength,EntityType,Help,IsActive,IsCentrallyMaintained,IsDisplayed,IsEncrypted,IsFieldOnly,IsHeading,IsReadOnly,IsSameLine,Name,SeqNo,SortNo,Updated,UpdatedBy) VALUES (0,59190,58880,0,170,TO_TIMESTAMP('2010-05-19 15:12:01','YYYY-MM-DD HH24:MI:SS'),100,'Delivery Policy',0,'D','The delivery policy determines how outbound orders will be allocated.
|
||||
The default delivery policy is to deliver fulfilled orders as soon as possible even if it means
|
||||
other non fulfilled orders also needs the items being delivered on the fulfilled orders.','Y','Y','Y','N','N','N','N','N','Delivery Policy',85,0,TO_TIMESTAMP('2010-05-19 15:12:01','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:12:01 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
INSERT INTO AD_Field_Trl (AD_Language,AD_Field_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Field_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Field t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Field_ID=58880 AND NOT EXISTS (SELECT * FROM AD_Field_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Field_ID=t.AD_Field_ID)
|
||||
;
|
||||
|
||||
-- 2010-maj-19 15:12:11 CEST
|
||||
-- FR 3002040 - Delivery Policy
|
||||
UPDATE AD_Field SET DisplayLength=22,Updated=TO_TIMESTAMP('2010-05-19 15:12:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=58880
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:47:33 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process (AccessLevel,AD_Client_ID,AD_Org_ID,AD_Process_ID,Classname,CopyFromProcess,Created,CreatedBy,Description,EntityType,Help,IsActive,IsBetaFunctionality,IsDirectPrint,IsReport,IsServerProcess,Name,ShowHelp,Statistic_Count,Statistic_Seconds,Updated,UpdatedBy,Value) VALUES ('3',0,0,53217,'org.adempiere.process.AllocateSalesOrders','N',TO_TIMESTAMP('2010-06-22 13:47:31','YYYY-MM-DD HH24:MI:SS'),100,'Allocate available on hand stock to sales orders','D','This process is only necessary for delivery policy = Strict order','Y','N','N','N','N','Allocate Sales Orders','Y',0,0,TO_TIMESTAMP('2010-06-22 13:47:31','YYYY-MM-DD HH24:MI:SS'),100,'AllocateSalesOrders')
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:47:33 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process_Trl (AD_Language,AD_Process_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Process_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Process t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_ID=53217 AND NOT EXISTS (SELECT * FROM AD_Process_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_ID=t.AD_Process_ID)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:48:24 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process_Para (AD_Client_ID,AD_Element_ID,AD_Org_ID,AD_Process_ID,AD_Process_Para_ID,AD_Reference_ID,ColumnName,Created,CreatedBy,Description,EntityType,FieldLength,IsActive,IsCentrallyMaintained,IsMandatory,IsRange,Name,SeqNo,Updated,UpdatedBy) VALUES (0,459,0,53217,53422,18,'M_Warehouse_ID',TO_TIMESTAMP('2010-06-22 13:48:23','YYYY-MM-DD HH24:MI:SS'),100,'Warehouse where allocation should be executed.','D',0,'Y','Y','N','N','Warehouse',10,TO_TIMESTAMP('2010-06-22 13:48:23','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:48:24 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Process_Para_Trl (AD_Language,AD_Process_Para_ID, Description,Help,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Process_Para_ID, t.Description,t.Help,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Process_Para t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_Para_ID=53422 AND NOT EXISTS (SELECT * FROM AD_Process_Para_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_Para_ID=t.AD_Process_Para_ID)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:05 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Menu ("action",AD_Client_ID,AD_Menu_ID,AD_Org_ID,AD_Process_ID,Created,CreatedBy,Description,EntityType,IsActive,IsCentrallyMaintained,IsReadOnly,IsSOTrx,IsSummary,Name,Updated,UpdatedBy) VALUES ('P',0,53283,0,53217,TO_TIMESTAMP('2010-06-22 13:49:04','YYYY-MM-DD HH24:MI:SS'),100,'Allocate available on hand stock to sales orders','D','Y','Y','N','N','N','Allocate Sales Orders',TO_TIMESTAMP('2010-06-22 13:49:04','YYYY-MM-DD HH24:MI:SS'),100)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:05 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_Menu_Trl (AD_Language,AD_Menu_ID, Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Menu_ID, t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Menu t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Menu_ID=53283 AND NOT EXISTS (SELECT * FROM AD_Menu_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Menu_ID=t.AD_Menu_ID)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:05 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo) SELECT t.AD_Client_ID, 0, 'Y', CURRENT_TIMESTAMP, 100, CURRENT_TIMESTAMP, 100,t.AD_Tree_ID, 53283, 0, 999 FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=53283)
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=0, Updated=CURRENT_TIMESTAMP WHERE AD_Tree_ID=10 AND Node_ID=53283
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=1, Updated=CURRENT_TIMESTAMP WHERE AD_Tree_ID=10 AND Node_ID=346
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=2, Updated=CURRENT_TIMESTAMP WHERE AD_Tree_ID=10 AND Node_ID=53132
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=3, Updated=CURRENT_TIMESTAMP WHERE AD_Tree_ID=10 AND Node_ID=193
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=4, Updated=CURRENT_TIMESTAMP WHERE AD_Tree_ID=10 AND Node_ID=180
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=5, Updated=CURRENT_TIMESTAMP WHERE AD_Tree_ID=10 AND Node_ID=494
|
||||
;
|
||||
|
||||
-- Jun 22, 2010 1:49:15 PM CEST
|
||||
-- FR 3004020 Delivery Policy
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=459, SeqNo=6, Updated=CURRENT_TIMESTAMP WHERE AD_Tree_ID=10 AND Node_ID=444
|
||||
;
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
-- Adjust, alter view M_Product_Stock_v
|
||||
DROP VIEW IF EXISTS m_product_stock_v;
|
||||
CREATE OR REPLACE VIEW m_product_stock_v AS
|
||||
SELECT ms.isactive, ms.created, ms.createdby, ms.updated, ms.updatedby,
|
||||
ms.m_product_id, mp.value, mp.name, mp.help,
|
||||
ms.qtyonhand - ms.qtyreserved AS qtyavailable,
|
||||
ms.qtyonhand, ms.qtyreserved,
|
||||
ms.qtyallocated,
|
||||
mp.description,
|
||||
mw.name AS warehouse,
|
||||
mw.m_warehouse_id,
|
||||
mw.ad_client_id,
|
||||
mw.ad_org_id,
|
||||
mp.documentnote
|
||||
FROM m_storage ms
|
||||
JOIN m_product mp ON ms.m_product_id = mp.m_product_id
|
||||
JOIN m_locator ml ON ms.m_locator_id = ml.m_locator_id
|
||||
JOIN m_warehouse mw ON ml.m_warehouse_id = mw.m_warehouse_id
|
||||
ORDER BY mw.name;
|
||||
|
||||
ALTER TABLE m_product_stock_v OWNER TO adempiere;
|
||||
|
||||
-- Create function isShippable
|
||||
CREATE OR REPLACE FUNCTION isshippable(product_id numeric)
|
||||
RETURNS character AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_IsStocked character(1);
|
||||
v_IsBom character(1);
|
||||
v_ProductType character(1);
|
||||
v_return character(1);
|
||||
BEGIN
|
||||
IF product_id = NULL THEN
|
||||
return 'N';
|
||||
END IF;
|
||||
|
||||
SELECT IsStocked, IsBom, ProductType
|
||||
INTO v_IsStocked, v_IsBom, v_ProductType
|
||||
FROM M_Product WHERE M_Product_ID=product_id;
|
||||
|
||||
IF (v_IsStocked='Y' AND v_ProductType='I' AND v_IsBom='N') THEN
|
||||
v_return := 'Y';
|
||||
ELSE
|
||||
v_return := 'N';
|
||||
END IF;
|
||||
|
||||
return v_return;
|
||||
END;
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
||||
ALTER FUNCTION isshippable(numeric) OWNER TO adempiere;
|
||||
|
||||
-- Function to get delivery policy
|
||||
|
||||
CREATE OR REPLACE FUNCTION get_delivery_policy(warehouse_id numeric)
|
||||
RETURNS character AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_orgId numeric;
|
||||
v_clientId numeric;
|
||||
v_return character(1);
|
||||
BEGIN
|
||||
SELECT ad_client_id, ad_org_id INTO
|
||||
v_clientId, v_orgId FROM
|
||||
M_Warehouse WHERE M_Warehouse_ID=warehouse_id;
|
||||
|
||||
SELECT COALESCE(ad_orginfo.deliverypolicy, ad_clientinfo.deliverypolicy) INTO
|
||||
v_return
|
||||
FROM AD_ClientInfo
|
||||
JOIN AD_OrgInfo ON (AD_ClientInfo.AD_Client_ID=AD_OrgInfo.AD_Client_ID)
|
||||
WHERE AD_ClientInfo.AD_Client_ID = v_clientId AND
|
||||
AD_OrgInfo.AD_Org_ID = v_orgId;
|
||||
|
||||
return v_return;
|
||||
END;
|
||||
$BODY$
|
||||
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
||||
ALTER FUNCTION get_delivery_policy(numeric) OWNER TO adempiere;
|
||||
|
||||
-- Get allocated on order
|
||||
|
||||
CREATE OR REPLACE FUNCTION get_allocated_on_order(p_product_id numeric, p_warehouse_id numeric)
|
||||
RETURNS numeric AS
|
||||
$BODY$
|
||||
|
||||
DECLARE
|
||||
|
||||
v_sum numeric;
|
||||
|
||||
BEGIN
|
||||
-- Get Product Attribute Set Instance
|
||||
SELECT sum(qtyallocated) into v_sum from C_OrderLine ol
|
||||
JOIN C_Order o on (o.C_Order_ID=ol.C_Order_ID)
|
||||
WHERE
|
||||
M_Product_ID=p_product_id AND
|
||||
COALESCE(ol.M_Warehouse_ID, o.M_Warehouse_ID)=p_warehouse_id;
|
||||
|
||||
RETURN v_sum;
|
||||
END;
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
||||
ALTER FUNCTION get_allocated_on_order(numeric, numeric) OWNER TO adempiere;
|
||||
|
||||
-- IN OUT CANDIDATE ORDERLINE
|
||||
|
||||
-- DROP FUNCTION is_inout_candidate_orderline(numeric);
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_orderline(c_order_line_id numeric)
|
||||
RETURNS numeric AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_qtyordered numeric;
|
||||
v_qtydelivered numeric;
|
||||
v_qtyallocated numeric;
|
||||
v_qtyonhand numeric;
|
||||
v_qtytodeliver numeric;
|
||||
v_qtyreserved numeric;
|
||||
v_order_id numeric;
|
||||
v_inoutExists numeric;
|
||||
v_warehouse_id numeric;
|
||||
v_product_id numeric;
|
||||
v_orderReady numeric;
|
||||
v_isShippable character(1);
|
||||
v_deliveryRule character(1);
|
||||
v_deliveryPolicy character(1);
|
||||
v_return character(1);
|
||||
BEGIN
|
||||
SELECT qtyordered, qtydelivered, qtyallocated, qtyreserved, c_order_id,
|
||||
get_delivery_policy(m_warehouse_id), isshippable(m_product_id),
|
||||
m_warehouse_id, m_product_id
|
||||
INTO
|
||||
v_qtyordered, v_qtydelivered, v_qtyallocated, v_qtyreserved, v_order_id,
|
||||
v_deliveryPolicy, v_isShippable,
|
||||
v_warehouse_id, v_product_id
|
||||
FROM
|
||||
C_OrderLine where C_OrderLine_ID=c_order_line_id;
|
||||
|
||||
-- If all is already delivered then it's not a candidate
|
||||
IF v_qtyordered = v_qtydelivered THEN
|
||||
-- RAISE NOTICE 'All is delivered';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Non shippable (ie non physical items) are always inout candidate
|
||||
IF v_isShippable='N' THEN
|
||||
-- RAISE NOTICE 'Non physical item, always deliverable';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
|
||||
SELECT 1 INTO v_inoutExists FROM m_inoutline iol
|
||||
JOIN m_inout io ON iol.m_inout_id = io.m_inout_id
|
||||
WHERE iol.c_orderline_id = c_order_line_id AND (io.docstatus = ANY (ARRAY['IP'::bpchar, 'WC'::bpchar, 'IN'::bpchar]));
|
||||
|
||||
-- If an in-out line is in progress this is not a candidate
|
||||
IF v_inoutExists = 1 THEN
|
||||
-- RAISE NOTICE 'Already being shipped';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
-- Check delivery rule
|
||||
SELECT DeliveryRule INTO
|
||||
v_deliveryRule
|
||||
FROM
|
||||
C_Order where C_Order_ID=v_order_id;
|
||||
|
||||
IF v_deliveryRule='F' THEN
|
||||
-- RAISE NOTICE 'Delivery rule = Force';
|
||||
RETURN 1;
|
||||
END IF; -- Force
|
||||
|
||||
v_qtytodeliver := v_qtyordered - v_qtydelivered;
|
||||
IF v_qtytodeliver = 0 THEN
|
||||
-- RAISE NOTICE 'Nothing to deliver';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'O' THEN -- Deliver in strict order, compare with qty allocated
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = Strict order';
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF v_qtytodeliver = v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Quantity to deliver = qty allocated';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver > v_qtyallocated THEN
|
||||
-- RAISE NOTICE 'Not enough allocated for complete order';
|
||||
RETURN 0;
|
||||
END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyallocated > 0 THEN
|
||||
-- RAISE NOTICE 'Something to deliver';
|
||||
RETURN 1;
|
||||
END IF;
|
||||
END CASE;
|
||||
-- RAISE NOTICE 'No inout candidate';
|
||||
RETURN 0;
|
||||
END;
|
||||
END IF;
|
||||
|
||||
IF v_DeliveryPolicy = 'N' THEN -- No hold, only compare with on hand
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Delivery policy = No hold';
|
||||
SELECT qtyonhand INTO
|
||||
v_qtyonhand
|
||||
FROM m_product_stock_v
|
||||
WHERE M_Product_ID=v_product_id AND M_Warehouse_ID=v_warehouse_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L' THEN -- Complete line
|
||||
IF (v_qtytodeliver = v_qtyreserved AND v_qtytodeliver <= v_qtyonhand) THEN RETURN 1; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_qtytodeliver < v_qtyreserved OR v_qtytodeliver >= v_qtyonhand THEN RETURN 0; END IF;
|
||||
WHEN 'A' THEN -- Availability
|
||||
IF v_qtyonhand > 0 THEN RETURN 1; END IF;
|
||||
END CASE;
|
||||
END;
|
||||
END IF;
|
||||
|
||||
-- RAISE NOTICE 'Default answer, something to deliver';
|
||||
return 1;
|
||||
END
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
||||
ALTER FUNCTION is_inout_candidate_orderline(numeric) OWNER TO adempiere;
|
||||
|
||||
-- INOUT CANDIDATE ORDER
|
||||
|
||||
CREATE OR REPLACE FUNCTION is_inout_candidate_order(p_order_id numeric)
|
||||
RETURNS character AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
v_lines_ready numeric;
|
||||
v_lines_total numeric;
|
||||
v_deliveryRule character(1);
|
||||
BEGIN
|
||||
|
||||
-- Get order info
|
||||
-- Only orders that are complete, not delivered, delivery rule anything else than manual and is a sales order
|
||||
-- can be inout candidates
|
||||
select DeliveryRule INTO v_deliveryRule FROM C_Order WHERE
|
||||
c_order_id=p_order_id AND
|
||||
docstatus = 'CO'::bpchar AND
|
||||
isdelivered = 'N'::bpchar AND
|
||||
deliveryrule <> 'M'::bpchar AND
|
||||
(c_doctype_id IN ( SELECT c_doctype.c_doctype_id FROM c_doctype
|
||||
WHERE c_doctype.docbasetype = 'SOO'::bpchar AND (c_doctype.docsubtypeso <> ALL (ARRAY['ON'::bpchar, 'OB'::bpchar, 'WR'::bpchar]))));
|
||||
|
||||
IF v_deliveryRule IS NULL THEN
|
||||
RETURN 'N';
|
||||
END IF;
|
||||
|
||||
IF v_deliveryRule='F' THEN RETURN 'Y'; END IF; -- Force
|
||||
|
||||
-- Check lines
|
||||
SELECT sum(is_inout_candidate_orderline(c_orderline_id)), sum(1)
|
||||
INTO v_lines_ready, v_lines_total
|
||||
FROM c_orderline where c_order_id=p_order_id;
|
||||
|
||||
CASE v_deliveryRule
|
||||
WHEN 'L','A' THEN -- Complete line and Availability
|
||||
IF v_lines_ready > 0 THEN RETURN 'Y'; END IF;
|
||||
WHEN 'O' THEN -- Complete order
|
||||
IF v_lines_ready = v_lines_total THEN RETURN 'Y'; END IF;
|
||||
END CASE;
|
||||
|
||||
return 'N';
|
||||
END
|
||||
$BODY$
|
||||
LANGUAGE 'plpgsql' VOLATILE
|
||||
COST 100;
|
||||
ALTER FUNCTION is_inout_candidate_order(numeric) OWNER TO adempiere;
|
||||
|
||||
-- INOUT CANDIDATE
|
||||
|
||||
CREATE OR REPLACE VIEW m_inout_candidate_v AS
|
||||
SELECT
|
||||
o.ad_client_id,
|
||||
o.ad_org_id,
|
||||
o.c_bpartner_id,
|
||||
o.c_order_id,
|
||||
o.documentno,
|
||||
o.dateordered,
|
||||
o.c_doctype_id,
|
||||
o.poreference,
|
||||
o.description,
|
||||
o.salesrep_id,
|
||||
l.m_warehouse_id,
|
||||
sum((l.qtyordered - l.qtydelivered) * l.priceactual) AS totallines
|
||||
|
||||
FROM c_order o
|
||||
JOIN c_orderline l ON o.c_order_id = l.c_order_id
|
||||
WHERE
|
||||
(l.m_product_id IS NULL OR (EXISTS ( SELECT 1
|
||||
FROM m_product p
|
||||
WHERE l.m_product_id = p.m_product_id AND p.isexcludeautodelivery = 'N'::bpchar))) AND
|
||||
(l.m_product_id IS NOT NULL OR l.c_charge_id IS NOT NULL) AND
|
||||
is_inout_candidate_order(o.c_order_id) = 'Y'
|
||||
|
||||
GROUP BY o.ad_client_id, o.ad_org_id, o.c_bpartner_id, o.c_order_id, o.documentno, o.dateordered, o.c_doctype_id, o.poreference, o.description, o.salesrep_id, l.m_warehouse_id;
|
||||
ALTER TABLE m_inout_candidate_v OWNER TO adempiere;
|
Loading…
Reference in New Issue