From 0824224a2890bcac1e0f38be4acb458ab572a7fd Mon Sep 17 00:00:00 2001 From: vpj-cd Date: Mon, 12 Jan 2009 18:39:01 +0000 Subject: [PATCH] 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. --- base/src/org/compiere/model/MDocType.java | 11 + .../org/eevolution/model/LiberoValidator.java | 66 ++- .../eevolution/model/MPPCostCollector.java | 2 +- base/src/org/eevolution/model/MPPMRP.java | 26 +- base/src/org/eevolution/model/MPPOrder.java | 460 +++++++++++++++++- .../org/eevolution/model/X_PP_Order_BOM.java | 6 +- .../eevolution/model/X_PP_Product_BOM.java | 6 +- .../eevolution/form/VOrderReceiptIssue.java | 377 ++++---------- .../oracle/393_FR_2501713_MakeToKit.sql | 40 ++ .../postgresql/393_FR_2501713_MakeToKit.sql | 39 ++ 10 files changed, 693 insertions(+), 340 deletions(-) create mode 100644 migration/353a-trunk/oracle/393_FR_2501713_MakeToKit.sql create mode 100644 migration/353a-trunk/postgresql/393_FR_2501713_MakeToKit.sql diff --git a/base/src/org/compiere/model/MDocType.java b/base/src/org/compiere/model/MDocType.java index f56f4953ae..6c67f2d659 100644 --- a/base/src/org/compiere/model/MDocType.java +++ b/base/src/org/compiere/model/MDocType.java @@ -35,6 +35,17 @@ import org.compiere.util.Env; */ 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 * @param ctx context diff --git a/base/src/org/eevolution/model/LiberoValidator.java b/base/src/org/eevolution/model/LiberoValidator.java index db8897eb91..1a543e2490 100644 --- a/base/src/org/eevolution/model/LiberoValidator.java +++ b/base/src/org/eevolution/model/LiberoValidator.java @@ -176,32 +176,60 @@ public class LiberoValidator implements ModelValidator public String docValidate (PO po, int 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 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) { MInOut inout = (MInOut)po; - for (MInOutLine line : inout.getLines()) - { - String whereClause = "C_OrderLine_ID=? AND PP_Cost_Collector_ID IS NOT NULL"; - Collection olines = new Query(po.getCtx(), MOrderLine.Table_Name, whereClause, po.get_TrxName()) - .setParameters(new Object[]{line.getC_OrderLine_ID()}) - .list(); - for (MOrderLine oline : olines) + + for (MInOutLine line : inout.getLines()) { - if(oline.getQtyOrdered().compareTo(oline.getQtyDelivered()) >= 0) - { - MPPCostCollector cc = new MPPCostCollector(po.getCtx(), oline.getPP_Cost_Collector_ID(), po.get_TrxName()); - String docStatus = cc.completeIt(); - cc.setDocStatus(docStatus); - cc.setDocAction(MPPCostCollector.DOCACTION_Close); - cc.saveEx(); - return Msg.translate(po.getCtx(), "PP_Order_ID") - +":"+cc.getPP_Order().getDocumentNo() - +Msg.translate(po.getCtx(),"PP_Order_Node_ID") - +":"+cc.getPP_Order_Node().getValue(); + final String whereClause = "C_OrderLine_ID=? AND PP_Cost_Collector_ID IS NOT NULL"; + Collection 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) + { + MPPCostCollector cc = new MPPCostCollector(po.getCtx(), oline.getPP_Cost_Collector_ID(), po.get_TrxName()); + String docStatus = cc.completeIt(); + cc.setDocStatus(docStatus); + cc.setDocAction(MPPCostCollector.DOCACTION_Close); + cc.saveEx(); + return Msg.translate(po.getCtx(), "PP_Order_ID") + +":"+cc.getPP_Order().getDocumentNo() + +Msg.translate(po.getCtx(),"PP_Order_Node_ID") + +":"+cc.getPP_Order_Node().getValue(); + } } } } - } return null; } // docValidate diff --git a/base/src/org/eevolution/model/MPPCostCollector.java b/base/src/org/eevolution/model/MPPCostCollector.java index 9627b7aa3e..d4f8af775e 100644 --- a/base/src/org/eevolution/model/MPPCostCollector.java +++ b/base/src/org/eevolution/model/MPPCostCollector.java @@ -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] 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; // diff --git a/base/src/org/eevolution/model/MPPMRP.java b/base/src/org/eevolution/model/MPPMRP.java index c96f1d984e..da2786acbb 100644 --- a/base/src/org/eevolution/model/MPPMRP.java +++ b/base/src/org/eevolution/model/MPPMRP.java @@ -29,6 +29,7 @@ import org.compiere.model.MLocator; import org.compiere.model.MOrder; import org.compiere.model.MOrderLine; import org.compiere.model.MProduct; +import org.compiere.model.MRefList; import org.compiere.model.MRequisition; import org.compiere.model.MRequisitionLine; import org.compiere.model.MResource; @@ -40,6 +41,7 @@ import org.compiere.process.DocAction; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.compiere.util.Msg; import org.compiere.util.TimeUtil; 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()); 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+"=?"; 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(); MPPProductPlanning pp = null; @@ -385,6 +393,10 @@ public class MPPMRP extends X_PP_MRP { bom = null; } + if(bom != null && !MPPProductBOM.BOMTYPE_Make_To_Kit.equals(bom.getBOMType())) + { + bom = null; + } } } if (bom != null) @@ -402,7 +414,12 @@ public class MPPMRP extends X_PP_MRP { 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.setS_Resource_ID(plant_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.setPriorityRule(MPPOrder.PRIORITYRULE_High); order.saveEx(); - order.prepareIt(); + order.setDocStatus(order.prepareIt()); + order.setDocAction(MPPOrder.ACTION_Complete); order.saveEx(); } } diff --git a/base/src/org/eevolution/model/MPPOrder.java b/base/src/org/eevolution/model/MPPOrder.java index d673009048..2d230995d2 100644 --- a/base/src/org/eevolution/model/MPPOrder.java +++ b/base/src/org/eevolution/model/MPPOrder.java @@ -21,17 +21,22 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.ResultSet; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.List; import java.util.Properties; +import java.util.Vector; import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.DocTypeNotFoundException; +import org.compiere.apps.ADialog; +import org.compiere.minigrid.IDColumn; import org.compiere.model.MAcctSchema; import org.compiere.model.MClient; import org.compiere.model.MCost; import org.compiere.model.MDocType; import org.compiere.model.MProduct; import org.compiere.model.MProject; +import org.compiere.model.MRefList; import org.compiere.model.MResource; import org.compiere.model.MStorage; import org.compiere.model.MTable; @@ -47,6 +52,8 @@ import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.util.DB; import org.compiere.util.Env; +import org.compiere.util.KeyNamePair; +import org.compiere.util.Msg; import org.compiere.wf.MWFNode; import org.compiere.wf.MWFNodeNext; import org.compiere.wf.MWorkflow; @@ -58,9 +65,7 @@ import org.compiere.wf.MWorkflow; * Use DocAction and C_DocTypeTarget_ID instead. * * @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 { @@ -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, get_TrxName()); // Get default Location - if (M_Locator_ID == 0) { - MWarehouse wh = MWarehouse.get(getCtx(), getM_Warehouse_ID()); - M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID(); + if (M_Locator_ID == 0) + { + M_Locator_ID = getM_Locator_ID(); } //4Layers - Necessary to clear order quantities when called from closeIt if (DOCACTION_Close.equals(getDocAction())) @@ -604,6 +609,90 @@ public class MPPOrder extends X_PP_Order implements DocAction PP_Order_Cost.saveEx(); } } + + 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 data = new ArrayList(); + + 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); setDocAction(DOCACTION_Close); @@ -650,31 +739,22 @@ public class MPPOrder extends X_PP_Order implements DocAction public boolean closeIt() { 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 m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE); if (m_processMsg != null) 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 - reserveStock(lines); // Clear Reservations + reserveStock(getLines()); // Clear Reservations m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE); if (m_processMsg != null) @@ -699,8 +779,14 @@ public class MPPOrder extends X_PP_Order implements DocAction public boolean reActivateIt() { - log.info("reActivateIt - " + toString()); - return false; + // After reActivate + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE); + if (m_processMsg != null) + return false; + + setDocAction(DOCACTION_Complete); + setProcessed(false); + return true; } // reActivateIt public int getDoc_User_ID() @@ -951,6 +1037,326 @@ public class MPPOrder extends X_PP_Order implements DocAction } // 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() { StringBuffer sb = new StringBuffer("MPPOrder[").append(get_ID()) diff --git a/base/src/org/eevolution/model/X_PP_Order_BOM.java b/base/src/org/eevolution/model/X_PP_Order_BOM.java index 1b188e0574..60b0f022dd 100644 --- a/base/src/org/eevolution/model/X_PP_Order_BOM.java +++ b/base/src/org/eevolution/model/X_PP_Order_BOM.java @@ -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"; /** Product Configure = C */ public static final String BOMTYPE_ProductConfigure = "C"; + /** Make-To-Kit = K */ + public static final String BOMTYPE_Make_To_Kit = "K"; /** Set BOM Type. @param BOMType 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) { - 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")); - else throw new IllegalArgumentException ("BOMType Invalid value - " + BOMType + " - Reference_ID=347 - A - O - P - S - F - M - R - 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 - K"); set_Value (COLUMNNAME_BOMType, BOMType); } diff --git a/base/src/org/eevolution/model/X_PP_Product_BOM.java b/base/src/org/eevolution/model/X_PP_Product_BOM.java index f715bcd274..51c0f1c690 100644 --- a/base/src/org/eevolution/model/X_PP_Product_BOM.java +++ b/base/src/org/eevolution/model/X_PP_Product_BOM.java @@ -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"; /** Product Configure = C */ public static final String BOMTYPE_ProductConfigure = "C"; + /** Make-To-Kit = K */ + public static final String BOMTYPE_Make_To_Kit = "K"; /** Set BOM Type. @param BOMType 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) { - 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")); - else throw new IllegalArgumentException ("BOMType Invalid value - " + BOMType + " - Reference_ID=347 - A - O - P - S - F - M - R - 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 - K"); set_Value (COLUMNNAME_BOMType, BOMType); } diff --git a/client/src/org/eevolution/form/VOrderReceiptIssue.java b/client/src/org/eevolution/form/VOrderReceiptIssue.java index 8048ad28f1..d5d250ef5b 100644 --- a/client/src/org/eevolution/form/VOrderReceiptIssue.java +++ b/client/src/org/eevolution/form/VOrderReceiptIssue.java @@ -196,7 +196,7 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel, /** * Fill Picks * 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 */ 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, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, 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, 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, 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)); BigDecimal qtyBom = rs.getBigDecimal(15); Boolean isQtyPercentage = rs.getString(16).equals("Y"); + Boolean isCritical = rs.getString(2).equals("Y"); BigDecimal qtyBatch = rs.getBigDecimal(17); BigDecimal qtyRequired = rs.getBigDecimal(8); BigDecimal qtyOnHand = rs.getBigDecimal(11); BigDecimal qtyOpen = rs.getBigDecimal(19); + BigDecimal qtyDelivered = rs.getBigDecimal(20); String componentType = rs.getString(18); BigDecimal toDeliverQty = getToDeliverQty(); BigDecimal openQty = getOpenQty(); @@ -680,13 +682,14 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel, id.setSelected(isOnlyReceipt()); 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(new KeyNamePair(rs.getInt(4), rs.getString(5)), row, 3); // Product issue.setValueAt(new KeyNamePair(rs.getInt(6), rs.getString(7)), row, 4); // UOM // ... 5 - ASI 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 issue.setValueAt(qtyOnHand, row, 10); // OnHand issue.setValueAt(rs.getBigDecimal(9), row, 11); // QtyReserved @@ -710,22 +713,25 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel, if (isBackflush()) { // Is Backflush - Calculate Component from Qty To Deliver - if (qtyRequired.signum() == 0) + if (qtyRequired.signum() == 0 || qtyOpen.signum() == 0) { componentToDeliverQty = Env.ZERO; } else { componentToDeliverQty = toDeliverQty.multiply(qtyBatchPerc); + + if(qtyRequired.subtract(qtyDelivered).signum() < 0 | componentToDeliverQty.signum() == 0) + componentToDeliverQty = qtyRequired.subtract(qtyDelivered); + } if (componentToDeliverQty.signum() != 0) { // 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); - - issue.setValueAt(toDeliverQty.multiply(qtyBatchPerc), row, 6); // QtyRequiered + //issue.setValueAt(toDeliverQty.multiply(qtyBatchPerc), row, 6); // QtyRequiered issue.setValueAt(componentToDeliverQty, row, 8); // QtyToDelivery } @@ -974,11 +980,25 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel, createIssue(); } 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, - Msg.translate(Env.getCtx(), "OnlyReceipt"), - Msg.translate(Env.getCtx(), "DocumentNo") + getPP_Order().getDocumentNo()); + //ADialog.info(m_WindowNo, this, + // Msg.translate(Env.getCtx(), "OnlyReceipt"), + // Msg.translate(Env.getCtx(), "DocumentNo") + getPP_Order().getDocumentNo()); } catch (Exception e) { ADialog.error(m_WindowNo, this, e.getLocalizedMessage()); @@ -993,60 +1013,27 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel, Timestamp movementDate = getMovementDate(); Timestamp minGuaranteeDate = movementDate; boolean isCompleteQtyDeliver = false; - - // + + ArrayList[][] m_issue = new ArrayList[issue.getRowCount()][1]; + + int row = 0; // Check Available On Hand Qty for (int i = 0; i < issue.getRowCount(); i++) { - IDColumn id = (IDColumn) issue.getValueAt(i, 0); - if (id == null || !id.isSelected()) - { - continue; - } - - KeyNamePair productkey = (KeyNamePair) issue.getValueAt(i, 3); - int product_ID = productkey.getKey(); - BigDecimal qtyToDeliver = getValueBigDecimal(i, 8); - BigDecimal qtyScrapComponent = getValueBigDecimal(i, 9); - - MStorage[] storages = getStorages(product_ID, getPP_Order().getM_AttributeSetInstance_ID(), minGuaranteeDate); + ArrayList data = new ArrayList(); - int M_AttributeSetInstance_ID = ANY_ASI; - 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 + data.add(issue.getValueAt (i, 0)); //0 - ID + data.add(issue.getValueAt (i, 1)); //1 - IsCritical + data.add(issue.getValueAt (i, 2)); //2 - Value + data.add(issue.getValueAt (i, 3)); //3 - KeyNamePair Product + data.add(getValueBigDecimal(i, 8)); //4 - QtyToDeliver + data.add(getValueBigDecimal(i, 9)); //5 - QtyScrapComponent + + m_issue[row][0] = data; + row ++ ; + } + + isCompleteQtyDeliver = MPPOrder.isAvailableQty(getPP_Order(), m_issue , minGuaranteeDate); if (!isCompleteQtyDeliver) { @@ -1054,217 +1041,54 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel, throw new AdempiereException("@NoQtyAvailable@"); } - // - // Issue Qty - for (int ok = 0; ok < issue.getRowCount(); ok++) + for(int i = 0; i < m_issue.length; i++ ) { - IDColumn id = (IDColumn) issue.getValueAt(ok, 0); - if (id == null || !id.isSelected()) { + IDColumn id = (IDColumn) m_issue[i][0].get(0); + if (id == null || !id.isSelected()) + { continue; } - KeyNamePair m_productkey = (KeyNamePair) issue.getValueAt(ok, 3); - int m_M_Product_ID = m_productkey.getKey(); + Boolean isCritical = (Boolean)m_issue[i][0].get(1); + 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 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" - +" WHERE M_Product_ID=? AND PP_Order_ID=?"; - 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 qtyToDeliver = (BigDecimal) m_issue[i][0].get(4); + BigDecimal qtyScrapComponent = (BigDecimal) m_issue[i][0].get(5); - BigDecimal m_qtyToDeliver = getValueBigDecimal(ok, 8); - BigDecimal m_scrapQtyComponent = getValueBigDecimal(ok, 9); - - 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) + MProduct product = MProduct.get(getPP_Order().getCtx(), M_Product_ID); + if (product != null && product.get_ID() != 0 && product.isStocked()) { - 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 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 scrap = getValueBigDecimal(i, 9); //QtyScrap @@ -1622,28 +1451,6 @@ public class VOrderReceiptIssue extends CPanel implements FormPanel, 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) { BigDecimal bd = (BigDecimal)issue.getValueAt(row, col); return bd == null ? Env.ZERO: bd; diff --git a/migration/353a-trunk/oracle/393_FR_2501713_MakeToKit.sql b/migration/353a-trunk/oracle/393_FR_2501713_MakeToKit.sql new file mode 100644 index 0000000000..8deac63c92 --- /dev/null +++ b/migration/353a-trunk/oracle/393_FR_2501713_MakeToKit.sql @@ -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 +; + diff --git a/migration/353a-trunk/postgresql/393_FR_2501713_MakeToKit.sql b/migration/353a-trunk/postgresql/393_FR_2501713_MakeToKit.sql new file mode 100644 index 0000000000..1a4fc2e113 --- /dev/null +++ b/migration/353a-trunk/postgresql/393_FR_2501713_MakeToKit.sql @@ -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 +;