use of org.compiere.model.MDistributionRunLine in project adempiere by adempiere.
the class DistributionRunOrders method generateDistributionDemand.
//Create Distribution Run Line
public boolean generateDistributionDemand() {
m_run = new MDistributionRun(this.getCtx(), 0, null);
m_run.setName("Generate from DRP " + p_DatePromised);
m_run.save();
StringBuffer sql = new StringBuffer("SELECT M_Product_ID , SUM (TargetQty) AS MinQty, SUM (QtyOrdered-QtyDelivered) AS TotalQty FROM DD_OrderLine ol INNER JOIN M_Locator l ON (l.M_Locator_ID=ol.M_Locator_ID) INNER JOIN DD_Order o ON (o.DD_Order_ID=ol.DD_Order_ID) ");
sql.append(" WHERE o.DocStatus IN ('DR','IN') AND ol.DatePromised <= ? AND l.M_Warehouse_ID=? GROUP BY M_Product_ID");
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = DB.prepareStatement(sql.toString(), get_TrxName());
pstmt.setTimestamp(1, p_DatePromised);
//pstmt.setTimestamp(2, p_DatePromised_To);
pstmt.setInt(2, p_M_Warehouse_ID);
rs = pstmt.executeQuery();
int line = 10;
while (rs.next()) {
int M_Product_ID = rs.getInt("M_Product_ID");
BigDecimal QtyAvailable = MStorage.getQtyAvailable(p_M_Warehouse_ID, 0, M_Product_ID, 0, get_TrxName());
if (QtyAvailable.signum() <= 0)
continue;
BigDecimal QtyToDistribute = rs.getBigDecimal("TotalQty");
if (QtyAvailable.compareTo(QtyToDistribute) >= 0)
QtyAvailable = QtyToDistribute;
else {
BigDecimal QtyReserved = getTargetQty(M_Product_ID);
QtyToDistribute = QtyAvailable.subtract(QtyReserved);
}
//if(QtyToDistribute.compareTo(Env.ZERO)==0)
// continue;
MDistributionRunLine m_runLine = new MDistributionRunLine(getCtx(), 0, get_TrxName());
m_runLine.setM_DistributionRun_ID(m_run.getM_DistributionRun_ID());
m_runLine.setAD_Org_ID(p_AD_Org_ID);
m_runLine.setM_DistributionList_ID(p_M_DistributionList_ID);
m_runLine.setLine(line);
m_runLine.setM_Product_ID(M_Product_ID);
m_runLine.setDescription(Msg.translate(getCtx(), "QtyAvailable") + " : " + QtyAvailable + " " + Msg.translate(getCtx(), "QtyOrdered") + " : " + QtyToDistribute);
//m_runLine.setMinQty(rs.getBigDecimal("MinQty"));
m_runLine.setTotalQty(QtyToDistribute);
m_runLine.saveEx();
line += 10;
}
} catch (Exception e) {
log.log(Level.SEVERE, "doIt - " + sql, e);
return false;
} finally {
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
return true;
}
use of org.compiere.model.MDistributionRunLine in project adempiere by adempiere.
the class DistributionRun method insertDetailsDistribution.
/**
* Insert Details
* @return number of rows inserted
*/
private int insertDetailsDistribution() {
// Handle NULL
String sql = "UPDATE M_DistributionRunLine SET MinQty = 0 WHERE MinQty IS NULL";
int no = DB.executeUpdate(sql, get_TrxName());
sql = "UPDATE M_DistributionListLine SET MinQty = 0 WHERE MinQty IS NULL";
no = DB.executeUpdate(sql, get_TrxName());
// Delete Old
sql = "DELETE FROM T_DistributionRunDetail WHERE M_DistributionRun_ID=" + p_M_DistributionRun_ID;
no = DB.executeUpdate(sql, get_TrxName());
log.fine("insertDetails - deleted #" + no);
// Insert New
sql = "INSERT INTO T_DistributionRunDetail " + "(M_DistributionRun_ID, M_DistributionRunLine_ID, M_DistributionList_ID, M_DistributionListLine_ID," + "AD_Client_ID,AD_Org_ID, IsActive, Created,CreatedBy, Updated,UpdatedBy," + "C_BPartner_ID, C_BPartner_Location_ID, M_Product_ID," + "Ratio, MinQty, Qty) " + "SELECT rl.M_DistributionRun_ID, rl.M_DistributionRunLine_ID,ll.M_DistributionList_ID, ll.M_DistributionListLine_ID, " + "rl.AD_Client_ID,rl.AD_Org_ID, rl.IsActive, rl.Created,rl.CreatedBy, rl.Updated,rl.UpdatedBy, " + "ll.C_BPartner_ID, ll.C_BPartner_Location_ID, rl.M_Product_ID, 0 , " + "ol.TargetQty AS MinQty , 0 FROM M_DistributionRunLine rl " + "INNER JOIN M_DistributionList l ON (rl.M_DistributionList_ID=l.M_DistributionList_ID) " + "INNER JOIN M_DistributionListLine ll ON (rl.M_DistributionList_ID=ll.M_DistributionList_ID) " + "INNER JOIN DD_Order o ON (o.C_BPartner_ID=ll.C_BPartner_ID) " + "INNER JOIN DD_OrderLine ol ON (ol.DD_Order_ID=o.DD_Order_ID AND ol.M_Product_ID=rl.M_Product_ID) AND ol.DatePromised" + //+ " BETWEEN " + DB.TO_DATE(p_DatePromised) +" AND "+ DB.TO_DATE(p_DatePromised_To)
"<=" + DB.TO_DATE(p_DatePromised) + " INNER JOIN M_Locator loc ON (loc.M_Locator_ID=ol.M_Locator_ID AND loc.M_Warehouse_ID=" + p_M_Warehouse_ID + ") " + " WHERE rl.M_DistributionRun_ID=" + p_M_DistributionRun_ID + " AND l.RatioTotal<>0 AND rl.IsActive='Y' AND ll.IsActive='Y'";
no = DB.executeUpdate(sql, get_TrxName());
Query query = MTable.get(getCtx(), I_T_DistributionRunDetail.Table_ID).createQuery(MDistributionRunDetail.COLUMNNAME_M_DistributionRun_ID + "=?", get_TrxName());
query.setParameters(p_M_DistributionRun_ID);
List<MDistributionRunDetail> records = query.list();
for (MDistributionRunDetail record : records) {
BigDecimal total_ration = DB.getSQLValueBD(get_TrxName(), "SELECT SUM(Ratio) FROM T_DistributionRunDetail WHERE M_DistributionRun_ID=? AND M_Product_ID=? GROUP BY M_Product_ID", p_M_DistributionRun_ID, record.getM_Product_ID());
MDistributionRunLine drl = (MDistributionRunLine) MTable.get(getCtx(), MDistributionRunLine.Table_ID).getPO(record.getM_DistributionRunLine_ID(), get_TrxName());
BigDecimal ration = record.getRatio();
BigDecimal factor = ration.divide(total_ration, BigDecimal.ROUND_HALF_UP);
record.setQty(factor.multiply(drl.getTotalQty()));
record.saveEx();
}
log.fine("inserted #" + no);
return no;
}
use of org.compiere.model.MDistributionRunLine in project adempiere by adempiere.
the class DistributionRun method adjustAllocation.
// adjustAllocation
/**
* Adjust Run Line Allocation
* @param index run line index
* @throws Exception
*/
private void adjustAllocation(int index) throws Exception {
MDistributionRunLine runLine = m_runLines[index];
BigDecimal difference = runLine.getActualAllocationDiff();
if (difference.compareTo(Env.ZERO) == 0)
return;
// Adjust when difference is -1->1 or last difference is the same
boolean adjustBiggest = difference.abs().compareTo(Env.ONE) <= 0 || difference.abs().compareTo(runLine.getLastDifference().abs()) == 0;
log.fine("Line=" + runLine.getLine() + ", Diff=" + difference + ", Adjust=" + adjustBiggest);
// Adjust Biggest Amount
if (adjustBiggest) {
for (int i = 0; i < m_details.length; i++) {
MDistributionRunDetail detail = m_details[i];
if (runLine.getM_DistributionRunLine_ID() == detail.getM_DistributionRunLine_ID()) {
log.fine("Biggest - DetailAllocation=" + detail.getActualAllocation() + ", MaxAllocation=" + runLine.getMaxAllocation() + ", Qty Difference=" + difference);
if (detail.getActualAllocation().compareTo(runLine.getMaxAllocation()) == 0 && detail.isCanAdjust()) {
detail.adjustQty(difference);
detail.saveEx();
return;
}
}
}
// for all detail lines
throw new Exception("Cannot adjust Difference = " + difference + " - You need to change Total Qty or Min Qty");
} else // Distibute
{
// New Total Ratio
BigDecimal ratioTotal = Env.ZERO;
for (int i = 0; i < m_details.length; i++) {
MDistributionRunDetail detail = m_details[i];
if (runLine.getM_DistributionRunLine_ID() == detail.getM_DistributionRunLine_ID()) {
if (detail.isCanAdjust())
ratioTotal = ratioTotal.add(detail.getRatio());
}
}
if (ratioTotal.compareTo(Env.ZERO) == 0)
throw new Exception("Cannot distribute Difference = " + difference + " - You need to change Total Qty or Min Qty");
// Distribute
for (int i = 0; i < m_details.length; i++) {
MDistributionRunDetail detail = m_details[i];
if (runLine.getM_DistributionRunLine_ID() == detail.getM_DistributionRunLine_ID()) {
if (detail.isCanAdjust()) {
BigDecimal diffRatio = detail.getRatio().multiply(difference).divide(ratioTotal, // precision from total
BigDecimal.ROUND_HALF_UP);
log.fine("Detail=" + detail.toString() + ", Allocation=" + detail.getActualAllocation() + ", DiffRatio=" + diffRatio);
detail.adjustQty(diffRatio);
detail.saveEx();
}
}
}
}
runLine.setLastDifference(difference);
}
use of org.compiere.model.MDistributionRunLine in project adempiere by adempiere.
the class DistributionRun method isAllocationEqTotal.
// addAllocations
/**
* Is Allocation Equals Total
* @return true if allocation eq total
* @throws Exception
*/
private boolean isAllocationEqTotal() throws Exception {
boolean allocationEqTotal = true;
// Check total min qty & delta
for (int j = 0; j < m_runLines.length; j++) {
MDistributionRunLine runLine = m_runLines[j];
if (runLine.isActualMinGtTotal())
throw new Exception("Line " + runLine.getLine() + " Sum of Min Qty=" + runLine.getActualMin() + " is greater than Total Qty=" + runLine.getTotalQty());
if (allocationEqTotal && !runLine.isActualAllocationEqTotal())
allocationEqTotal = false;
}
// for all run lines
log.info("=" + allocationEqTotal);
return allocationEqTotal;
}
Aggregations