Bring in Manufacturing Light code from Adaxa / Paul Bowden
This commit is contained in:
parent
0785915c7b
commit
41338b001f
|
@ -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;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue