//	API to add component transaction lines in M_WorkOrderTransactionLine. Called from MWarehouseTask for WMS integration.

        /**
         * Api to add component transaction lines.
         * @param ctx
         * @param VAMFG_M_WorkOrder_ID Work Order
         * @param M_WorkOrderComponent_ID Work Order Component
         * @param Qty Number of components to be issued
         * @param M_Locator_ID Supply Locator for the component
         * @param trx
         * @return int M_WorkOrderTransactionLine_ID
         */
        public int AddComponentTxnLine(Ctx ctx, int M_WorkOrderComponent_ID, Decimal Qty, int M_Locator_ID, Trx trx)
        {
            ViennaAdvantage.Model.MVAMFGMWorkOrderComponent woc = new ViennaAdvantage.Model.MVAMFGMWorkOrderComponent(ctx, M_WorkOrderComponent_ID, trx);
            MVAMFGMWorkOrderOperation woo = new MVAMFGMWorkOrderOperation(ctx, woc.GetVAMFG_M_WorkOrderOperation_ID(), trx);

            ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = RetrieveWOTxn(ctx, woo.GetVAMFG_M_WorkOrder_ID(), X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_1_ComponentIssueToWorkOrder, trx);
            if (wot == null)
            {
                log.Severe("Cannot create or retrieve WO Txn.");
                return(0);
            }

            ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine wotLine = new ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine(ctx, 0, trx);
            wotLine.SetRequiredColumns(wot.GetVAMFG_M_WrkOdrTransaction_ID(), woc.GetM_Product_ID(), woc.GetM_AttributeSetInstance_ID(), woc.GetC_UOM_ID(), Qty, woc.GetVAMFG_M_WorkOrderOperation_ID(), woc.GetBasisType());
            wotLine.SetC_BPartner_ID(wot.GetC_BPartner_ID());
            wotLine.SetC_BPartner_Location_ID(wot.GetC_BPartner_Location_ID());
            wotLine.SetM_Locator_ID(M_Locator_ID);

            if (save)
            {
                if (!wotLine.Save(trx))
                {
                    log.Severe("Could not save component transaction line.");
                    return(0);
                }
            }

            return(wotLine.GetVAMFG_M_WrkOdrTrnsctionLine_ID());
        }
        /**
         * api to generate component transaction lines in M_WorkOrderTransactionLine. Skips optional operations unless they are either part of starting operation sequence number or ending operation sequence number
         * uses Default Locator/ highest priority Locator of Warehouse of the WorkOrder
         * @param ctx
         * @param M_WorkOrderTransaction_ID Work Order Transaction header
         * @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 trx
         * @return MVAMFGMWrkOdrTrnsctionLine
         */
        public ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine[] GenerateComponentTxnLine(Ctx ctx, int M_WorkOrderTransaction_ID,
                                                                                           Decimal?Qty, Decimal?OperationFrom, Decimal?OperationTo, String SupplyType, Trx trx)
        {
            ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, M_WorkOrderTransaction_ID, trx);
            if (!((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("Invalid Work Order Txn DocStatus.");
                return(null);
            }

            int locatorID = wot.GetM_Locator_ID();

            if (0 == locatorID)
            {
                ViennaAdvantage.Model.MVAMFGMWorkOrder wo = new ViennaAdvantage.Model.MVAMFGMWorkOrder(ctx, wot.GetVAMFG_M_WorkOrder_ID(), trx);
                if (!wo.GetDocStatus().Equals(X_VAMFG_M_WorkOrder.DOCSTATUS_InProgress))
                {
                    log.Severe("Invalid Work Order DocStatus.");
                    return(null);
                }
                locatorID = (MWarehouse.Get(ctx, wo.GetM_Warehouse_ID())).GetDefaultM_Locator_ID();
            }

            return(GenerateComponentTxnLine(ctx, M_WorkOrderTransaction_ID,
                                            Qty, OperationFrom, OperationTo, SupplyType, locatorID, trx));
        }
 /**
  *  Get latest open work order transaction for the Work Order or create one
  * @param ctx
  * @param VAMFG_M_WorkOrder_ID Work Order
  * @param TxnType Work Order Transaction Type
  * @param trx
  * @return MVAMFGMWrkOdrTransaction - latest open work order transaction
  */
 public ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction RetrieveWOTxn(Ctx ctx, int VAMFG_M_WorkOrder_ID, String TxnType, Trx trx)
 {
     ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = null;
     if (wot == null)
     {
         wot = CreateWOTxn(ctx, VAMFG_M_WorkOrder_ID, TxnType, trx);
     }
     return(wot);
 }
        /**
         * verifyQuantity - checks that the warehouse specified in the work order transaction
         * has sufficient quantity of the product
         * @param product
         * @param wot
         * @param qty
         * @param asiID
         * @return error message if any, else Quantity Available
         */
        private String VerifyQuantity(VAdvantage.Model.MProduct product, ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot, Decimal qty, int asiID)
        {
            if (product.IsStocked())
            {
                ViennaAdvantage.Model.MVAMFGMWorkOrder wo = new ViennaAdvantage.Model.MVAMFGMWorkOrder(wot.GetCtx(), wot.GetVAMFG_M_WorkOrder_ID(), wot.Get_TrxName());
                int M_Warehouse_ID = wo.GetM_Warehouse_ID();

                //logic change by Raghu
                //Decimal available = ViennaAdvantage.Model.Storage.GetQtyAvailable
                //(M_Warehouse_ID, product.GetM_Product_ID(), asiID, null);

                // during creation of production execution line, reserverd qty to be checked or not
                Decimal?available = 0.0M;
                if (VAdvantage.Utility.Util.GetValueOfString(wot.GetConsiderReservedQty()) == "N")
                {
                    try
                    {
                        available = MStorage.GetQtyAvailableWithoutReserved
                                        (M_Warehouse_ID, product.GetM_Product_ID(), asiID, null);
                    }
                    catch
                    {
                        return(Msg.GetMsg(wot.GetCtx(), "PleaseUpdateVAFramework"));
                    }
                }
                else
                {
                    available = MStorage.GetQtyAvailable
                                    (M_Warehouse_ID, product.GetM_Product_ID(), asiID, null);
                }

                if (available == null)
                {
                    available = Env.ZERO;
                }
                if (Env.Signum(available.Value) == 0)
                {
                    return(Msg.GetMsg(wot.GetCtx(), "NoQtyAvailable", "0"));
                }
                else if (available.Value.CompareTo(qty) < 0)
                {
                    return(Msg.GetMsg(wot.GetCtx(), "InsufficientQtyAvailable", available.ToString()));
                }
            }
            return(Msg.GetMsg(wot.GetCtx(), "QtyAvailable"));
        } // verifyQuantity
        /// <summary>
        /// Generates Resource Txn Lines against WO Txn for quantity earlier estimated and not yet used for all the operations in the Work Order; skips the optional operations
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="M_WorkOrderTransaction_ID"></param>
        /// <param name="Qty"></param>
        /// <param name="trx"></param>
        /// <param name="automatic"></param>
        /// <returns></returns>

        public MVAMFGMWrkOdrRscTxnLine[] GenerateResourceTxnLine(Ctx ctx, int M_WorkOrderTransaction_ID, Decimal Qty,
                                                                 Trx trx, bool automatic)
        {
            ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, M_WorkOrderTransaction_ID, trx);
            if (wot != null && !(wot.GetVAMFG_WorkOrderTxnType().Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_ResourceUsage) &&
                                 (wot.GetDocStatus().Equals(X_VAMFG_M_WrkOdrTransaction.DOCSTATUS_Drafted) || wot.GetDocStatus().Equals(X_VAMFG_M_WrkOdrTransaction.DOCSTATUS_InProgress))))
            {
                log.Severe("Work Order transaction type not correct.");
                return(null);
            }

            int OperationFrom = DB.GetSQLValue(trx, "SELECT MIN(VAMFG_SeqNo) FROM VAMFG_M_WorkOrderOperation " +
                                               "WHERE VAMFG_M_WorkOrder_ID = " + wot.GetVAMFG_M_WorkOrder_ID() + " AND VAMFG_IsOptional<> 'Y'");
            int OperationTo = 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'");

            return(GenerateResourceTxnLine(ctx, M_WorkOrderTransaction_ID, Qty,
                                           new Decimal(OperationFrom), new Decimal(OperationTo), trx, automatic));
        }
        /**
         * api to generate component transaction lines in M_WorkOrderTransactionLine
         * uses OperationFrom as the 1st Operation of WO
         * uses OperationTo as the last
         * @param ctx
         * @param M_WorkOrderTransaction_ID Work Order Transaction header
         * @param Qty Number of Work Order Product Assemblies for which to generate components
         * @param SupplyType Component Supply Type. Valid values are P (Push), O (Operation Pull), A (Assembly Pull)
         * @param trx
         * @return Array of MVAMFGMWrkOdrTrnsctionLine on success, null otherwise
         */
        public ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine[] GenerateComponentTxnLine(Ctx ctx, int M_WorkOrderTransaction_ID,
                                                                                           Decimal Qty, String SupplyType, Trx trx)
        {
            ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, M_WorkOrderTransaction_ID, trx);
            if (!((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("Invalid Work Order Txn DocStatus.");
                return(null);
            }

            int OperationFrom = DB.GetSQLValue(trx, "SELECT MIN(VAMFG_SeqNo) FROM VAMFG_M_WorkOrderOperation WHERE VAMFG_M_WorkOrder_ID = " + wot.GetVAMFG_M_WorkOrder_ID() +
                                               "AND VAMFG_IsOptional <> 'Y'");
            int OperationTo = 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'");

            return(GenerateComponentTxnLine(ctx, M_WorkOrderTransaction_ID, Qty,
                                            new Decimal(OperationFrom), new Decimal(OperationTo), SupplyType, trx));
        }
Пример #7
0
        /**
         *  Perform process.
         *  @return Message
         *  @throws Exception
         */
        //@Override
        protected override String DoIt()
        {
            if (0 == p_M_WorkOrderTransaction_ID)
            {
                throw new Exception("@FillMandatory@ @M_WorkOrderTransaction_ID@");
            }
            ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction woTxn = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(GetCtx(), p_M_WorkOrderTransaction_ID, Get_TrxName());
            ViennaAdvantage.Model.MVAMFGMWorkOrder         wo    = new ViennaAdvantage.Model.MVAMFGMWorkOrder(GetCtx(), woTxn.GetVAMFG_M_WorkOrder_ID(), Get_TrxName());

            VAdvantage.Model.MBOM bom         = new VAdvantage.Model.MBOM(GetCtx(), wo.GetM_BOM_ID(), Get_TrxName());
            MBOMProduct[]         BOMproducts = MBOMProduct.GetOfBOM(bom);
            for (int i = 0; i < BOMproducts.Length; i++)
            {
                string  prodensity = "SELECT nvl(GOM01_DENSITY,0) FROM VAMFG_M_WorkOrder WHERE VAMFG_M_WorkOrder_ID =" + woTxn.GetVAMFG_M_WorkOrder_ID();
                decimal DenQty     = VAdvantage.Utility.Util.GetValueOfDecimal(DB.ExecuteScalar(prodensity));
                if (DenQty == 0)
                {
                    DenQty = 1;
                }

                MBOMProduct BOMproduct = BOMproducts[i];
                decimal     qtyReqd    = (p_Qty * BOMproduct.GetBOMQty()) * DenQty;

                //string qry = "SELECT currentqty FROM M_Transaction WHERE M_Transaction_ID = (SELECT MAX(M_Transaction_ID)   FROM M_Transaction  WHERE movementdate = " +
                //            " (SELECT MAX(movementdate) FROM M_Transaction WHERE movementdate <= " + GlobalVariable.TO_DATE(woTxn.GetVAMFG_DateTrx(), true) + " AND  M_Product_ID = " + BOMproduct.GetM_ProductBOM_ID() + " AND M_Locator_ID = " + woTxn.GetM_Locator_ID() +
                //            " AND M_AttributeSetInstance_ID = " + BOMproduct.GetM_AttributeSetInstance_ID() + ") AND  M_Product_ID = " + BOMproduct.GetM_ProductBOM_ID() + " AND M_Locator_ID = " + woTxn.GetM_Locator_ID() +
                //            " AND M_AttributeSetInstance_ID = " + BOMproduct.GetM_AttributeSetInstance_ID() + ") AND AD_Org_ID = " + woTxn.GetAD_Org_ID() + " AND  M_Product_ID = " + BOMproduct.GetM_ProductBOM_ID() +
                //            " AND M_Locator_ID = " + woTxn.GetM_Locator_ID() + " AND M_AttributeSetInstance_ID = " + BOMproduct.GetM_AttributeSetInstance_ID();
                //decimal CurrentQty = VAdvantage.Utility.Util.GetValueOfDecimal(DB.ExecuteScalar(qry));
                //if (CurrentQty < qtyReqd)
                //{
                //    ViennaAdvantage.Model.MProduct product = new ViennaAdvantage.Model.MProduct(GetCtx(), BOMproduct.GetM_ProductBOM_ID(), Get_Trx());
                //    return "Insufficient qty in warehouse for : " + product.GetName();
                //}

                VAdvantage.Model.MStorage st = VAdvantage.Model.MStorage.Get(Env.GetCtx(), woTxn.GetM_Locator_ID(), BOMproduct.GetM_ProductBOM_ID(), BOMproduct.GetM_AttributeSetInstance_ID(), Get_TrxName());
                if (st == null)
                {
                    ViennaAdvantage.Model.MProduct product = new ViennaAdvantage.Model.MProduct(GetCtx(), BOMproduct.GetM_ProductBOM_ID(), Get_Trx());
                    return("Insufficient qty in warehouse for : " + product.GetName());
                }
                decimal CurrentQty = st.GetQtyOnHand();
                if (CurrentQty < qtyReqd)
                {
                    ViennaAdvantage.Model.MProduct product = new ViennaAdvantage.Model.MProduct(GetCtx(), BOMproduct.GetM_ProductBOM_ID(), Get_Trx());
                    return("Insufficient qty in warehouse for : " + product.GetName());
                }
            }

            if (p_Qty == 0)
            {
                //MVAMFGMWorkOrder wo = new MVAMFGMWorkOrder(GetCtx(), woTxn.GetVAMFG_M_WorkOrder_ID(), Get_TrxName());
                // p_Qty = wo.GetVAMFG_QtyEntered().subtract(wo.GetVAMFG_QtyAssembled());
                string prdOrdQry = "SELECT SUM(wkt.VAMFG_QtyEntered) AS ProdOrder FROM VAMFG_M_WrkOdrTransaction wkt WHERE wkt.VAMFG_WorkOrderTxnType ='CI' AND wkt.M_Product_ID = "
                                   + woTxn.GetM_Product_ID() + " AND wkt.VAMFG_M_Workorder_ID = " + woTxn.GetVAMFG_M_WorkOrder_ID() + " AND wkt.DocStatus ='CO'";

                Decimal ProdOrdQty = VAdvantage.Utility.Util.GetValueOfDecimal(DB.ExecuteScalar(prdOrdQry, null, Get_TrxName()));
                p_Qty = Decimal.Subtract(wo.GetVAMFG_QtyEntered(), (ProdOrdQty));
                //p_Qty = Decimal.Subtract(wo.GetVAMFG_QtyEntered(), (wo.GetVAMFG_QtyAssembled()));

                //log.Info ("@Quantity@ = " + wo.GetVAMFG_QtyEntered().subtract(wo.GetVAMFG_QtyAssembled().add(wo.GetVAMFG_QtyScrapped())));
                log.Info("@Quantity@ = " + Decimal.Subtract(wo.GetVAMFG_QtyEntered(), Decimal.Add(wo.GetVAMFG_QtyAssembled(), (wo.GetVAMFG_QtyScrapped()))));
            }

            //woTxn.SetVAMFG_QtyEntered(p_Qty.setScale(MUOM.GetPrecision(GetCtx(), woTxn.GetC_UOM_ID()), Decimal.ROUND_HALF_UP));
            woTxn.SetVAMFG_QtyEntered(Decimal.Round((p_Qty), VAdvantage.Model.MUOM.GetPrecision(woTxn.GetCtx(), woTxn.GetC_UOM_ID()), MidpointRounding.AwayFromZero));
            // Added by Bharat on 20/12/2016 to Set Density and Liter values for production execution Process of Gulf Oil.
            Tuple <String, String, String> mInfo = null;

            if (Env.HasModulePrefix("GOM01_", out mInfo))
            {
                woTxn.SetGOM01_Density(wo.GetGOM01_Density());
                Decimal qtyKg = Decimal.Multiply(wo.GetGOM01_Density(), woTxn.GetVAMFG_QtyEntered());
                woTxn.SetGOM01_Quantity(Decimal.Round((qtyKg), MUOM.GetPrecision(woTxn.GetCtx(), woTxn.GetC_UOM_ID()), MidpointRounding.AwayFromZero));
            }
            woTxn.Save();

            ViennaAdvantage.Process.MWorkOrderTxnUtil prodTxnLines = new ViennaAdvantage.Process.MWorkOrderTxnUtil(true);
            // Done by Bharat on 24 Jan 2018 to delete lines as when process runs multiple times it creates duplicate lines.
            int no = DB.ExecuteQuery("DELETE FROM VAMFG_M_WrkOdrTrnsctionLine WHERE VAMFG_M_WrkOdrTransaction_ID = " + p_M_WorkOrderTransaction_ID, null, Get_TrxName());

            ViennaAdvantage.Model.MVAMFGMWrkOdrTrnsctionLine[] wotlines = prodTxnLines.GenerateComponentTxnLine(GetCtx(), p_M_WorkOrderTransaction_ID, p_Qty,
                                                                                                                X_VAMFG_M_WorkOrderComponent.VAMFG_SUPPLYTYPE_Push, Get_TrxName());

            if (wotlines != null && wotlines.Length > 0)
            {
                return("Generated " + wotlines.Length + " line(s) for component(s): " + VLogger.RetrieveInfo().GetName());
            }
            else
            {
                return("Generated 0 lines for components.");
            }
        }
        /// <summary>
        /// Generates Resource Transaction Lines against WO Txn between &
        /// including specified operation VAMFG_SeqNo; skips the optional operations unless
        /// they are either the starting operation sequence or ending operation sequence
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="M_WorkOrderTransaction_ID"></param>
        /// <param name="Qty"></param>
        /// <param name="OperationFrom"></param>
        /// <param name="OperationTo"></param>
        /// <param name="trx"></param>
        /// <param name="automatic"></param>
        /// <returns></returns>
        public MVAMFGMWrkOdrRscTxnLine[] GenerateResourceTxnLine(Ctx ctx, int M_WorkOrderTransaction_ID, Decimal?Qty,
                                                                 Decimal?OperationFrom, Decimal?OperationTo, Trx trx, bool automatic)
        {
            if (0 >= M_WorkOrderTransaction_ID)
            {
                log.Severe("No Work Order Transaction ID specified");
                return(null);
            }

            if (OperationFrom.Value.CompareTo(OperationTo) > 0)
            {
                log.Severe("Operation Numbers not correct.");
                return(null);
            }

            if (Qty != null && Qty.Value.CompareTo(Decimal.Zero) <= 0)
            {
                log.Severe("Number of product assemblies must be positive");
                return(null);
            }

            ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, M_WorkOrderTransaction_ID, trx);
            if (wot != null && !(wot.GetVAMFG_WorkOrderTxnType().Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_ResourceUsage) &&
                                 (wot.GetDocStatus().Equals(X_VAMFG_M_WrkOdrTransaction.DOCSTATUS_Drafted) || wot.GetDocStatus().Equals(X_VAMFG_M_WrkOdrTransaction.DOCSTATUS_InProgress))))
            {
                log.Severe("Work Order transaction type not correct.");
                return(null);
            }

            //ArrayList<MVAMFGMWrkOdrRscTxnLine> wortLines = new ArrayList<MVAMFGMWrkOdrRscTxnLine>();
            // List<MVAMFGMWrkOdrRscTxnLine> wortLines=new List<MVAMFGMWrkOdrRscTxnLine>();
            System.Collections.ArrayList wortLines = new System.Collections.ArrayList();

            ViennaAdvantage.Model.MVAMFGMWorkOrder wo = new ViennaAdvantage.Model.MVAMFGMWorkOrder(ctx, wot.GetVAMFG_M_WorkOrder_ID(), trx);
            int resTxnLineSeqNo = DB.GetSQLValue(trx, "SELECT Max(VAMFG_SeqNo) FROM MVAMFGMWrkOdrRscTxnLine WHERE VAMFG_M_WrkOdrTransaction_ID =" + M_WorkOrderTransaction_ID);

            StringBuilder wc = new StringBuilder();

            if (OperationFrom.Value.CompareTo(Decimal.Zero) > 0)
            {
                wc.Append(" VAMFG_SeqNo >= ").Append(OperationFrom);
                if (OperationTo.Value.CompareTo(Decimal.Zero) > 0)
                {
                    wc.Append(" AND VAMFG_SeqNo <= ").Append(OperationTo);
                }
            }
            else if (OperationTo.Value.CompareTo(Decimal.Zero) > 0)
            {
                wc.Append(" VAMFG_SeqNo <= ").Append(OperationTo);
            }

            //	Don't consider the optional operations, but include the "From" and "To" operations even if they are optional
            wc.Append(" AND (VAMFG_IsOptional <> 'Y' ");
            if (OperationFrom.Value.CompareTo(Decimal.Zero) > 0)
            {
                wc.Append(" OR VAMFG_SeqNo = ").Append(OperationFrom);
            }
            if (OperationTo.Value.CompareTo(Decimal.Zero) > 0)
            {
                wc.Append(" OR VAMFG_SeqNo = ").Append(OperationTo);
            }
            wc.Append(" )");

            ViennaAdvantage.CMFG.Model.MVAMFGMWorkOrder worder = new CMFG.Model.MVAMFGMWorkOrder(ctx, wo.GetVAMFG_M_WorkOrder_ID(), trx);
            String whereClause = (wc.Length > 0 ? wc.ToString() : null);

            MVAMFGMWorkOrderOperation[] woos = MVAMFGMWorkOrderOperation.GetOfWorkOrder(worder, whereClause, "VAMFG_SeqNo");

            StringBuilder response = new StringBuilder();

            foreach (MVAMFGMWorkOrderOperation woo in woos)
            {
                MVAMFGMWorkOrderResource[] wors = MVAMFGMWorkOrderResource.GetofWorkOrderOperation(woo, null, null);
                foreach (MVAMFGMWorkOrderResource wor in wors)
                {
                    String chargeType = wor.GetVAMFG_ChargeType();
                    if (!((chargeType.Equals(X_VAMFG_M_WorkOrderResource.VAMFG_CHARGETYPE_Automatic) && automatic) ||
                          (chargeType.Equals(X_VAMFG_M_WorkOrderResource.VAMFG_CHARGETYPE_Manual) && !automatic)))
                    {
                        continue;
                    }
                    //calculated values
                    Decimal resAmt = Decimal.Zero;      //Resource amount to be charged
                    //if product assembly quantity, Qty, is null then derive based on how many have already been charged
                    //if estimated amt as indicated by WorkOrder Resource is already, then don't charge any more
                    if (Qty == null)
                    {
                        Decimal resCharged = wor.GetVAMFG_QtySpent();
                        Decimal resReq     = Decimal.Multiply(wo.GetVAMFG_QtyEntered(), (wor.GetVAMFG_QtyRequired()));
                        resAmt = Decimal.Subtract(resReq, (resCharged));
                        if (resAmt.CompareTo(Decimal.Zero) <= 0)
                        {
                            log.Warning("Estimated Resource usage has been already charged.");
                            continue;
                        }
                    }
                    else
                    {
                        resAmt = Decimal.Multiply(Qty.Value, (wor.GetVAMFG_QtyRequired()));
                    }

                    MVAMFGMWrkOdrRscTxnLine wortl = new MVAMFGMWrkOdrRscTxnLine(ctx, 0, trx);
                    //wortl.SetVAMFG_QtyEntered(resAmt.setScale(MUOM.getPrecision(ctx, wor.getC_UOM_ID()), Decimal.ROUND_HALF_UP));
                    wortl.SetVAMFG_QtyEntered(Decimal.Round((resAmt), VAdvantage.Model.MUOM.GetPrecision(ctx, wor.GetC_UOM_ID()), MidpointRounding.AwayFromZero));
                    // set fields from parent Work Order Transaction
                    wortl.SetVAMFG_M_WrkOdrTransaction_ID(M_WorkOrderTransaction_ID);
                    wortl.SetClientOrg(wot);

                    // set fields from Work Order Resource
                    wortl.Setresourceinfo(wor);

                    //increase the VAMFG_SeqNo for each WOResourceTxnLine
                    resTxnLineSeqNo += 10;
                    wortl.SetVAMFG_SeqNo(resTxnLineSeqNo);

                    wortl.SetIsActive(true);

                    //Add to the return ArrayList
                    wortLines.Add(wortl);

                    ViennaAdvantage.Model.MProduct product = ViennaAdvantage.Model.MProduct.Get(ctx, wortl.GetM_Product_ID());
                    response.Append(product.GetName() + ": ").Append(wortl.GetVAMFG_QtyEntered());
                    if (!wortl.Save())
                    {
                        log.Severe("Could not save resource transaction line.");
                    }
                }
            }

            if (save)
            {
                try
                {
                    if (!VAdvantage.Model.PO.SaveAll(trx, wortLines))
                    {
                        log.Severe("Could not save resource transaction line.");
                        return(null);
                    }
                }
                catch { }
            }
            log.SaveInfo("Info", response.ToString());
            // return (MVAMFGMWrkOdrRscTxnLine[])wortLines.ToArray();
            MVAMFGMWrkOdrRscTxnLine[] newObject = null;

            try
            {
                newObject = (MVAMFGMWrkOdrRscTxnLine[])wortLines.ToArray(typeof(MVAMFGMWrkOdrRscTxnLine));
                return(newObject);
            }
            catch { }
            return((MVAMFGMWrkOdrRscTxnLine[])wortLines.ToArray());
        }
        //	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());
        }
        /**
         * Creates a Work Order Transaction header for a given Work Order
         * Transactions handled : Resource Usage (RU), Component Return (CR), Component Issue (CI)
         * @param ctx
         * @param VAMFG_M_WorkOrder_ID Work Order
         * @param TxnType Work Order Transaction Type
         * @param parent_M_WorkOrderTransaction_ID Parent Work Order Transaction
         * @param M_Locator_ID Work Order Transaction Locator
         * @param Qty Work Order Transaction Quantity
         * @param trx
         * @return MVAMFGMWrkOdrTransaction
         */
        public ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction createWOTxn(Ctx ctx, int VAMFG_M_WorkOrder_ID, String TxnType,
                                                                          int parent_M_WorkOrderTransaction_ID, int M_Locator_ID, Decimal Qty, Trx trx)
        {
            int _countGOM01 = Convert.ToInt32(DB.ExecuteScalar("SELECT COUNT(AD_ModuleInfo_ID) FROM AD_ModuleInfo WHERE Prefix like 'GOM01_'"));

            if (!(TxnType.Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_ResourceUsage) ||
                  TxnType.Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_1_ComponentIssueToWorkOrder) ||
                  TxnType.Equals(X_VAMFG_M_WrkOdrTransaction.VAMFG_WORKORDERTXNTYPE_ComponentReturnFromWorkOrder)))
            {
                log.Severe("Not correct transaction type to generate WO Transaction");
                return(null);
            }
            //Check the validity of the Work Order
            ViennaAdvantage.Model.MVAMFGMWorkOrder wo = new ViennaAdvantage.Model.MVAMFGMWorkOrder(ctx, VAMFG_M_WorkOrder_ID, trx);
            if (wo == null || !wo.GetDocStatus().Equals(X_VAMFG_M_WorkOrder.DOCSTATUS_InProgress))
            {
                log.Severe("Work Order number not valid for transactions.");
                return(null);
            }

            //	Checking if Quantity can be derived from associated WorkOrder
            if (parent_M_WorkOrderTransaction_ID == 0)
            {
                if (Qty == null || Qty == 0)
                {
                    log.Info("Deriving Quantity from Work Order");
                    Qty = wo.GetVAMFG_QtyEntered();
                }
            }

            //Deriving Qty from parent WO Move Txn
            if (Qty.CompareTo(Decimal.Zero) <= 0)
            {
                ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction parentWOT = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, parent_M_WorkOrderTransaction_ID, trx);
                Qty = parentWOT.GetVAMFG_QtyEntered();
            }

            //Creating new WorkOrder Transaction
            ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction wot = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, 0, trx);
            wot.SetRequiredColumns(VAMFG_M_WorkOrder_ID, M_Locator_ID, X_VAMFG_M_WrkOdrTransaction.VAMFG_WOTXNSOURCE_Generated, TxnType);
            if (parent_M_WorkOrderTransaction_ID > 0)
            {
                wot.SetParentWorkOrderTxn_ID(parent_M_WorkOrderTransaction_ID);
                ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction parentWOT = new ViennaAdvantage.Model.MVAMFGMWrkOdrTransaction(ctx, parent_M_WorkOrderTransaction_ID, trx);
                wot.SetC_DocType_ID(parentWOT.GetC_DocType_ID());
                // set the client & org derived from parent work order transaction
                wot.SetClientOrg(parentWOT);
                if (_countGOM01 > 0)
                {
                    wot.SetGOM01_Density(parentWOT.GetGOM01_Density());
                    wot.SetGOM01_Quantity(parentWOT.GetGOM01_Quantity());
                    wot.SetGOM01_ActualQuantity(parentWOT.GetGOM01_ActualQuantity());
                    wot.SetGOM01_ActualDensity(parentWOT.GetGOM01_ActualDensity());
                    wot.SetGOM01_ActualLiter(parentWOT.GetGOM01_ActualLiter());
                }
            }
            else
            {   //	derive the doctype from the WorkOrderClass
                MVAMFGMWorkOrderClass woclass = new MVAMFGMWorkOrderClass(ctx, wo.GetVAMFG_M_WorkOrderClass_ID(), trx);
                wot.SetC_DocType_ID(woclass.GetWOT_DocType_ID());
                // since there is no parent work order transaction
                // set the client & org derived from the associated work order
                wot.SetClientOrg(wo);
            }
            //wot.SetVAMFG_QtyEntered(Qty.setScale(MUOM.getPrecision(ctx, wot.getC_UOM_ID()), Decimal.ROUND_HALF_UP));
            wot.SetVAMFG_QtyEntered(Decimal.Round((Qty), VAdvantage.Model.MUOM.GetPrecision(ctx, wot.GetC_UOM_ID()), MidpointRounding.AwayFromZero));
            if (save)
            {
                if (!wot.Save(trx))
                {
                    log.Severe("Could not save WO Txn.");
                    return(null);
                }
            }

            return(wot);
        }