Bring in Manufacturing Light code from Adaxa / Paul Bowden

This commit is contained in:
Carlos Ruiz 2012-08-21 17:41:53 -05:00
parent 0785915c7b
commit 41338b001f
2 changed files with 202 additions and 155 deletions

View File

@ -22,6 +22,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.compiere.model.MBPartner; import org.compiere.model.MBPartner;
@ -35,6 +36,7 @@ import org.compiere.model.MOrg;
import org.compiere.model.MProduct; import org.compiere.model.MProduct;
import org.compiere.model.MProduction; import org.compiere.model.MProduction;
import org.compiere.model.MProductionLine; import org.compiere.model.MProductionLine;
import org.compiere.model.MReplenish;
import org.compiere.model.MRequisition; import org.compiere.model.MRequisition;
import org.compiere.model.MRequisitionLine; import org.compiere.model.MRequisitionLine;
import org.compiere.model.MStorage; import org.compiere.model.MStorage;
@ -758,7 +760,7 @@ public class ReplenishReportProduction extends SvrProcess
} }
} // create Distribution Order } // create Distribution Order
/** /**
* Create Requisition * Create Production
*/ */
private void createProduction() private void createProduction()
{ {
@ -775,24 +777,47 @@ public class ReplenishReportProduction extends SvrProcess
X_T_Replenish replenish = replenishs[i]; X_T_Replenish replenish = replenishs[i];
if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID()) if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID()); wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID());
production = new MProduction (getCtx(), 0, get_TrxName());
production.setDescription(Msg.getMsg(getCtx(), "Replenishment"));
// Set Org/WH
production.setAD_Org_ID(wh.getAD_Org_ID());
production.setM_Locator_ID(wh.getDefaultLocator().get_ID());
production.setM_Product_ID(replenish.getM_Product_ID());
production.setProductionQty(replenish.getQtyToOrder());
production.setMovementDate(Env.getContextAsDate(getCtx(), "#Date"));
production.saveEx();
production.createLines(false);
BigDecimal batchQty = null;
production.setIsCreated("Y"); for (MReplenish rep : MReplenish.getForProduct(getCtx(), replenish.getM_Product_ID(), get_TrxName()))
production.save(get_TrxName()); {
log.fine(production.toString()); if ( rep.getM_Warehouse_ID() == replenish.getM_Warehouse_ID())
noProds++; batchQty = rep.getQtyBatchSize();
info += " - " + production.getDocumentNo(); }
BigDecimal qtyToProduce = replenish.getQtyToOrder();
while ( qtyToProduce.compareTo(Env.ZERO) > 0)
{
BigDecimal qty = qtyToProduce;
if ( batchQty != null && batchQty.compareTo(Env.ZERO) > 0 && qtyToProduce.compareTo(batchQty) > 0)
{
qty = batchQty;
qtyToProduce = qtyToProduce.subtract(batchQty);
}
else
{
qtyToProduce = Env.ZERO;
}
production = new MProduction (getCtx(), 0, get_TrxName());
production.setDescription(Msg.getMsg(getCtx(), "Replenishment"));
// Set Org/WH
production.setAD_Org_ID(wh.getAD_Org_ID());
production.setM_Locator_ID(wh.getDefaultLocator().get_ID());
production.setM_Product_ID(replenish.getM_Product_ID());
production.setProductionQty(qty);
production.setMovementDate(Env.getContextAsDate(getCtx(), "#Date"));
production.saveEx();
production.createLines(false);
production.setIsCreated("Y");
production.save(get_TrxName());
log.fine(production.toString());
noProds++;
info += " - " + production.getDocumentNo();
}
} }
m_info = "#" + noProds + info; m_info = "#" + noProds + info;

View File

@ -27,6 +27,8 @@ public class MProduction extends X_M_Production {
/** Log */ /** Log */
private static CLogger m_log = CLogger.getCLogger (MProduction.class); private static CLogger m_log = CLogger.getCLogger (MProduction.class);
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private int lineno;
private int count;
public MProduction(Properties ctx, int M_Production_ID, String trxName) { public MProduction(Properties ctx, int M_Production_ID, String trxName) {
super(ctx, M_Production_ID, trxName); super(ctx, M_Production_ID, trxName);
@ -90,17 +92,13 @@ public class MProduction extends X_M_Production {
public int createLines(boolean mustBeStocked) { public int createLines(boolean mustBeStocked) {
int defaultLocator = 0; lineno = 100;
int lineno = 100; count = 0;
int count = 0;
// product to be produced // product to be produced
MProduct finishedProduct = new MProduct(getCtx(), getM_Product_ID(), get_TrxName()); MProduct finishedProduct = new MProduct(getCtx(), getM_Product_ID(), get_TrxName());
MLocator finishedLocator = MLocator.get(getCtx(), getM_Locator_ID());
int M_Warehouse_ID = finishedLocator.getM_Warehouse_ID();
int asi = 0;
MProductionLine line = new MProductionLine( this ); MProductionLine line = new MProductionLine( this );
line.setLine( lineno ); line.setLine( lineno );
@ -111,10 +109,25 @@ public class MProduction extends X_M_Production {
line.save(); line.save();
count++; count++;
createLines(mustBeStocked, finishedProduct, getProductionQty());
return count;
}
private int createLines(boolean mustBeStocked, MProduct finishedProduct, BigDecimal requiredQty) {
int defaultLocator = 0;
MLocator finishedLocator = MLocator.get(getCtx(), getM_Locator_ID());
int M_Warehouse_ID = finishedLocator.getM_Warehouse_ID();
int asi = 0;
// products used in production // products used in production
String sql = "SELECT M_ProductBom_ID, BOMQty" + " FROM M_Product_BOM" String sql = "SELECT M_ProductBom_ID, BOMQty" + " FROM M_Product_BOM"
+ " WHERE M_Product_ID=" + getM_Product_ID() + " ORDER BY Line"; + " WHERE M_Product_ID=" + finishedProduct.getM_Product_ID() + " ORDER BY Line";
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
@ -128,149 +141,158 @@ public class MProduction extends X_M_Production {
lineno = lineno + 10; lineno = lineno + 10;
int BOMProduct_ID = rs.getInt(1); int BOMProduct_ID = rs.getInt(1);
BigDecimal BOMQty = rs.getBigDecimal(2); BigDecimal BOMQty = rs.getBigDecimal(2);
BigDecimal BOMMovementQty = BOMQty.multiply(getProductionQty()); BigDecimal BOMMovementQty = BOMQty.multiply(requiredQty);
MProduct bomproduct = new MProduct(Env.getCtx(), BOMProduct_ID, get_TrxName()); MProduct bomproduct = new MProduct(Env.getCtx(), BOMProduct_ID, get_TrxName());
defaultLocator = bomproduct.getM_Locator_ID();
if ( defaultLocator == 0 )
defaultLocator = getM_Locator_ID();
if (!bomproduct.isStocked())
{
MProductionLine BOMLine = null;
BOMLine = new MProductionLine( this );
BOMLine.setLine( lineno );
BOMLine.setM_Product_ID( BOMProduct_ID );
BOMLine.setM_Locator_ID( defaultLocator );
BOMLine.setQtyUsed(BOMMovementQty );
BOMLine.setPlannedQty( BOMMovementQty );
BOMLine.save(get_TrxName());
lineno = lineno + 10; if ( bomproduct.isPhantom() )
count++;
}
else if (BOMMovementQty.signum() == 0)
{ {
MProductionLine BOMLine = null; createLines(mustBeStocked, bomproduct, BOMMovementQty);
BOMLine = new MProductionLine( this );
BOMLine.setLine( lineno );
BOMLine.setM_Product_ID( BOMProduct_ID );
BOMLine.setM_Locator_ID( defaultLocator );
BOMLine.setQtyUsed( BOMMovementQty );
BOMLine.setPlannedQty( BOMMovementQty );
BOMLine.save(get_TrxName());
lineno = lineno + 10;
count++;
} }
else else
{ {
// BOM stock info defaultLocator = bomproduct.getM_Locator_ID();
MStorage[] storages = null;
MProduct usedProduct = MProduct.get(getCtx(), BOMProduct_ID);
defaultLocator = usedProduct.getM_Locator_ID();
if ( defaultLocator == 0 ) if ( defaultLocator == 0 )
defaultLocator = getM_Locator_ID(); defaultLocator = getM_Locator_ID();
if (usedProduct == null || usedProduct.get_ID() == 0)
return 0;
MClient client = MClient.get(getCtx());
MProductCategory pc = MProductCategory.get(getCtx(),
usedProduct.getM_Product_Category_ID());
String MMPolicy = pc.getMMPolicy();
if (MMPolicy == null || MMPolicy.length() == 0)
{
MMPolicy = client.getMMPolicy();
}
storages = MStorage.getWarehouse(getCtx(), M_Warehouse_ID, BOMProduct_ID, 0, null,
MProductCategory.MMPOLICY_FiFo.equals(MMPolicy), true, 0, get_TrxName());
MProductionLine BOMLine = null; if (!bomproduct.isStocked())
int prevLoc = -1; {
int previousAttribSet = -1; MProductionLine BOMLine = null;
// Create lines from storage until qty is reached BOMLine = new MProductionLine( this );
for (int sl = 0; sl < storages.length; sl++) { BOMLine.setLine( lineno );
BOMLine.setM_Product_ID( BOMProduct_ID );
BigDecimal lineQty = storages[sl].getQtyOnHand(); BOMLine.setM_Locator_ID( defaultLocator );
if (lineQty.signum() != 0) { BOMLine.setQtyUsed(BOMMovementQty );
if (lineQty.compareTo(BOMMovementQty) > 0) BOMLine.setPlannedQty( BOMMovementQty );
lineQty = BOMMovementQty; BOMLine.save(get_TrxName());
lineno = lineno + 10;
int loc = storages[sl].getM_Locator_ID(); count++;
int slASI = storages[sl].getM_AttributeSetInstance_ID(); }
int locAttribSet = new MAttributeSetInstance(getCtx(), asi, else if (BOMMovementQty.signum() == 0)
get_TrxName()).getM_AttributeSet_ID(); {
MProductionLine BOMLine = null;
// roll up costing attributes if in the same locator BOMLine = new MProductionLine( this );
if (locAttribSet == 0 && previousAttribSet == 0 BOMLine.setLine( lineno );
&& prevLoc == loc) { BOMLine.setM_Product_ID( BOMProduct_ID );
BOMLine.setQtyUsed(BOMLine.getQtyUsed() BOMLine.setM_Locator_ID( defaultLocator );
.add(lineQty)); BOMLine.setQtyUsed( BOMMovementQty );
BOMLine.setPlannedQty(BOMLine.getQtyUsed()); BOMLine.setPlannedQty( BOMMovementQty );
BOMLine.save(get_TrxName()); BOMLine.save(get_TrxName());
} lineno = lineno + 10;
// otherwise create new line count++;
else { }
BOMLine = new MProductionLine( this ); else
BOMLine.setLine( lineno ); {
BOMLine.setM_Product_ID( BOMProduct_ID );
BOMLine.setM_Locator_ID( loc ); // BOM stock info
BOMLine.setQtyUsed( lineQty); MStorage[] storages = null;
BOMLine.setPlannedQty( lineQty); MProduct usedProduct = MProduct.get(getCtx(), BOMProduct_ID);
if ( slASI != 0 && locAttribSet != 0 ) // ie non costing attribute defaultLocator = usedProduct.getM_Locator_ID();
BOMLine.setM_AttributeSetInstance_ID(slASI); if ( defaultLocator == 0 )
BOMLine.save(get_TrxName()); defaultLocator = getM_Locator_ID();
if (usedProduct == null || usedProduct.get_ID() == 0)
lineno = lineno + 10; return 0;
count++;
} MClient client = MClient.get(getCtx());
prevLoc = loc; MProductCategory pc = MProductCategory.get(getCtx(),
previousAttribSet = locAttribSet; usedProduct.getM_Product_Category_ID());
// enough ? String MMPolicy = pc.getMMPolicy();
BOMMovementQty = BOMMovementQty.subtract(lineQty); if (MMPolicy == null || MMPolicy.length() == 0)
if (BOMMovementQty.signum() == 0) {
break; MMPolicy = client.getMMPolicy();
} }
} // for available storages
storages = MStorage.getWarehouse(getCtx(), M_Warehouse_ID, BOMProduct_ID, 0, null,
// fallback MProductCategory.MMPOLICY_FiFo.equals(MMPolicy), true, 0, get_TrxName());
if (BOMMovementQty.signum() != 0 ) {
if (!mustBeStocked) MProductionLine BOMLine = null;
{ int prevLoc = -1;
int previousAttribSet = -1;
// roll up costing attributes if in the same locator // Create lines from storage until qty is reached
if ( previousAttribSet == 0 for (int sl = 0; sl < storages.length; sl++) {
&& prevLoc == defaultLocator) {
BOMLine.setQtyUsed(BOMLine.getQtyUsed() BigDecimal lineQty = storages[sl].getQtyOnHand();
.add(BOMMovementQty)); if (lineQty.signum() != 0) {
BOMLine.setPlannedQty(BOMLine.getQtyUsed()); if (lineQty.compareTo(BOMMovementQty) > 0)
BOMLine.save(get_TrxName()); lineQty = BOMMovementQty;
int loc = storages[sl].getM_Locator_ID();
int slASI = storages[sl].getM_AttributeSetInstance_ID();
int locAttribSet = new MAttributeSetInstance(getCtx(), asi,
get_TrxName()).getM_AttributeSet_ID();
// roll up costing attributes if in the same locator
if (locAttribSet == 0 && previousAttribSet == 0
&& prevLoc == loc) {
BOMLine.setQtyUsed(BOMLine.getQtyUsed()
.add(lineQty));
BOMLine.setPlannedQty(BOMLine.getQtyUsed());
BOMLine.save(get_TrxName());
}
// otherwise create new line
else {
BOMLine = new MProductionLine( this );
BOMLine.setLine( lineno );
BOMLine.setM_Product_ID( BOMProduct_ID );
BOMLine.setM_Locator_ID( loc );
BOMLine.setQtyUsed( lineQty);
BOMLine.setPlannedQty( lineQty);
if ( slASI != 0 && locAttribSet != 0 ) // ie non costing attribute
BOMLine.setM_AttributeSetInstance_ID(slASI);
BOMLine.save(get_TrxName());
lineno = lineno + 10;
count++;
}
prevLoc = loc;
previousAttribSet = locAttribSet;
// enough ?
BOMMovementQty = BOMMovementQty.subtract(lineQty);
if (BOMMovementQty.signum() == 0)
break;
} }
// otherwise create new line } // for available storages
else {
// fallback
BOMLine = new MProductionLine( this ); if (BOMMovementQty.signum() != 0 ) {
BOMLine.setLine( lineno ); if (!mustBeStocked)
BOMLine.setM_Product_ID( BOMProduct_ID ); {
BOMLine.setM_Locator_ID( defaultLocator );
BOMLine.setQtyUsed( BOMMovementQty); // roll up costing attributes if in the same locator
BOMLine.setPlannedQty( BOMMovementQty); if ( previousAttribSet == 0
BOMLine.save(get_TrxName()); && prevLoc == defaultLocator) {
BOMLine.setQtyUsed(BOMLine.getQtyUsed()
lineno = lineno + 10; .add(BOMMovementQty));
count++; BOMLine.setPlannedQty(BOMLine.getQtyUsed());
BOMLine.save(get_TrxName());
}
// otherwise create new line
else {
BOMLine = new MProductionLine( this );
BOMLine.setLine( lineno );
BOMLine.setM_Product_ID( BOMProduct_ID );
BOMLine.setM_Locator_ID( defaultLocator );
BOMLine.setQtyUsed( BOMMovementQty);
BOMLine.setPlannedQty( BOMMovementQty);
BOMLine.save(get_TrxName());
lineno = lineno + 10;
count++;
}
}
else
{
throw new AdempiereUserError("Not enough stock of " + BOMProduct_ID);
} }
}
else
{
throw new AdempiereUserError("Not enough stock of " + BOMProduct_ID);
} }
} }
} }