/// <summary> /// is used to save Product container /// </summary> /// <param name="warehouseId">Warehouse where we create container</param> /// <param name="locatorId">Locator - in which locator we place container</param> /// <param name="value">Search key of the container</param> /// <param name="name">name of teh container</param> /// <param name="height">height of the container</param> /// <param name="width">width of the container</param> /// <param name="parentContainerId">Parent of the nw container</param> /// <returns>Save Or Not Saved message</returns> /// <writer>Amit Bansal</writer> public string SaveProductContainer(int warehouseId, int locatorId, string value, string name, Decimal height, Decimal width, int parentContainerId) { MLocator m_locator = null; MWarehouse m_warehouse = null; // when warehouse ID is ZERO, then extract it from Locator if (warehouseId == 0 && locatorId > 0) { m_locator = MLocator.Get(_ctx, locatorId); warehouseId = m_locator.GetM_Warehouse_ID(); } // when locator ID is ZERO, then extract it either from Parent Conatiner or from Warehouse else if (warehouseId > 0 && locatorId == 0) { if (parentContainerId == 0) { m_warehouse = MWarehouse.Get(_ctx, warehouseId); locatorId = m_warehouse.GetDefaultM_Locator_ID(); } else { locatorId = Util.GetValueOfInt(DB.ExecuteScalar("SELECT M_Locator_ID FROM M_ProductContainer WHERE M_ProductContainer_ID = " + parentContainerId, null, null)); } } // need to check warehouse and locator shoyld be active during ceation of Product Container m_warehouse = MWarehouse.Get(_ctx, warehouseId); m_locator = MLocator.Get(_ctx, locatorId); if (!m_warehouse.IsActive()) { return(Msg.GetMsg(_ctx, "VIS_WarehouseNotActive")); } else if (!m_locator.IsActive()) { return(Msg.GetMsg(_ctx, "VIS_LocatorNotActive")); } // Create Product Container in Locator Organization //MProductContainer container = new MProductContainer(_ctx, 0, null); //container.SetAD_Org_ID(m_locator.GetAD_Org_ID()); //container.SetValue(value); //container.SetName(name); //container.SetM_Warehouse_ID(warehouseId); //container.SetM_Locator_ID(locatorId); //container.SetHeight(height); //container.SetWidth(width); //container.SetRef_M_Container_ID(parentContainerId); //if (!container.Save()) //{ // ValueNamePair pp = VLogger.RetrieveError(); // return Msg.GetMsg(_ctx, "VIS_ContainernotSaved") + " " + (pp != null ? pp.GetName() : ""); //} //else //{ // return ""; //} return(""); }
/// <summary> /// Get Product Container in term of Tree Structure /// </summary> /// <param name="warehouse">Warehouse -- which warehouse container we have to show</param> /// <param name="locator">Locato - which locator container we have to show</param> /// <param name="container">not used this parameter functionality -- Tree structure mismatched</param> /// <returns></returns> public List <TreeContainer> GetContainerAsTree(int warehouse, int locator, int container, string validation) { if (warehouse == 0 && locator > 0) { MLocator m_locator = MLocator.Get(_ctx, locator); warehouse = m_locator.GetM_Warehouse_ID(); } List <TreeContainer> keyVal = new List <TreeContainer>(); string sql = @"SELECT value , '.' || LPAD (' ', LEVEL * 1) || Name AS Name, LEVEL , name || '_' || value AS ContainerName , m_productcontainer_id FROM m_productcontainer WHERE IsActive = 'Y'"; if (warehouse > 0) { sql += " AND m_warehouse_id = " + warehouse; } if (locator > 0) { sql += " AND M_Locator_ID = " + locator; } if (container > 0) { sql += " AND M_ProductContainer_ID != " + container; } if (!String.IsNullOrEmpty(validation)) { sql += " AND " + validation; } sql += " START WITH NVL(ref_m_container_id,0) =0 CONNECT BY NVL(ref_m_container_id,0) = PRIOR m_productcontainer_id"; sql = MRole.GetDefault(_ctx).AddAccessSQL(sql, "M_ProductContainer", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); // fully qualidfied - RO DataSet ds = DB.ExecuteDataset(sql); if (ds != null && ds.Tables[0].Rows.Count > 0) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { keyVal.Add(new TreeContainer() { Value = Util.GetValueOfString(ds.Tables[0].Rows[i]["value"]), Name = Util.GetValueOfString(ds.Tables[0].Rows[i]["Name"]), Level = Util.GetValueOfInt(ds.Tables[0].Rows[i]["LEVEL"]), ContainerName = Util.GetValueOfString(ds.Tables[0].Rows[i]["ContainerName"]), M_ProductContainer_ID = Util.GetValueOfInt(ds.Tables[0].Rows[i]["M_ProductContainer_ID"]) }); } ds.Dispose(); } return(keyVal); }
// API to generate component transaction lines in M_WorkOrderTransactionLine. It should be possible to generate component lines // for all push / pull components in a specific operation and all push / pull components in all operations in a work order /** * api to generate component transaction lines in M_WorkOrderTransactionLine. Skips Optional operations unless they are either the starting operation sequence or ending operation sequence in the list of operations specified * @param ctx * @param M_WorkOrderTransaction_ID Work Order Transaction * @param Qty Number of Work Order Product Assemblies for which to generate components * @param OperationFrom Starting operation sequence number * @param OperationTo Ending operation sequence number * @param SupplyType Component Supply Type. Valid values are P (Push), O (Operation Pull), A (Assembly Pull) * @param M_Locator_ID Supply Locator for the components in case of Push supply type * @param trx * @return Array of MVAMFGMWrkOdrTrnsctionLine */ public ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine[] GenerateComponentTxnLine(Ctx ctx, int M_WorkOrderTransaction_ID, Decimal?Qty, Decimal?OperationFrom, Decimal?OperationTo, String SupplyType, int M_Locator_ID, Trx trx) { int _countGOM01 = 0; Tuple <String, String, String> mInfo = null; if (Env.HasModulePrefix("GOM01_", out mInfo)) { _countGOM01 = 1; } if (OperationFrom != null && OperationFrom.Value.CompareTo(OperationTo) > 0) { log.Severe("Operation Numbers not correct."); return(null); } ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, M_WorkOrderTransaction_ID, trx); if (0 == M_WorkOrderTransaction_ID || !((wot.GetDocStatus().Equals(X_VAMFG_M_WrkOdrTransaction.DOCSTATUS_Drafted) || wot.GetDocStatus().Equals(X_VAMFG_M_WrkOdrTransaction.DOCSTATUS_InProgress)) && (wot.GetVAMFG_WorkOrderTxnType().Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_1_ComponentIssueToWorkOrder) || wot.GetVAMFG_WorkOrderTxnType().Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_ComponentReturnFromWorkOrder)))) { log.Severe("Cannot create component lines against give WO Txn."); return(null); } if (Qty != null && Qty.Value.CompareTo(Decimal.Zero) <= 0) { log.Severe("Number of product assemblies must be positive"); return(null); } //ArrayList<MVAMFGMWrkOdrTrnsctionLine> wotLines = new ArrayList<MVAMFGMWrkOdrTrnsctionLine>(); // List<MVAMFGMWrkOdrTrnsctionLine> wotLines = new List<MVAMFGMWrkOdrTrnsctionLine>(); ArrayList wotLines = new ArrayList(); int lastMandatoryWOO = DB.GetSQLValue(trx, "SELECT MAX(VAMFG_SeqNo) FROM VAMFG_M_WorkOrderOperation " + "WHERE VAMFG_M_WorkOrder_ID = " + wot.GetVAMFG_M_WorkOrder_ID() + " AND VAMFG_IsOptional<>'Y'"); // automatically consider AssemblyPull Supply Type when the OperationTo is greater than the last Work Order Operation. // This in turn should take care of optional operations. bool assemblyPull = lastMandatoryWOO == OperationTo; StringBuilder response = new StringBuilder(""); // Getting the WorkOrder product assembly quantity Decimal woQty = DB.GetSQLValue(trx, "SELECT VAMFG_QtyEntered FROM VAMFG_M_WorkOrder " + "WHERE VAMFG_M_WorkOrder_ID = " + wot.GetVAMFG_M_WorkOrder_ID()); // Get component requirements based on the operations moved through in this transaction and then make lines StringBuilder sqlBuf = new StringBuilder("SELECT woc.M_Product_ID, woc.C_UOM_ID, woc.VAMFG_QtyRequired, " + " woc.VAMFG_SupplyType, woc.M_AttributeSetInstance_ID, woc.M_Locator_ID, woc.BasisType," + " woo.VAMFG_M_WorkOrderOperation_ID, woc.VAMFG_QtyAvailable, woc.VAMFG_QtySpent," + " woc.VAMFG_QtyAllocated, woc.VAMFG_QtyDedicated,woc.isqualitycorrection" + " FROM VAMFG_M_WorkOrderOperation woo INNER JOIN VAMFG_M_WorkOrderComponent woc ON woo.VAMFG_M_WorkOrderOperation_ID = woc.VAMFG_M_WorkOrderOperation_ID" + " WHERE woo.VAMFG_M_WorkOrder_ID = " + wot.GetVAMFG_M_WorkOrder_ID() + " AND woc.VAMFG_QtyRequired != 0 AND (woo.VAMFG_IsOptional <> 'Y' OR "); if (OperationFrom != null && OperationFrom.Value.CompareTo(Decimal.Zero) > 0) { sqlBuf.Append(" woo.VAMFG_SeqNo =" + VAdvantage.Utility.Util.GetValueOfInt(OperationFrom)); sqlBuf.Append(" OR woo.VAMFG_SeqNo =" + VAdvantage.Utility.Util.GetValueOfInt(OperationTo)); sqlBuf.Append(")"); } else { sqlBuf.Append(" woo.VAMFG_SeqNo =0"); sqlBuf.Append(" OR woo.VAMFG_SeqNo =0"); sqlBuf.Append(")"); } // Set OperationTo sequence no if (OperationTo != null && OperationTo.Value.CompareTo(Decimal.Zero) > 0) { sqlBuf.Append(" AND ((woo.VAMFG_SeqNo BETWEEN " + VAdvantage.Utility.Util.GetValueOfInt(OperationFrom) + " AND " + VAdvantage.Utility.Util.GetValueOfInt(OperationTo)); sqlBuf.Append(")"); } else { sqlBuf.Append(" AND ((woo.VAMFG_SeqNo BETWEEN " + lastMandatoryWOO + " AND 0"); sqlBuf.Append(")"); } if (assemblyPull) // if assembly pull, then get component lines from all operations except { sqlBuf.Append(" OR woc.VAMFG_SupplyType = 'A'"); } sqlBuf.Append(" ) ORDER BY woo.VAMFG_SeqNo, woc.M_Product_ID, woc.VAMFG_QtyRequired "); // close the statement and add ORDER BY clause String sql = sqlBuf.ToString(); // SqlParameter[] param = null; IDataReader idr = null; DataTable dt = new DataTable(); try { //pstmt.setInt(1, wot.GetVAMFG_M_WorkOrder_ID()); // woo.VAMFG_M_WorkOrder_ID //param = new SqlParameter[5]; //param[0] = new SqlParameter("@param1", wot.GetVAMFG_M_WorkOrder_ID()); //// Set OperationFrom sequence no //if (OperationFrom != null && OperationFrom.Value.CompareTo(Decimal.Zero) > 0) //{ // param[1] = new SqlParameter("@param2", VAdvantage.Utility.Util.GetValueOfInt(OperationFrom)); // param[3] = new SqlParameter("@param4", VAdvantage.Utility.Util.GetValueOfInt(OperationFrom)); // //pstmt.setInt(2, OperationFrom.intValue()); // //pstmt.setInt(4, OperationFrom.intValue()); //} //else //{ // param[1] = new SqlParameter("@param2", 0); // param[3] = new SqlParameter("@param4", 0); // //pstmt.setInt(2, 0); // //pstmt.setInt(4, 0); //} //// Set OperationTo sequence no //if (OperationTo != null && OperationTo.Value.CompareTo(Decimal.Zero) > 0) //{ // param[2] = new SqlParameter("@param3", VAdvantage.Utility.Util.GetValueOfInt(OperationTo)); // param[4] = new SqlParameter("@param5", VAdvantage.Utility.Util.GetValueOfInt(OperationTo)); // //pstmt.setInt(3, OperationTo.intValue()); // //pstmt.setInt(5, OperationTo.intValue()); //} //else //{ // param[2] = new SqlParameter("@param3", lastMandatoryWOO); // param[4] = new SqlParameter("@param5", 0); // //pstmt.setInt(3, lastMandatoryWOO); // //pstmt.setInt(5, 0); //} //rs = pstmt.executeQuery(); idr = DB.ExecuteReader(sql.ToString(), null, trx); //dt.Load(idr); //idr.Close(); int productID = 0; int uomID = 0; Decimal qtyEntered = Decimal.Zero; // Quantity in the Product Transaction Line Decimal QtyInKg = Decimal.Zero; // Quantity in KG at Product Transaction Line int asiID = 0; int locatorID = 0; // set the component line no to 10 greater than existing int compLineNo = DB.GetSQLValue(trx, "SELECT COALESCE(MAX(VAMFG_Line),0)+10 FROM VAMFG_M_WrkOdrTrnsctionLine " + "WHERE VAMFG_M_WrkOdrTransaction_ID =" + M_WorkOrderTransaction_ID); bool checkInventory = wot.GetVAMFG_WorkOrderTxnType().Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_1_ComponentIssueToWorkOrder); while (idr.Read()) { productID = VAdvantage.Utility.Util.GetValueOfInt(idr[0]); uomID = VAdvantage.Utility.Util.GetValueOfInt(idr[1]); Decimal qtyRequired = VAdvantage.Utility.Util.GetValueOfDecimal(idr[2]); String wocSupplyType = VAdvantage.Utility.Util.GetValueOfString(idr[3]); asiID = VAdvantage.Utility.Util.GetValueOfInt(idr[4]); locatorID = VAdvantage.Utility.Util.GetValueOfInt(idr[5]); String basisType = VAdvantage.Utility.Util.GetValueOfString(idr[6]); int wooID = VAdvantage.Utility.Util.GetValueOfInt(idr[7]); string IsQualityCorr = VAdvantage.Utility.Util.GetValueOfString(idr[12]); // If qty=0, then no value was passed for Qty // for Component Issue assume issue needs to be generated for remaining amount // for Component Return assume return needs to be generated for unused quantity Decimal qtyIssued = VAdvantage.Utility.Util.GetValueOfDecimal(idr[8]); Decimal qtySpent = VAdvantage.Utility.Util.GetValueOfDecimal(idr[9]); Decimal qtyAllocated = VAdvantage.Utility.Util.GetValueOfDecimal(idr[10]); Decimal qtyDedicated = VAdvantage.Utility.Util.GetValueOfDecimal(idr[11]); // continue if component line is quality correction if (IsQualityCorr == "Y") { continue; } if (Qty == null) { if (wot.GetVAMFG_WorkOrderTxnType().Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_1_ComponentIssueToWorkOrder)) { // qtyEntered = (qtyRequired.multiply(woQty)).subtract(qtyIssued).subtract(qtyAllocated).subtract(qtyDedicated); qtyEntered = Decimal.Subtract(Decimal.Subtract(Decimal.Subtract(Decimal.Multiply(qtyRequired, woQty), qtyIssued), qtyAllocated), qtyDedicated); } else // automatically assume ComponentReturn txn { qtyEntered = Decimal.Subtract(qtyIssued, qtySpent); } } else { qtyEntered = Decimal.Multiply(qtyRequired, Qty.Value); if (wot.GetVAMFG_WorkOrderTxnType().Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_ComponentReturnFromWorkOrder) //&& qtyEntered.setScale(MUOM.getPrecision(ctx, uomID), Decimal.ROUND_HALF_UP).compareTo(qtyIssued.subtract(qtySpent)) > 0) && Decimal.Round((qtyEntered), VAdvantage.Model.MUOM.GetPrecision(ctx, uomID), MidpointRounding.AwayFromZero).CompareTo(Decimal.Subtract(qtyIssued, qtySpent)) > 0) { log.Warning("Not enough quantities to return from Work Order"); continue; } } // For Pull type: If quantity requirement has been filled or there are not enough quantities to issue // then don't generate a line -> goto next line processing //if (qtyEntered.setScale(MUOM.getPrecision(ctx, uomID), Decimal.ROUND_HALF_UP).compareTo(Decimal.Zero) <= 0) // continue; if (Decimal.Round((qtyEntered), VAdvantage.Model.MUOM.GetPrecision(ctx, uomID), MidpointRounding.AwayFromZero).CompareTo(Decimal.Zero) <= 0) { continue; } if (SupplyType.Equals(wocSupplyType) || (wocSupplyType.Equals(X_VAMFG_M_WorkOrderComponent.VAMFG_SUPPLYTYPE_AssemblyPull) && assemblyPull && !SupplyType.Equals(X_VAMFG_M_WorkOrderComponent.VAMFG_SUPPLYTYPE_Push))) { ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine compIssueLine = new ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine(ctx, 0, trx); // set the client + org derived from the transaction header compIssueLine.SetClientOrg(wot); // Work done to add attributeset Instance ID for finished products compIssueLine.SetRequiredColumns(M_WorkOrderTransaction_ID, productID, asiID, uomID, qtyEntered, wooID, basisType); // Added by Bharat on 26 Dec 2017 to set Business Partner Information on Line compIssueLine.SetC_BPartner_ID(wot.GetC_BPartner_ID()); compIssueLine.SetC_BPartner_Location_ID(wot.GetC_BPartner_Location_ID()); if (locatorID != 0) // Implicit assumption : Only Pull components will have a locator populated in the WOC { // compIssueLine.SetM_Locator_ID(locatorID); ((X_VAMFG_M_WrkOdrTrnsctionLine)compIssueLine).SetM_Locator_ID(locatorID); } else { // Check if the locator passed is under the Warehouse of the Work Order // If no, then skip generating transaction line for this component ViennaAdvantage.Model.MVAMFGMWorkOrder wo = new ViennaAdvantage.Model.MVAMFGMWorkOrder(ctx, wot.GetVAMFG_M_WorkOrder_ID(), trx); MLocator loc = new MLocator(ctx, M_Locator_ID, trx); if (loc.GetM_Warehouse_ID() != wo.GetM_Warehouse_ID()) { log.Warning("Locator passed is not under the Warehouse of the WorkOrder"); continue; } ((X_VAMFG_M_WrkOdrTrnsctionLine)compIssueLine).SetM_Locator_ID(M_Locator_ID); } if (asiID > 0) { compIssueLine.SetM_AttributeSetInstance_ID(asiID); } compIssueLine.SetVAMFG_Line(compLineNo); compLineNo += 10; // Added by Bharat on 20/12/2016 to Set Density and Liter values for production execution Process of Gulf Oil. if (_countGOM01 > 0) { Decimal density = wot.GetGOM01_Density(); QtyInKg = Decimal.Multiply(qtyEntered, density); QtyInKg = Decimal.Round((QtyInKg), VAdvantage.Model.MUOM.GetPrecision(ctx, uomID)); Decimal ltrQty = density > 0 ? QtyInKg / density : 0; compIssueLine.SetGOM01_Quantity(QtyInKg); compIssueLine.SetGOM01_ActualQuantity(QtyInKg); compIssueLine.SetGOM01_Density(density); compIssueLine.SetGOM01_Litre(Decimal.Round((ltrQty), VAdvantage.Model.MUOM.GetPrecision(ctx, uomID))); compIssueLine.SetGOM01_FromProcess(true); } // End Bharat wotLines.Add(compIssueLine); VAdvantage.Model.MProduct product = new VAdvantage.Model.MProduct(ctx, productID, trx); if (checkInventory) { if (_countGOM01 > 0) { response.Append(product.GetName() + ": ").Append(VerifyQuantity(product, wot, QtyInKg, asiID)).Append(" "); } else { response.Append(product.GetName() + ": ").Append(VerifyQuantity(product, wot, qtyEntered, asiID)).Append(" "); } } if (compIssueLine.Save()) { } } } } catch (Exception e) { log.Log(Level.SEVERE, sqlBuf.ToString(), e); log.Severe("SQL failure in checking component requirements"); return(null); } finally { if (idr != null) { idr.Close(); idr = null; } } //Not using this here we have save line one by one //if (save) //{ // if (!VAdvantage.Model.PO.SaveAll(trx, wotLines)) // { // log.Severe("Could not save component transaction lines."); // return null; // } //} log.SaveInfo("Info", response.ToString()); //return wotLines.toArray(new MVAMFGMWrkOdrTrnsctionLine[] { }); ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine[] newObject = null; try { newObject = (ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine[])wotLines.ToArray(typeof(ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine)); //newObject = new MVAMFGMWrkOdrTrnsctionLine[] { }; //newObject = Convert.ChangeType(wotLines.ToArray(), typeof(MVAMFGMWrkOdrTrnsctionLine[])); //newObject = lst.ToArray(); return(newObject); } catch { } return((ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine[])wotLines.ToArray()); }