Make To Kit functionality

http://sourceforge.net/tracker2/?func=detail&atid=879335&aid=2501713&group_id=176962

The kit functionality let define a BOM Type of Make To Kit Type when it is
combined with BOM Use Manufacturing ADempiere let create a Manufacturing
Order from Standard Sales Order this functionality is very similar to Make
To Order but with de different that when a Customer Shipment for this Sales
Order is completed the Manufacturing Order is close , finish product is
receipt and the components are issue automatically.
This commit is contained in:
vpj-cd 2009-01-12 18:39:01 +00:00
parent 9e72e117e6
commit 0824224a28
10 changed files with 693 additions and 340 deletions

View File

@ -35,6 +35,17 @@ import org.compiere.util.Env;
*/ */
public class MDocType extends X_C_DocType public class MDocType extends X_C_DocType
{ {
/**
* Return the first Doc Type for this BaseType
* @param DocBaseType
* @return
*/
static public int getDocType(String DocBaseType)
{
MDocType[] doc = MDocType.getOfDocBaseType(Env.getCtx(), DocBaseType);
return doc.length > 0 ? doc[0].get_ID() : 0;
}
/** /**
* Get Client Document Type with DocBaseType * Get Client Document Type with DocBaseType
* @param ctx context * @param ctx context

View File

@ -176,32 +176,60 @@ public class LiberoValidator implements ModelValidator
public String docValidate (PO po, int timing) public String docValidate (PO po, int timing)
{ {
log.info(po.get_TableName() + " Timing: "+timing); log.info(po.get_TableName() + " Timing: "+timing);
if(po instanceof MInOut && timing == TIMING_BEFORE_COMPLETE)
{
MInOut inout = (MInOut)po;
if(inout.isSOTrx())
{
final String whereClause = "C_OrderLine_ID IS NOT NULL AND EXISTS ( SELECT 1 FROM C_OrderLine ol , M_InOutLine iol WHERE ol.C_OrderLine_ID=iol.C_OrderLine_ID AND iol.M_InOut_ID=? )";
Collection<MPPOrder> orders = new Query(po.getCtx(), MPPOrder.Table_Name, whereClause, po.get_TrxName())
.setParameters(new Object[]{inout.getM_InOut_ID()})
.list();
for(MPPOrder order : orders)
{
String description = order.getDescription() != null ? order.getDescription() : ""
+ Msg.translate(inout.getCtx(), MInOut.COLUMNNAME_M_InOut_ID)
+ " : "
+ Msg.translate(inout.getCtx(), MInOut.COLUMNNAME_DocumentNo);
order.setDescription(description);
order.closeIt();
order.setDocStatus(MPPOrder.DOCACTION_Close);
order.setDocAction(MPPOrder.DOCACTION_None);
order.saveEx();
}
}
}
else
{
}
if (po instanceof MInOut && timing == TIMING_AFTER_COMPLETE) if (po instanceof MInOut && timing == TIMING_AFTER_COMPLETE)
{ {
MInOut inout = (MInOut)po; MInOut inout = (MInOut)po;
for (MInOutLine line : inout.getLines())
{ for (MInOutLine line : inout.getLines())
String whereClause = "C_OrderLine_ID=? AND PP_Cost_Collector_ID IS NOT NULL";
Collection<MOrderLine> olines = new Query(po.getCtx(), MOrderLine.Table_Name, whereClause, po.get_TrxName())
.setParameters(new Object[]{line.getC_OrderLine_ID()})
.list();
for (MOrderLine oline : olines)
{ {
if(oline.getQtyOrdered().compareTo(oline.getQtyDelivered()) >= 0) final String whereClause = "C_OrderLine_ID=? AND PP_Cost_Collector_ID IS NOT NULL";
Collection<MOrderLine> olines = new Query(po.getCtx(), MOrderLine.Table_Name, whereClause, po.get_TrxName())
.setParameters(new Object[]{line.getC_OrderLine_ID()})
.list();
for (MOrderLine oline : olines)
{ {
MPPCostCollector cc = new MPPCostCollector(po.getCtx(), oline.getPP_Cost_Collector_ID(), po.get_TrxName()); if(oline.getQtyOrdered().compareTo(oline.getQtyDelivered()) >= 0)
String docStatus = cc.completeIt(); {
cc.setDocStatus(docStatus); MPPCostCollector cc = new MPPCostCollector(po.getCtx(), oline.getPP_Cost_Collector_ID(), po.get_TrxName());
cc.setDocAction(MPPCostCollector.DOCACTION_Close); String docStatus = cc.completeIt();
cc.saveEx(); cc.setDocStatus(docStatus);
return Msg.translate(po.getCtx(), "PP_Order_ID") cc.setDocAction(MPPCostCollector.DOCACTION_Close);
+":"+cc.getPP_Order().getDocumentNo() cc.saveEx();
+Msg.translate(po.getCtx(),"PP_Order_Node_ID") return Msg.translate(po.getCtx(), "PP_Order_ID")
+":"+cc.getPP_Order_Node().getValue(); +":"+cc.getPP_Order().getDocumentNo()
+Msg.translate(po.getCtx(),"PP_Order_Node_ID")
+":"+cc.getPP_Order_Node().getValue();
}
} }
} }
} }
}
return null; return null;
} // docValidate } // docValidate

View File

@ -854,7 +854,7 @@ public class MPPCostCollector extends X_PP_Cost_Collector implements DocAction
// //
// If Product is not Purchased or is not Service, then it is not a subcontracting candidate [SKIP] // If Product is not Purchased or is not Service, then it is not a subcontracting candidate [SKIP]
MProduct product = MProduct.get(getCtx(), subcontract.getM_Product_ID()); MProduct product = MProduct.get(getCtx(), subcontract.getM_Product_ID());
if(!product.isPurchased() && MProduct.PRODUCTTYPE_Service.equals(product.getProductType())) if(!product.isPurchased() || !MProduct.PRODUCTTYPE_Service.equals(product.getProductType()))
continue; continue;
// //

View File

@ -29,6 +29,7 @@ import org.compiere.model.MLocator;
import org.compiere.model.MOrder; import org.compiere.model.MOrder;
import org.compiere.model.MOrderLine; import org.compiere.model.MOrderLine;
import org.compiere.model.MProduct; import org.compiere.model.MProduct;
import org.compiere.model.MRefList;
import org.compiere.model.MRequisition; import org.compiere.model.MRequisition;
import org.compiere.model.MRequisitionLine; import org.compiere.model.MRequisitionLine;
import org.compiere.model.MResource; import org.compiere.model.MResource;
@ -40,6 +41,7 @@ import org.compiere.process.DocAction;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.TimeUtil; import org.compiere.util.TimeUtil;
import org.compiere.wf.MWorkflow; import org.compiere.wf.MWorkflow;
@ -367,10 +369,16 @@ public class MPPMRP extends X_PP_MRP
MPPOrder order = MPPOrder.forC_OrderLine_ID(ol.getCtx(), ol.get_ID(), ol.get_TrxName()); MPPOrder order = MPPOrder.forC_OrderLine_ID(ol.getCtx(), ol.get_ID(), ol.get_TrxName());
if (order == null) if (order == null)
{ {
final String whereClause = MPPProductBOM.COLUMNNAME_BOMType+"=?" final String whereClause = MPPProductBOM.COLUMNNAME_BOMType+"=? "
+" OR "+MPPProductBOM.COLUMNNAME_BOMType+"=? "
+" AND "+MPPProductBOM.COLUMNNAME_BOMUse+"=?"
+" AND "+MPPProductBOM.COLUMNNAME_M_Product_ID+"=?"; +" AND "+MPPProductBOM.COLUMNNAME_M_Product_ID+"=?";
MPPProductBOM bom = new Query(ol.getCtx(), MPPProductBOM.Table_Name, whereClause, null) MPPProductBOM bom = new Query(ol.getCtx(), MPPProductBOM.Table_Name, whereClause, null)
.setParameters(new Object[]{MPPProductBOM.BOMTYPE_Make_To_Order, ol.getM_Product_ID()}) .setParameters(new Object[]{
MPPProductBOM.BOMTYPE_Make_To_Order,
MPPProductBOM.BOMTYPE_Make_To_Kit,
MPPProductBOM.BOMUSE_Manufacturing,
ol.getM_Product_ID()})
.firstOnly(); .firstOnly();
MPPProductPlanning pp = null; MPPProductPlanning pp = null;
@ -385,6 +393,10 @@ public class MPPMRP extends X_PP_MRP
{ {
bom = null; bom = null;
} }
if(bom != null && !MPPProductBOM.BOMTYPE_Make_To_Kit.equals(bom.getBOMType()))
{
bom = null;
}
} }
} }
if (bom != null) if (bom != null)
@ -403,6 +415,11 @@ public class MPPMRP extends X_PP_MRP
int duration = MPPMRP.getDays(ol.getCtx(), plant_id, workflow.get_ID(), ol.getQtyOrdered(), ol.get_TrxName()).intValue(); int duration = MPPMRP.getDays(ol.getCtx(), plant_id, workflow.get_ID(), ol.getQtyOrdered(), ol.get_TrxName()).intValue();
// //
order = new MPPOrder(ol.getCtx(), 0 , ol.get_TrxName()); order = new MPPOrder(ol.getCtx(), 0 , ol.get_TrxName());
order.setDescription( Msg.translate(ol.getCtx(),MRefList.getListName(ol.getCtx(), MPPOrderBOM.BOMTYPE_AD_Reference_ID, bom.getBOMType()))
+ " "
+ Msg.translate(ol.getCtx(), MOrder.COLUMNNAME_C_Order_ID)
+ " : "
+ o.getDocumentNo());
order.setC_OrderLine_ID(ol.getC_OrderLine_ID()); order.setC_OrderLine_ID(ol.getC_OrderLine_ID());
order.setS_Resource_ID(plant_id); order.setS_Resource_ID(plant_id);
order.setM_Warehouse_ID(ol.getM_Warehouse_ID()); order.setM_Warehouse_ID(ol.getM_Warehouse_ID());
@ -420,7 +437,8 @@ public class MPPMRP extends X_PP_MRP
order.setQty(ol.getQtyOrdered()); order.setQty(ol.getQtyOrdered());
order.setPriorityRule(MPPOrder.PRIORITYRULE_High); order.setPriorityRule(MPPOrder.PRIORITYRULE_High);
order.saveEx(); order.saveEx();
order.prepareIt(); order.setDocStatus(order.prepareIt());
order.setDocAction(MPPOrder.ACTION_Complete);
order.saveEx(); order.saveEx();
} }
} }

View File

@ -21,17 +21,22 @@ import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.Vector;
import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DocTypeNotFoundException; import org.adempiere.exceptions.DocTypeNotFoundException;
import org.compiere.apps.ADialog;
import org.compiere.minigrid.IDColumn;
import org.compiere.model.MAcctSchema; import org.compiere.model.MAcctSchema;
import org.compiere.model.MClient; import org.compiere.model.MClient;
import org.compiere.model.MCost; import org.compiere.model.MCost;
import org.compiere.model.MDocType; import org.compiere.model.MDocType;
import org.compiere.model.MProduct; import org.compiere.model.MProduct;
import org.compiere.model.MProject; import org.compiere.model.MProject;
import org.compiere.model.MRefList;
import org.compiere.model.MResource; import org.compiere.model.MResource;
import org.compiere.model.MStorage; import org.compiere.model.MStorage;
import org.compiere.model.MTable; import org.compiere.model.MTable;
@ -47,6 +52,8 @@ import org.compiere.process.DocAction;
import org.compiere.process.DocumentEngine; import org.compiere.process.DocumentEngine;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.wf.MWFNode; import org.compiere.wf.MWFNode;
import org.compiere.wf.MWFNodeNext; import org.compiere.wf.MWFNodeNext;
import org.compiere.wf.MWorkflow; import org.compiere.wf.MWorkflow;
@ -58,9 +65,7 @@ import org.compiere.wf.MWorkflow;
* Use DocAction and C_DocTypeTarget_ID instead. * Use DocAction and C_DocTypeTarget_ID instead.
* *
* @author Victor Perez www.e-evolution.com * @author Victor Perez www.e-evolution.com
* @version $Id: MOrder.java,v 1.57 2004/05/21 02:27:38 vpj-cd Exp $ * @author Teo Sarca, www.arhipac.ro
*
* @author Teo Sarca, www.arhipac.ro
*/ */
public class MPPOrder extends X_PP_Order implements DocAction public class MPPOrder extends X_PP_Order implements DocAction
{ {
@ -429,9 +434,9 @@ public class MPPOrder extends X_PP_Order implements DocAction
M_Locator_ID = MStorage.getM_Locator_ID(getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), ordered, M_Locator_ID = MStorage.getM_Locator_ID(getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), ordered,
get_TrxName()); get_TrxName());
// Get default Location // Get default Location
if (M_Locator_ID == 0) { if (M_Locator_ID == 0)
MWarehouse wh = MWarehouse.get(getCtx(), getM_Warehouse_ID()); {
M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID(); M_Locator_ID = getM_Locator_ID();
} }
//4Layers - Necessary to clear order quantities when called from closeIt //4Layers - Necessary to clear order quantities when called from closeIt
if (DOCACTION_Close.equals(getDocAction())) if (DOCACTION_Close.equals(getDocAction()))
@ -605,6 +610,90 @@ public class MPPOrder extends X_PP_Order implements DocAction
} }
} }
MPPOrderBOM obom = (MPPOrderBOM)getMPPOrderBOM();
// Auto receipt and issue for kit
if (MPPOrderBOM.BOMTYPE_Make_To_Kit.equals(obom.getBOMType()) && MPPOrderBOM.BOMUSE_Manufacturing.equals(obom.getBOMUse()))
{
if(!MPPOrder.DOCSTATUS_Completed.equals(getDocStatus()))
throw new AdempiereException( Msg.translate(getCtx(),MRefList.getListName(getCtx(), MPPOrderBOM.BOMTYPE_AD_Reference_ID, MPPOrderBOM.BOMTYPE_Make_To_Kit))
+ " "
+ Msg.translate(getCtx(), MPPOrder.COLUMNNAME_PP_Order_ID)
+" : "
+ getDocumentNo()
+ " "+Msg.getMsg(getCtx(), "ShipmentCreateDocNotCompleted"));
ArrayList[][] issue = new ArrayList[m_lines.length][1];
Timestamp today = new Timestamp(System.currentTimeMillis());
int row = 0;
for (int i = 0; i < getLines().length ; i++)
{
MPPOrderBOMLine line = m_lines[i];
IDColumn id = new IDColumn(line.get_ID());
if(MPPOrderBOMLine.ISSUEMETHOD_Backflush.equals(line.getIssueMethod()))
id.setSelected(true);
else
id.setSelected(false);
ArrayList<Object> data = new ArrayList<Object>();
data.add(id); //0 - ASI
data.add(line.isCritical()); //1 - Critical
MProduct product = (MProduct) line.getM_Product();
data.add(product.getValue()); //2 - Value
KeyNamePair productKey = new KeyNamePair(product.get_ID(),product.getName());
data.add(productKey); //3 - KeyNamePair Product
data.add(line.getQtyRequiered()); //4 - QtyToDeliver
data.add(Env.ZERO); //5 - QtyScrapComponent
issue[i][0] = data;
}
boolean isCompleteQtyDeliver = MPPOrder.isAvailableQty(this, issue ,today);
if (!isCompleteQtyDeliver)
{
throw new AdempiereException("@NoQtyAvailable@");
}
for(int i = 0; i < issue.length; i++ )
{
IDColumn id = (IDColumn) issue[i][0].get(0);
Boolean isCritical = (Boolean) issue[i][0].get(1);
String value = (String)issue[i][0].get(2);
KeyNamePair productkey = (KeyNamePair) issue[i][0].get(3);
int M_Product_ID = productkey.getKey();
BigDecimal qtyToDeliver = (BigDecimal)issue[i][0].get(4);
BigDecimal qtyScrapComponent = (BigDecimal) issue[i][0].get(5);
MStorage[] storages = MPPOrder.getStorages(
M_Product_ID,
getM_Warehouse_ID(),
0,
getM_AttributeSetInstance_ID(),
1, today);
MPPOrder.createIssue(
this,
id.getRecord_ID(),
today, qtyToDeliver,
qtyScrapComponent,
Env.ZERO,
storages,
get_TrxName());
}
MPPOrder.createReceipt(
this,
today ,
this.getQtyDelivered(),
this.getQtyOpen(),
this.getQtyScrap(),
this.getQtyReject(),
this.getM_Locator_ID(),
this.getM_AttributeSetInstance_ID(), true, get_TrxName());
return DocAction.ACTION_None;
}
setProcessed(true); setProcessed(true);
setDocAction(DOCACTION_Close); setDocAction(DOCACTION_Close);
@ -650,31 +739,22 @@ public class MPPOrder extends X_PP_Order implements DocAction
public boolean closeIt() public boolean closeIt()
{ {
log.info(toString()); log.info(toString());
if(MPPOrder.DOCSTATUS_Closed.equals(getDocStatus()))
return true;
if(!MPPOrder.DOCSTATUS_Completed.equals(this.getDocStatus()))
{
String DocStatus = completeIt();
setDocStatus(DocStatus);
setDocAction(MPPOrder.ACTION_Close);
}
// Before Close // Before Close
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE); m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
if (m_processMsg != null) if (m_processMsg != null)
return false; return false;
// Close Not delivered Qty - SO/PO
MPPOrderBOMLine[] lines = getLines();
/*
for (int i = 0; i < lines.length; i++)
{
MPPOrderBOMLine line = lines[i];
BigDecimal old = line.getQtyRequiered();
if (old.compareTo(line.getQtyDelivered()) != 0)
{
//line.setQtyLostSales(line.getQtyRequiered().subtract(line.getQtyDelivered()));
line.setQtyRequiered(line.getQtyDelivered());
// QtyEntered unchanged
//line.addDescription("Close (" + old + ")");
line.save(get_TrxName());
}
}*/
orderStock(); // Clear Ordered Quantities orderStock(); // Clear Ordered Quantities
reserveStock(lines); // Clear Reservations reserveStock(getLines()); // Clear Reservations
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE); m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
if (m_processMsg != null) if (m_processMsg != null)
@ -699,8 +779,14 @@ public class MPPOrder extends X_PP_Order implements DocAction
public boolean reActivateIt() public boolean reActivateIt()
{ {
log.info("reActivateIt - " + toString()); // After reActivate
return false; m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE);
if (m_processMsg != null)
return false;
setDocAction(DOCACTION_Complete);
setProcessed(false);
return true;
} // reActivateIt } // reActivateIt
public int getDoc_User_ID() public int getDoc_User_ID()
@ -951,6 +1037,326 @@ public class MPPOrder extends X_PP_Order implements DocAction
} // workflow valid from/to } // workflow valid from/to
} }
/**
* Create Receipt Finish Good
* @param pp_order
* @param movementDate
* @param deliveredQty
* @param toDeliverQty
* @param scrapQty
* @param rejectQty
* @param M_Locator_ID
* @param M_AttributeSetInstance_ID
* @param IsCloseDocument
* @param trxName
*/
static public void createReceipt(MPPOrder pp_order,
Timestamp movementDate,
BigDecimal deliveredQty,
BigDecimal toDeliverQty,
BigDecimal scrapQty,
BigDecimal rejectQty,
int M_Locator_ID,
int M_AttributeSetInstance_ID,
boolean IsCloseDocument,
String trxName)
{
if (toDeliverQty.signum() != 0 || scrapQty.signum() != 0 || rejectQty.signum() != 0)
{
createCollector(pp_order, pp_order.getM_Product_ID(),
M_Locator_ID,
M_AttributeSetInstance_ID,
movementDate,
toDeliverQty, scrapQty, rejectQty,
MDocType.getDocType(MDocType.DOCBASETYPE_ManufacturingOrder),
0, // PP_Order_BOMLine_ID
MPPCostCollector.COSTCOLLECTORTYPE_MaterialReceipt,
trxName
);
}
if (IsCloseDocument)
{
pp_order.setDateFinish(movementDate);
pp_order.closeIt();
pp_order.saveEx();
}
pp_order.setDateDelivered(movementDate);
if (pp_order.getDateStart() == null)
{
pp_order.setDateStart(movementDate);
}
BigDecimal DQ = deliveredQty;
BigDecimal SQ = scrapQty;
BigDecimal OQ = toDeliverQty;
if (DQ.add(SQ).compareTo(OQ) >= 0)
{
pp_order.setDateFinish(movementDate);
}
pp_order.saveEx(trxName);
}
/**
* Create Issue
* @param PP_OrderBOMLine_ID
* @param movementdate
* @param qty
* @param qtyScrap
* @param qtyReject
* @param storages
*/
public static void createIssue(MPPOrder pp_order, int PP_OrderBOMLine_ID,
Timestamp movementdate,
BigDecimal qty, BigDecimal qtyScrap, BigDecimal qtyReject,
MStorage[] storages ,String trxName)
{
if (qty.signum() == 0)
return;
BigDecimal toIssue = qty.add(qtyScrap);
for (MStorage storage : storages)
{
// TODO Selection of ASI
if (storage.getQtyOnHand().signum() == 0)
continue;
BigDecimal qtyIssue = toIssue.min(storage.getQtyOnHand());
//log.fine("ToIssue: " + issue);
MPPOrderBOMLine PP_orderbomLine = new MPPOrderBOMLine(Env.getCtx(), PP_OrderBOMLine_ID, null);
//create record for negative and positive transaction
if (qtyIssue.signum() != 0 || qtyScrap.signum() != 0 || qtyReject.signum() != 0)
{
String CostCollectorType = null;
int C_DocType_ID = MDocType.getDocType(MDocType.DOCBASETYPE_ManufacturingOrder);
// Method Variance
if (PP_orderbomLine.getQtyBatch().signum() == 0
&& PP_orderbomLine.getQtyBOM().signum() == 0)
{
CostCollectorType = MPPCostCollector.COSTCOLLECTORTYPE_MethodChangeVariance;
}
// Order Issue
else
{
CostCollectorType = MPPCostCollector.COSTCOLLECTORTYPE_ComponentIssue;
}
//
createCollector (pp_order,
PP_orderbomLine.getM_Product_ID(),
storage.getM_Locator_ID(),
storage.getM_AttributeSetInstance_ID(),
movementdate,
qtyIssue, qtyScrap, qtyReject,
C_DocType_ID,
PP_OrderBOMLine_ID,
CostCollectorType, // Production "-"
trxName
);
}
toIssue = toIssue.subtract(qtyIssue);
if (toIssue.signum() == 0)
break;
}
//
if (toIssue.signum() != 0)
{
// should not happen because we validate Qty On Hand on start of this process
throw new AdempiereException("Should not happen toIssue="+toIssue);
}
}
/**
* Create Collector Cost
* @param pp_order
* @param M_Product_ID
* @param M_Locator_ID
* @param M_AttributeSetInstance_ID
* @param movementdate
* @param qty
* @param scrap
* @param reject
* @param C_DocType_ID
* @param PP_Order_BOMLine_ID
* @param CostCollectorType
* @param trxName
*/
static private void createCollector (MPPOrder pp_order ,
int M_Product_ID,
int M_Locator_ID,
int M_AttributeSetInstance_ID,
Timestamp movementdate,
BigDecimal qty,
BigDecimal scrap,
BigDecimal reject,
int C_DocType_ID,
int PP_Order_BOMLine_ID,
String CostCollectorType,
String trxName
)
{
MPPCostCollector PP_Cost_Collector = new MPPCostCollector(Env.getCtx(), 0, trxName);
PP_Cost_Collector.setPP_Order_ID(pp_order.getPP_Order_ID());
PP_Cost_Collector.setPP_Order_BOMLine_ID(PP_Order_BOMLine_ID);
PP_Cost_Collector.setAD_OrgTrx_ID(pp_order.getAD_OrgTrx_ID());
PP_Cost_Collector.setC_Activity_ID(pp_order.getC_Activity_ID());
PP_Cost_Collector.setC_Campaign_ID(pp_order.getC_Campaign_ID());
PP_Cost_Collector.setC_DocType_ID(C_DocType_ID);
PP_Cost_Collector.setC_DocTypeTarget_ID(C_DocType_ID);
PP_Cost_Collector.setCostCollectorType(CostCollectorType);
PP_Cost_Collector.setC_Project_ID(pp_order.getC_Project_ID());
PP_Cost_Collector.setDescription(pp_order.getDescription());
PP_Cost_Collector.setDocAction(MPPCostCollector.ACTION_Complete);
PP_Cost_Collector.setDocStatus(MPPCostCollector.DOCSTATUS_Drafted);
PP_Cost_Collector.setIsActive(true);
PP_Cost_Collector.setM_Warehouse_ID(pp_order.getM_Warehouse_ID());
PP_Cost_Collector.setM_Locator_ID(M_Locator_ID);
PP_Cost_Collector.setM_AttributeSetInstance_ID(M_AttributeSetInstance_ID);
PP_Cost_Collector.setS_Resource_ID(pp_order.getS_Resource_ID());
PP_Cost_Collector.setMovementDate(movementdate);
PP_Cost_Collector.setDateAcct(movementdate);
PP_Cost_Collector.setMovementQty(qty);
PP_Cost_Collector.setScrappedQty(scrap);
PP_Cost_Collector.setQtyReject(reject);
PP_Cost_Collector.setPosted(false);
PP_Cost_Collector.setProcessed(false);
PP_Cost_Collector.setProcessing(false);
PP_Cost_Collector.setUser1_ID(pp_order.getUser1_ID());
PP_Cost_Collector.setUser2_ID(pp_order.getUser2_ID());
PP_Cost_Collector.setM_Product_ID(M_Product_ID);
PP_Cost_Collector.saveEx();
if (!PP_Cost_Collector.processIt(MPPCostCollector.DOCACTION_Complete)) {
throw new AdempiereException(PP_Cost_Collector.getProcessMsg());
}
PP_Cost_Collector.saveEx();
}
/**
* get if Component is Available
* @param MPPOrdrt Manufacturing order
* @param ArrayList Issues
* @param minGuaranteeDate Guarantee Date
* @return true when the qty available is enough
*/
public static boolean isAvailableQty(MPPOrder order ,ArrayList[][] issue,Timestamp minGuaranteeDate)
{
boolean isCompleteQtyDeliver = false;
int ANY_ASI = 1;
for(int i = 0; i < issue.length; i++ )
{
IDColumn id = (IDColumn) issue[i][0].get(0);
if (id == null || !id.isSelected())
{
continue;
}
Boolean isCritical = (Boolean)issue[i][0].get(1);
String value = (String)issue[i][0].get(2);
KeyNamePair productkey = (KeyNamePair) issue[i][0].get(3);
int M_Product_ID = productkey.getKey();
BigDecimal qtyToDeliver = (BigDecimal)issue[i][0].get(4);
BigDecimal qtyScrapComponent = (BigDecimal) issue[i][0].get(5);
MProduct product = MProduct.get(order.getCtx(), M_Product_ID);
if (product != null && product.get_ID() != 0 && product.isStocked())
{
int M_AttributeSetInstance_ID = ANY_ASI;
if (value == null && id.isSelected())
{
M_AttributeSetInstance_ID = (Integer)id.getRecord_ID();
}
MStorage[] storages = MPPOrder.getStorages(
M_Product_ID,
order.getM_Warehouse_ID(),
M_AttributeSetInstance_ID,
order.getM_AttributeSetInstance_ID(),
ANY_ASI,
minGuaranteeDate);
if (M_AttributeSetInstance_ID == ANY_ASI)
{
BigDecimal toIssue = qtyToDeliver.add(qtyScrapComponent);
for (MStorage storage : storages)
{
// TODO Selection of ASI
if (storage.getQtyOnHand().signum() == 0)
continue;
BigDecimal issueActual = toIssue.min(storage.getQtyOnHand());
toIssue = toIssue.subtract(issueActual);
if (toIssue.signum() <= 0)
break;
}
}
else
{
BigDecimal qtydelivered = qtyToDeliver;
qtydelivered.setScale(4, BigDecimal.ROUND_HALF_UP);
qtydelivered = Env.ZERO;
}
BigDecimal onHand = Env.ZERO;
for (MStorage storage : storages)
{
onHand = onHand.add(storage.getQtyOnHand());
}
isCompleteQtyDeliver = onHand.compareTo(qtyToDeliver.add(qtyScrapComponent)) >= 0;
if (!isCompleteQtyDeliver)
break;
}
} // for each line
return isCompleteQtyDeliver;
}
public static MStorage[] getStorages(
int m_M_Product_ID, int M_Warehouse_ID,
int M_ASI_ID,
int O_ASI_ID,
int ANY_ASI,
Timestamp minGuaranteeDate)
{
Properties ctx = Env.getCtx();
MProduct product = MProduct.get(ctx, m_M_Product_ID);
if (product != null && product.get_ID() != 0 && product.isStocked()) {
String MMPolicy = product.getMMPolicy();
return MStorage.getWarehouse(ctx,
M_Warehouse_ID,
m_M_Product_ID,
M_ASI_ID == ANY_ASI ? O_ASI_ID : M_ASI_ID,
product.getM_AttributeSet_ID(),
true, // all attribute set instances
minGuaranteeDate,
MClient.MMPOLICY_FiFo.equals(MMPolicy),
null // no trx
);
}
else {
return new MStorage[0];
}
}
/**
* Default Location
* @return
*/
private int getM_Locator_ID()
{
MWarehouse wh = MWarehouse.get(getCtx(), getM_Warehouse_ID());
return wh.getDefaultLocator().getM_Locator_ID();
}
public String toString() public String toString()
{ {
StringBuffer sb = new StringBuffer("MPPOrder[").append(get_ID()) StringBuffer sb = new StringBuffer("MPPOrder[").append(get_ID())

View File

@ -98,6 +98,8 @@ public class X_PP_Order_BOM extends PO implements I_PP_Order_BOM, I_Persistent
public static final String BOMTYPE_Repair = "R"; public static final String BOMTYPE_Repair = "R";
/** Product Configure = C */ /** Product Configure = C */
public static final String BOMTYPE_ProductConfigure = "C"; public static final String BOMTYPE_ProductConfigure = "C";
/** Make-To-Kit = K */
public static final String BOMTYPE_Make_To_Kit = "K";
/** Set BOM Type. /** Set BOM Type.
@param BOMType @param BOMType
Type of BOM Type of BOM
@ -105,8 +107,8 @@ public class X_PP_Order_BOM extends PO implements I_PP_Order_BOM, I_Persistent
public void setBOMType (String BOMType) public void setBOMType (String BOMType)
{ {
if (BOMType == null || BOMType.equals("A") || BOMType.equals("O") || BOMType.equals("P") || BOMType.equals("S") || BOMType.equals("F") || BOMType.equals("M") || BOMType.equals("R") || BOMType.equals("C")); if (BOMType == null || BOMType.equals("A") || BOMType.equals("O") || BOMType.equals("P") || BOMType.equals("S") || BOMType.equals("F") || BOMType.equals("M") || BOMType.equals("R") || BOMType.equals("C") || BOMType.equals("K"));
else throw new IllegalArgumentException ("BOMType Invalid value - " + BOMType + " - Reference_ID=347 - A - O - P - S - F - M - R - C"); else throw new IllegalArgumentException ("BOMType Invalid value - " + BOMType + " - Reference_ID=347 - A - O - P - S - F - M - R - C - K");
set_Value (COLUMNNAME_BOMType, BOMType); set_Value (COLUMNNAME_BOMType, BOMType);
} }

View File

@ -97,6 +97,8 @@ public class X_PP_Product_BOM extends PO implements I_PP_Product_BOM, I_Persiste
public static final String BOMTYPE_Repair = "R"; public static final String BOMTYPE_Repair = "R";
/** Product Configure = C */ /** Product Configure = C */
public static final String BOMTYPE_ProductConfigure = "C"; public static final String BOMTYPE_ProductConfigure = "C";
/** Make-To-Kit = K */
public static final String BOMTYPE_Make_To_Kit = "K";
/** Set BOM Type. /** Set BOM Type.
@param BOMType @param BOMType
Type of BOM Type of BOM
@ -104,8 +106,8 @@ public class X_PP_Product_BOM extends PO implements I_PP_Product_BOM, I_Persiste
public void setBOMType (String BOMType) public void setBOMType (String BOMType)
{ {
if (BOMType == null || BOMType.equals("A") || BOMType.equals("O") || BOMType.equals("P") || BOMType.equals("S") || BOMType.equals("F") || BOMType.equals("M") || BOMType.equals("R") || BOMType.equals("C")); if (BOMType == null || BOMType.equals("A") || BOMType.equals("O") || BOMType.equals("P") || BOMType.equals("S") || BOMType.equals("F") || BOMType.equals("M") || BOMType.equals("R") || BOMType.equals("C") || BOMType.equals("K"));
else throw new IllegalArgumentException ("BOMType Invalid value - " + BOMType + " - Reference_ID=347 - A - O - P - S - F - M - R - C"); else throw new IllegalArgumentException ("BOMType Invalid value - " + BOMType + " - Reference_ID=347 - A - O - P - S - F - M - R - C - K");
set_Value (COLUMNNAME_BOMType, BOMType); set_Value (COLUMNNAME_BOMType, BOMType);
} }

View File

@ -196,7 +196,7 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
/** /**
* Fill Picks * Fill Picks
* Column_ID from C_Order * Column_ID from C_Order
* This is only run as part of the windows initialisation process * This is only run as part of the windows initialization process
* @throws Exception if Lookups cannot be initialized * @throws Exception if Lookups cannot be initialized
*/ */
private void fillPicks() throws Exception { private void fillPicks() throws Exception {
@ -423,10 +423,10 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
northPanel.add(attribute, new GridBagConstraints(5, 7, 1, 1, 0.0, 0.0, northPanel.add(attribute, new GridBagConstraints(5, 7, 1, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(5, 5, 5, 5), 0, 0)); new Insets(5, 5, 5, 5), 0, 0));
northPanel.add(backflushGroupLabel, new GridBagConstraints(4, 5, 1, 1, 0.0, 0.0, northPanel.add(backflushGroupLabel, new GridBagConstraints(2, 5, 1, 1, 0.0, 0.0,
GridBagConstraints.EAST, GridBagConstraints.NONE, GridBagConstraints.EAST, GridBagConstraints.NONE,
new Insets(5, 5, 5, 5), 0, 0)); new Insets(5, 5, 5, 5), 0, 0));
northPanel.add(backflushGroup, new GridBagConstraints(5, 5, 1, 1, 0.0, 0.0, northPanel.add(backflushGroup, new GridBagConstraints(3, 5, 1, 1, 0.0, 0.0,
GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
new Insets(5, 5, 5, 5), 0, 0)); new Insets(5, 5, 5, 5), 0, 0));
@ -664,10 +664,12 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
IDColumn id = new IDColumn(rs.getInt(1)); IDColumn id = new IDColumn(rs.getInt(1));
BigDecimal qtyBom = rs.getBigDecimal(15); BigDecimal qtyBom = rs.getBigDecimal(15);
Boolean isQtyPercentage = rs.getString(16).equals("Y"); Boolean isQtyPercentage = rs.getString(16).equals("Y");
Boolean isCritical = rs.getString(2).equals("Y");
BigDecimal qtyBatch = rs.getBigDecimal(17); BigDecimal qtyBatch = rs.getBigDecimal(17);
BigDecimal qtyRequired = rs.getBigDecimal(8); BigDecimal qtyRequired = rs.getBigDecimal(8);
BigDecimal qtyOnHand = rs.getBigDecimal(11); BigDecimal qtyOnHand = rs.getBigDecimal(11);
BigDecimal qtyOpen = rs.getBigDecimal(19); BigDecimal qtyOpen = rs.getBigDecimal(19);
BigDecimal qtyDelivered = rs.getBigDecimal(20);
String componentType = rs.getString(18); String componentType = rs.getString(18);
BigDecimal toDeliverQty = getToDeliverQty(); BigDecimal toDeliverQty = getToDeliverQty();
BigDecimal openQty = getOpenQty(); BigDecimal openQty = getOpenQty();
@ -680,13 +682,14 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
id.setSelected(isOnlyReceipt()); id.setSelected(isOnlyReceipt());
issue.setValueAt(id, row, 0); // PP_OrderBOMLine_ID issue.setValueAt(id, row, 0); // PP_OrderBOMLine_ID
issue.setValueAt(rs.getString(2).equals("Y"), row, 1); // IsCritical issue.setValueAt(isCritical, row, 1); // IsCritical
issue.setValueAt(rs.getString(3), row, 2); // Product's Search key issue.setValueAt(rs.getString(3), row, 2); // Product's Search key
issue.setValueAt(new KeyNamePair(rs.getInt(4), rs.getString(5)), row, 3); // Product issue.setValueAt(new KeyNamePair(rs.getInt(4), rs.getString(5)), row, 3); // Product
issue.setValueAt(new KeyNamePair(rs.getInt(6), rs.getString(7)), row, 4); // UOM issue.setValueAt(new KeyNamePair(rs.getInt(6), rs.getString(7)), row, 4); // UOM
// ... 5 - ASI // ... 5 - ASI
issue.setValueAt(qtyRequired, row, 6); // QtyRequiered issue.setValueAt(qtyRequired, row, 6); // QtyRequiered
issue.setValueAt(rs.getBigDecimal(20), row, 7); // QtyDelivered issue.setValueAt(qtyDelivered, row, 7); // QtyDelivered
// ... 8, 9, 10 - QtyToDeliver, QtyScrap, QtyOnHand // ... 8, 9, 10 - QtyToDeliver, QtyScrap, QtyOnHand
issue.setValueAt(qtyOnHand, row, 10); // OnHand issue.setValueAt(qtyOnHand, row, 10); // OnHand
issue.setValueAt(rs.getBigDecimal(9), row, 11); // QtyReserved issue.setValueAt(rs.getBigDecimal(9), row, 11); // QtyReserved
@ -710,22 +713,25 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
if (isBackflush()) if (isBackflush())
{ // Is Backflush - Calculate Component from Qty To Deliver { // Is Backflush - Calculate Component from Qty To Deliver
if (qtyRequired.signum() == 0) if (qtyRequired.signum() == 0 || qtyOpen.signum() == 0)
{ {
componentToDeliverQty = Env.ZERO; componentToDeliverQty = Env.ZERO;
} }
else else
{ {
componentToDeliverQty = toDeliverQty.multiply(qtyBatchPerc); componentToDeliverQty = toDeliverQty.multiply(qtyBatchPerc);
if(qtyRequired.subtract(qtyDelivered).signum() < 0 | componentToDeliverQty.signum() == 0)
componentToDeliverQty = qtyRequired.subtract(qtyDelivered);
} }
if (componentToDeliverQty.signum() != 0) if (componentToDeliverQty.signum() != 0)
{ {
// TODO: arhipac: teo_sarca: is this a bug ? ...instead of toDeliverQty, qtyRequired should be used! // TODO: arhipac: teo_sarca: is this a bug ? ...instead of toDeliverQty, qtyRequired should be used!
componentQtyReq = toDeliverQty.multiply(qtyBatchPerc); // TODO: set scale 4 //componentQtyReq = toDeliverQty.multiply(qtyBatchPerc); // TODO: set scale 4
componentQtyToDel = componentToDeliverQty.setScale(4, BigDecimal.ROUND_HALF_UP); componentQtyToDel = componentToDeliverQty.setScale(4, BigDecimal.ROUND_HALF_UP);
//issue.setValueAt(toDeliverQty.multiply(qtyBatchPerc), row, 6); // QtyRequiered
issue.setValueAt(toDeliverQty.multiply(qtyBatchPerc), row, 6); // QtyRequiered
issue.setValueAt(componentToDeliverQty, row, 8); // QtyToDelivery issue.setValueAt(componentToDeliverQty, row, 8); // QtyToDelivery
} }
@ -974,11 +980,25 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
createIssue(); createIssue();
} }
if (isOnlyReceipt() || isBackflush()) { if (isOnlyReceipt() || isBackflush()) {
createReceipt();
boolean isCloseDocument = ADialog.ask(m_WindowNo, this,
Msg.translate(Env.getCtx(), "IsCloseDocument"),
Msg.translate(Env.getCtx(), "DocumentNo") + getPP_Order().getDocumentNo());
MPPOrder.createReceipt(this.getPP_Order(),
getMovementDate(),
getDeliveredQty(),
getToDeliverQty(),
getScrapQty(),
getRejectQty(),
getM_Locator_ID(),
getM_AttributeSetInstance_ID(),
isCloseDocument,
null);
} }
ADialog.info(m_WindowNo, this, //ADialog.info(m_WindowNo, this,
Msg.translate(Env.getCtx(), "OnlyReceipt"), // Msg.translate(Env.getCtx(), "OnlyReceipt"),
Msg.translate(Env.getCtx(), "DocumentNo") + getPP_Order().getDocumentNo()); // Msg.translate(Env.getCtx(), "DocumentNo") + getPP_Order().getDocumentNo());
} }
catch (Exception e) { catch (Exception e) {
ADialog.error(m_WindowNo, this, e.getLocalizedMessage()); ADialog.error(m_WindowNo, this, e.getLocalizedMessage());
@ -994,59 +1014,26 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
Timestamp minGuaranteeDate = movementDate; Timestamp minGuaranteeDate = movementDate;
boolean isCompleteQtyDeliver = false; boolean isCompleteQtyDeliver = false;
// ArrayList[][] m_issue = new ArrayList[issue.getRowCount()][1];
int row = 0;
// Check Available On Hand Qty // Check Available On Hand Qty
for (int i = 0; i < issue.getRowCount(); i++) for (int i = 0; i < issue.getRowCount(); i++)
{ {
IDColumn id = (IDColumn) issue.getValueAt(i, 0); ArrayList<Object> data = new ArrayList<Object>();
if (id == null || !id.isSelected())
{
continue;
}
KeyNamePair productkey = (KeyNamePair) issue.getValueAt(i, 3); data.add(issue.getValueAt (i, 0)); //0 - ID
int product_ID = productkey.getKey(); data.add(issue.getValueAt (i, 1)); //1 - IsCritical
BigDecimal qtyToDeliver = getValueBigDecimal(i, 8); data.add(issue.getValueAt (i, 2)); //2 - Value
BigDecimal qtyScrapComponent = getValueBigDecimal(i, 9); data.add(issue.getValueAt (i, 3)); //3 - KeyNamePair Product
data.add(getValueBigDecimal(i, 8)); //4 - QtyToDeliver
data.add(getValueBigDecimal(i, 9)); //5 - QtyScrapComponent
MStorage[] storages = getStorages(product_ID, getPP_Order().getM_AttributeSetInstance_ID(), minGuaranteeDate); m_issue[row][0] = data;
row ++ ;
}
int M_AttributeSetInstance_ID = ANY_ASI; isCompleteQtyDeliver = MPPOrder.isAvailableQty(getPP_Order(), m_issue , minGuaranteeDate);
if (issue.getValueAt(i, 2) == null && id.isSelected())
{
M_AttributeSetInstance_ID = (Integer)id.getRecord_ID();
}
if (M_AttributeSetInstance_ID == ANY_ASI)
{
BigDecimal toIssue = qtyToDeliver.add(qtyScrapComponent);
for (MStorage storage : storages) {
// TODO Selection of ASI
if (storage.getQtyOnHand().signum() == 0)
continue;
BigDecimal issueActual = toIssue.min(storage.getQtyOnHand());
toIssue = toIssue.subtract(issueActual);
if (toIssue.signum() <= 0)
break;
}
}
else
{
BigDecimal qtydelivered = qtyToDeliver;
qtydelivered.setScale(4, BigDecimal.ROUND_HALF_UP);
qtydelivered = Env.ZERO;
}
BigDecimal onHand = Env.ZERO;
for (MStorage storage : storages)
{
onHand = onHand.add(storage.getQtyOnHand());
}
isCompleteQtyDeliver = onHand.compareTo(qtyToDeliver.add(qtyScrapComponent)) >= 0;
if (!isCompleteQtyDeliver)
break;
} // for each line
if (!isCompleteQtyDeliver) if (!isCompleteQtyDeliver)
{ {
@ -1054,217 +1041,54 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
throw new AdempiereException("@NoQtyAvailable@"); throw new AdempiereException("@NoQtyAvailable@");
} }
// for(int i = 0; i < m_issue.length; i++ )
// Issue Qty
for (int ok = 0; ok < issue.getRowCount(); ok++)
{ {
IDColumn id = (IDColumn) issue.getValueAt(ok, 0); IDColumn id = (IDColumn) m_issue[i][0].get(0);
if (id == null || !id.isSelected()) { if (id == null || !id.isSelected())
{
continue; continue;
} }
KeyNamePair m_productkey = (KeyNamePair) issue.getValueAt(ok, 3); Boolean isCritical = (Boolean)m_issue[i][0].get(1);
int m_M_Product_ID = m_productkey.getKey(); String value = (String)m_issue[i][0].get(2);
KeyNamePair productkey = (KeyNamePair) m_issue[i][0].get(3);
int M_Product_ID = productkey.getKey();
int PP_Order_BOMLine_ID = 0; int PP_Order_BOMLine_ID = 0;
int M_AttributeSetInstance_ID = ANY_ASI; int M_AttributeSetInstance_ID = ANY_ASI;
if (issue.getValueAt(ok, 2) == null && id.isSelected()) {
M_AttributeSetInstance_ID = (Integer) id.getRecord_ID();
String sql = "SELECT PP_Order_BOMLine_ID FROM PP_Order_BOMLine" BigDecimal qtyToDeliver = (BigDecimal) m_issue[i][0].get(4);
+" WHERE M_Product_ID=? AND PP_Order_ID=?"; BigDecimal qtyScrapComponent = (BigDecimal) m_issue[i][0].get(5);
PP_Order_BOMLine_ID = DB.getSQLValue(null, sql, m_M_Product_ID, getPP_Order_ID());
}
else if (issue.getValueAt(ok, 2) != null && id.isSelected()) {
PP_Order_BOMLine_ID = ((Integer) id.getRecord_ID());
}
BigDecimal m_qtyToDeliver = getValueBigDecimal(ok, 8); MProduct product = MProduct.get(getPP_Order().getCtx(), M_Product_ID);
BigDecimal m_scrapQtyComponent = getValueBigDecimal(ok, 9); if (product != null && product.get_ID() != 0 && product.isStocked())
BigDecimal onHand = Env.ZERO;
MStorage[] storages = getStorages(m_M_Product_ID, M_AttributeSetInstance_ID, minGuaranteeDate);
for (MStorage storage : storages) {
onHand = onHand.add(storage.getQtyOnHand());
}
createIssue(PP_Order_BOMLine_ID, movementDate,
m_qtyToDeliver, m_scrapQtyComponent,
Env.ZERO, storages);
}
}
private void createReceipt()
{
MPPOrder pp_order = getPP_Order();
Timestamp movementDate = getMovementDate();
BigDecimal toDeliverQty = getToDeliverQty();
BigDecimal scrapQty = getScrapQty();
BigDecimal rejectQty = getRejectQty();
if (toDeliverQty.signum() > 0 || scrapQty.signum() > 0 || rejectQty.signum() > 0)
{
createCollector(pp_order.getM_Product_ID(),
getM_Locator_ID(),
getM_AttributeSetInstance_ID(),
movementDate,
toDeliverQty, scrapQty, rejectQty,
getDocType(MDocType.DOCBASETYPE_ManufacturingOrder),
0, // PP_Order_BOMLine_ID
MPPCostCollector.COSTCOLLECTORTYPE_MaterialReceipt);
}
if (ADialog.ask(m_WindowNo, this,
Msg.translate(Env.getCtx(), "IsCloseDocument"),
Msg.translate(Env.getCtx(), "DocumentNo") + pp_order.getDocumentNo())
)
{
pp_order.setDateFinish(movementDate);
pp_order.closeIt();
pp_order.saveEx();
}
pp_order.setDateDelivered(movementDate);
if (pp_order.getDateStart() == null)
{
pp_order.setDateStart(movementDate);
}
BigDecimal DQ = getDeliveredQty();
BigDecimal SQ = getScrapQty();
BigDecimal OQ = getToDeliverQty();
if (DQ.add(SQ).compareTo(OQ) >= 0)
{
pp_order.setDateFinish(movementDate);
}
pp_order.saveEx();
}
/**
* Create Issue
* @param PP_OrderBOMLine_ID
* @param movementdate
* @param qty
* @param qtyScrap
* @param qtyReject
* @param storages
*/
private void createIssue(int PP_OrderBOMLine_ID,
Timestamp movementdate,
BigDecimal qty, BigDecimal qtyScrap, BigDecimal qtyReject,
MStorage[] storages)
{
if (qty.signum() == 0)
return;
BigDecimal toIssue = qty.add(qtyScrap);
for (MStorage storage : storages)
{
// TODO Selection of ASI
if (storage.getQtyOnHand().signum() == 0)
continue;
BigDecimal issue = toIssue.min(storage.getQtyOnHand());
log.fine("ToIssue: " + issue);
MPPOrderBOMLine PP_orderbomLine = new MPPOrderBOMLine(Env.getCtx(), PP_OrderBOMLine_ID, null);
if (issue.signum() > 0 || qtyScrap.signum() > 0 || qtyReject.signum() > 0)
{ {
String CostCollectorType = null;
int C_DocType_ID = getDocType(MDocType.DOCBASETYPE_ManufacturingOrder);
// Method Variance
if (PP_orderbomLine.getQtyBatch().signum() == 0
&& PP_orderbomLine.getQtyBOM().signum() == 0)
{
CostCollectorType = MPPCostCollector.COSTCOLLECTORTYPE_MethodChangeVariance;
}
// Order Issue
else
{
CostCollectorType = MPPCostCollector.COSTCOLLECTORTYPE_ComponentIssue;
}
//
createCollector (
PP_orderbomLine.getM_Product_ID(),
storage.getM_Locator_ID(),
storage.getM_AttributeSetInstance_ID(),
movementdate,
issue, qtyScrap, qtyReject,
C_DocType_ID,
PP_OrderBOMLine_ID,
CostCollectorType // Production "-"
);
if (value == null && id.isSelected())
{
M_AttributeSetInstance_ID = (Integer) id.getRecord_ID();
//TODO: vpj-cd What happen when a product it more the time in Order
String sql = "SELECT PP_Order_BOMLine_ID FROM PP_Order_BOMLine"
+" WHERE M_Product_ID=? AND PP_Order_ID=?";
PP_Order_BOMLine_ID = DB.getSQLValue(null, sql, M_Product_ID, getPP_Order_ID());
}
else if (value != null && id.isSelected())
{
PP_Order_BOMLine_ID = ((Integer) id.getRecord_ID());
}
MStorage[] storages = MPPOrder.getStorages(
M_Product_ID,
getPP_Order().getM_Warehouse_ID(),
M_AttributeSetInstance_ID,
getPP_Order().getM_AttributeSetInstance_ID(),
ANY_ASI, minGuaranteeDate);
MPPOrder.createIssue(getPP_Order(),PP_Order_BOMLine_ID, movementDate,
qtyToDeliver, qtyScrapComponent,
Env.ZERO, storages , null);
} }
toIssue = toIssue.subtract(issue);
if (toIssue.signum() == 0)
break;
} }
//
if (toIssue.signum() != 0)
{
// should not happen because we validate Qty On Hand on start of this process
throw new AdempiereException("Should not happen toIssue="+toIssue);
}
}
private void createCollector (
int M_Product_ID,
int M_Locator_ID,
int M_AttributeSetInstance_ID,
Timestamp movementdate,
BigDecimal qty,
BigDecimal scrap,
BigDecimal reject,
int C_DocType_ID,
int PP_Order_BOMLine_ID,
String CostCollectorType
)
{
MPPOrder pp_order = getPP_Order();
MPPCostCollector PP_Cost_Collector = new MPPCostCollector(Env.getCtx(), 0, null);
PP_Cost_Collector.setPP_Order_ID(pp_order.getPP_Order_ID());
PP_Cost_Collector.setPP_Order_BOMLine_ID(PP_Order_BOMLine_ID);
PP_Cost_Collector.setAD_OrgTrx_ID(pp_order.getAD_OrgTrx_ID());
PP_Cost_Collector.setC_Activity_ID(pp_order.getC_Activity_ID());
PP_Cost_Collector.setC_Campaign_ID(pp_order.getC_Campaign_ID());
PP_Cost_Collector.setC_DocType_ID(C_DocType_ID);
PP_Cost_Collector.setC_DocTypeTarget_ID(C_DocType_ID);
PP_Cost_Collector.setCostCollectorType(CostCollectorType);
PP_Cost_Collector.setC_Project_ID(pp_order.getC_Project_ID());
PP_Cost_Collector.setDescription(pp_order.getDescription());
PP_Cost_Collector.setDocAction(MPPCostCollector.ACTION_Complete);
PP_Cost_Collector.setDocStatus(MPPCostCollector.DOCSTATUS_Drafted);
PP_Cost_Collector.setIsActive(true);
PP_Cost_Collector.setM_Warehouse_ID(pp_order.getM_Warehouse_ID());
PP_Cost_Collector.setM_Locator_ID(M_Locator_ID);
PP_Cost_Collector.setM_AttributeSetInstance_ID(M_AttributeSetInstance_ID);
PP_Cost_Collector.setS_Resource_ID(pp_order.getS_Resource_ID());
PP_Cost_Collector.setMovementDate(movementdate);
PP_Cost_Collector.setDateAcct(movementdate);
PP_Cost_Collector.setMovementQty(qty);
PP_Cost_Collector.setScrappedQty(scrap);
PP_Cost_Collector.setQtyReject(reject);
PP_Cost_Collector.setPosted(false);
PP_Cost_Collector.setProcessed(false);
PP_Cost_Collector.setProcessing(false);
PP_Cost_Collector.setUser1_ID(pp_order.getUser1_ID());
PP_Cost_Collector.setUser2_ID(pp_order.getUser2_ID());
PP_Cost_Collector.setM_Product_ID(M_Product_ID);
PP_Cost_Collector.saveEx();
if (!PP_Cost_Collector.processIt(MPPCostCollector.DOCACTION_Complete)) {
throw new AdempiereException(PP_Cost_Collector.getProcessMsg());
}
PP_Cost_Collector.saveEx();
}
private int getDocType(String DocBaseType)
{
MDocType[] doc = MDocType.getOfDocBaseType(Env.getCtx(), DocBaseType);
return doc.length > 0 ? doc[0].get_ID() : 0;
} }
/** /**
@ -1324,7 +1148,12 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
{ {
Timestamp m_movementDate = getMovementDate(); Timestamp m_movementDate = getMovementDate();
Timestamp minGuaranteeDate = m_movementDate; Timestamp minGuaranteeDate = m_movementDate;
MStorage[] storages = getStorages(m_M_Product_ID, getPP_Order().getM_AttributeSetInstance_ID(), minGuaranteeDate); MStorage[] storages = MPPOrder.getStorages(
m_M_Product_ID,
getPP_Order().getM_Warehouse_ID(),
0,
getPP_Order().getM_AttributeSetInstance_ID(),
ANY_ASI, minGuaranteeDate);
BigDecimal todelivery = getValueBigDecimal(i, 8); //QtyOpen BigDecimal todelivery = getValueBigDecimal(i, 8); //QtyOpen
BigDecimal scrap = getValueBigDecimal(i, 9); //QtyScrap BigDecimal scrap = getValueBigDecimal(i, 9); //QtyScrap
@ -1622,28 +1451,6 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel,
public void unlockUI(org.compiere.process.ProcessInfo processInfo) { public void unlockUI(org.compiere.process.ProcessInfo processInfo) {
} }
private MStorage[] getStorages(int m_M_Product_ID, int M_ASI_ID, Timestamp minGuaranteeDate)
{
Properties ctx = Env.getCtx();
MProduct product = MProduct.get(ctx, m_M_Product_ID);
if (product != null && product.get_ID() != 0 && product.isStocked()) {
String MMPolicy = product.getMMPolicy();
return MStorage.getWarehouse(ctx,
m_PP_order.getM_Warehouse_ID(),
m_M_Product_ID,
M_ASI_ID == ANY_ASI ? m_PP_order.getM_AttributeSetInstance_ID() : M_ASI_ID,
product.getM_AttributeSet_ID(),
true, // all attribute set instances
minGuaranteeDate,
MClient.MMPOLICY_FiFo.equals(MMPolicy),
null // no trx
);
}
else {
return new MStorage[0];
}
}
private BigDecimal getValueBigDecimal(int row, int col) { private BigDecimal getValueBigDecimal(int row, int col) {
BigDecimal bd = (BigDecimal)issue.getValueAt(row, col); BigDecimal bd = (BigDecimal)issue.getValueAt(row, col);
return bd == null ? Env.ZERO: bd; return bd == null ? Env.ZERO: bd;

View File

@ -0,0 +1,40 @@
-- Jan 12, 2009 12:08:51 AM ECT
-- New BOM Type for KIT
INSERT INTO AD_Ref_List (AD_Client_ID,AD_Org_ID,AD_Ref_List_ID,AD_Reference_ID,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,Value) VALUES (0,0,53450,347,TO_DATE('2009-01-12 00:08:45','YYYY-MM-DD HH24:MI:SS'),100,'EE01','Y','Make-To-Kit',TO_DATE('2009-01-12 00:08:45','YYYY-MM-DD HH24:MI:SS'),100,'K')
;
-- Jan 12, 2009 12:08:51 AM ECT
-- New BOM Type for KIT
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=53450 AND EXISTS (SELECT * FROM AD_Ref_List_Trl tt WHERE tt.AD_Language!=l.AD_Language OR tt.AD_Ref_List_ID!=t.AD_Ref_List_ID)
;
-- Jan 12, 2009 12:09:09 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_DATE('2009-01-12 00:09:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=746
;
-- Jan 12, 2009 12:09:12 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_DATE('2009-01-12 00:09:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=747
;
-- Jan 12, 2009 12:09:17 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_DATE('2009-01-12 00:09:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=744
;
-- Jan 12, 2009 12:09:21 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_DATE('2009-01-12 00:09:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=745
;
-- Jan 12, 2009 12:35:52 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET Description='Create a Manufacturing Order, Receipt the finish product and issue the Components automaticaly ',Updated=TO_DATE('2009-01-12 00:35:52','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53450
;
-- Jan 12, 2009 12:35:52 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List_Trl SET IsTranslated='N' WHERE AD_Ref_List_ID=53450
;

View File

@ -0,0 +1,39 @@
-- Jan 12, 2009 12:08:51 AM ECT
-- New BOM Type for KIT
INSERT INTO AD_Ref_List (AD_Client_ID,AD_Org_ID,AD_Ref_List_ID,AD_Reference_ID,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,Value) VALUES (0,0,53450,347,TO_TIMESTAMP('2009-01-12 00:08:45','YYYY-MM-DD HH24:MI:SS'),100,'EE01','Y','Make-To-Kit',TO_TIMESTAMP('2009-01-12 00:08:45','YYYY-MM-DD HH24:MI:SS'),100,'K')
;
-- Jan 12, 2009 12:08:51 AM ECT
-- New BOM Type for KIT
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=53450 AND EXISTS (SELECT * FROM AD_Ref_List_Trl tt WHERE tt.AD_Language!=l.AD_Language OR tt.AD_Ref_List_ID!=t.AD_Ref_List_ID)
;
-- Jan 12, 2009 12:09:09 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_TIMESTAMP('2009-01-12 00:09:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=746
;
-- Jan 12, 2009 12:09:12 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_TIMESTAMP('2009-01-12 00:09:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=747
;
-- Jan 12, 2009 12:09:17 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_TIMESTAMP('2009-01-12 00:09:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=744
;
-- Jan 12, 2009 12:09:21 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET IsActive='N',Updated=TO_TIMESTAMP('2009-01-12 00:09:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=745
;
-- Jan 12, 2009 12:35:52 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List SET Description='Create a Manufacturing Order, Receipt the finish product and issue the Components automaticaly ',Updated=TO_TIMESTAMP('2009-01-12 00:35:52','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53450
;
-- Jan 12, 2009 12:35:52 AM ECT
-- New BOM Type for KIT
UPDATE AD_Ref_List_Trl SET IsTranslated='N' WHERE AD_Ref_List_ID=53450
;