using System;
using System.Data;
using System.Data.Common;
using Microsoft.VisualBasic;
using static iMESCore.Base.iMESComSubroutine;
using static iMESCore.Base.iMESComXML;
using static iMESCore.Base.iMESConst;
using static iMESCore.DataBase.iMESSql;
using iMESCore.Settings;
using Microsoft.VisualBasic.CompilerServices;
using System.Linq;

namespace MEStc_ABC
{


    public class clsLot_21674 : IDisposable
    {
        /*不使用modXX,不再使用OleDb
         * 資料庫相關(建立連線/讀取資料/異動資料),使用data_access_service.dll
         * 設定檔相關,使用iMESAppSetting
         * Xml相關,使用iMESComXML.dll
         * 常數相關,使用iMESConst.dll
         * 簡易副程式,使用iMESComSubroutine.dll
        */
        private udReverse.clsReverse objReverse = new udReverse.clsReverse();
        // 2006/05/10,sammi
        private AppSettings objSetting = new AppSettings();
        private clsDBCom objDBCom = new clsDBCom();
        private kcSYS.clsSYSUserLog objSYS = new kcSYS.clsSYSUserLog();   // 宣告Sys的物件
        private kcWIP.clsLot objLot = new kcWIP.clsLot();
        public iMESWIPReleaseLogHandler.clsLotReleaseLogHandle objLotLog;
        private string strConnectionString;       // Connection string
        private string strDataBaseType;           // DataBase Type:oracle, mysql, access
        private string strMQType;                 // MessageQueue Type:TIBCO, MQSeries, MSMQ
        private bool disposed = false;        // To detect redundant calls
        private string strSQL = "";
        private const int ActiveId_CI = 1;
        private const int ActiveId_CO = 2;
        private string strReportConnectionString;
        private string strReportDataBaseType;

        private string strSQLAddField;
        private string strSQLAddValue;
        private string strUploadPath;                   // WebServer放置上傳檔案的實體路徑
        private string cModuleNodeId = "N/A";
        private string cModuleNo = "N/A";
        private string cModuleVersion = "N/A";
        private string cStageNo = "N/A";
        private int cOPReference = 0;
        public string MaxWaitNo = defString;
        private string MNewLotSerial;


        private string strConnectionString_ERP;   // 2016-03-14, Joe, Add
        private string strDataBaseType_ERP;       // 2016-03-14, Joe, Add

        private string strConnectionString_eSOP;   // 2016-03-14, Joe, Add
        private string strDataBaseType_eSOP;       // 2016-03-14, Joe, Add
        #region --- Initial Object ---

        public clsLot_21674()
        {
            // Get database type
            strDataBaseType = objSetting.GetDataBaseType();
            // Get connection string    
            strConnectionString = objSetting.GetConnectionString(strDataBaseType);
            // Get Message Queue Type
            strMQType = objSetting.GetMQType();
        }

        #endregion

        #region --- Property ---

        // //Property--------------------------------------------------------------------------------------------------------------------------------
        public string ConnectionString
        {
            get
            {
                return strConnectionString;
            }
        }

        public string DataBaseType
        {
            get
            {
                return strDataBaseType;
            }
        }

        public string MQType
        {
            get
            {
                return strMQType;
            }
        }

        // 2003/03/22,sammi.
        // 因TC可能呼叫KC,在整個Function中,必須要使用同一個Reverse物件,如此在產生AddReverseUpdateContent的資料時,ReverseOrder才不會重覆.
        // 若KC再往下呼叫UD,則必須將Reverse物件傳遞予UD.
        //public object ReverseObj
        //{
        //    get
        //    {
        //        //return objReverse;
        //        // ReverseObj = objReverse
        //    }
        //}


        #endregion

        #region IDisposable Support
        private bool disposedValue; // 偵測多餘的呼叫

        // IDisposable
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: 處置 Managed 狀態 (Managed 物件)。
                }

                // TODO: 釋放 Unmanaged 資源 (Unmanaged 物件) 並覆寫下面的 Finalize()。
                // TODO: 將大型欄位設定為 null。
            }
            disposedValue = true;
        }

        // TODO: 只有當上面的 Dispose(ByVal disposing As Boolean) 有可釋放 Unmanaged 資源的程式碼時，才覆寫 Finalize()。
        // Protected Overrides Sub Finalize()
        // ' 請勿變更此程式碼。在上面的 Dispose(ByVal disposing As Boolean) 中輸入清除程式碼。
        // Dispose(False)
        // MyBase.Finalize()
        // End Sub

        // 由 Visual Basic 新增此程式碼以正確實作可處置的模式。
        public void Dispose()
        {
            // 請勿變更此程式碼。在以上的 Dispose 置入清除程式碼 (ByVal 視為布林值處置)。
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion


        public string LoadOPType(string OPType = defString, int IssueState = defInteger, string AdditionalXml = "")
        {
            string LoadOPTypeRet = null;
            // 此 Function 將資料以XML方式取出
            // 傳入值: 索引值
            // 傳回值: XML(成功), fail(失敗)


            DataSet dsOP = null;

            try
            {

                dsOP = ShowOPType(OPType, IssueState, AdditionalXml);

                // //Combine return value
                LoadOPTypeRet = CombineXMLReturnValue("loadoptype", "OPType", "DataSet", FormatXMLSchema(dsOP.GetXmlSchema()), dsOP.GetXml(), "");
            }

            catch (Exception e1)
            {
                LoadOPTypeRet = "fail";
                throw;
            } // New Exception("kcOP.LoadOPType: " & e1.Message)

            finally
            {
                if (dsOP != null)
                {
                    dsOP.Dispose();
                }
            }

            return LoadOPTypeRet;

        }

        public DataSet ShowOPType(string OPType = defString, int IssueState = defInteger, string AdditionalXml = "")
        {
            DataSet ShowOPTypeRet = null;

            // 此 Function 將資料以 Dataset 方式取出
            // 傳入值: 索引值
            // 傳回值: Dataset(成功), Nothing(失敗)


            DataSet dsOP = null;
            IDbConnection cnnTemp = null;

            try
            {
                // //Create connection
                cnnTemp = CreateConnection(strConnectionString);

                strSQL = "Select * From tblOPType Where OPType Is Not Null";
                if (OPType != defString)
                {
                    strSQL = strSQL + " And OPType = '" + OPType + "'";
                }
                if (IssueState != defInteger)
                {
                    strSQL = strSQL + " And IssueState = " + IssueState;
                }

                if (!string.IsNullOrEmpty(AdditionalXml))
                {
                    // 加上additional的condition
                    strSQL = strSQL + SeparateAddXML_Condition(AdditionalXml);
                }

                // //Select data
                dsOP = new DataSet();
                ExecuteSQLQuery_Adapter(strSQL, dsOP, "OPType", cnnTemp);

                // //Return data
                ShowOPTypeRet = dsOP;
            }

            catch (Exception e1)
            {
                ShowOPTypeRet = null;
                throw;
            }

            finally
            {
                CloseConnection(cnnTemp);
                if (dsOP != null)
                {
                    dsOP.Dispose();
                }
            }

            return ShowOPTypeRet;
        }

        public DataRow GetOPType(string OPType = defString, int IssueState = defInteger, string AdditionalXml = "")
        {
            DataRow GetOPTypeRet = null;
            // 此 Function 將資料以XML方式取出
            // 傳入值: 索引值
            // 傳回值: XML(成功), fail(失敗)


            DataSet dsOP = null;

            try
            {

                dsOP = ShowOPType(OPType, IssueState, AdditionalXml);

                // //Return data
                if (dsOP.Tables[0].Rows.Count > 0)
                {
                    GetOPTypeRet = dsOP.Tables[0].Rows[0];
                }
                else
                {
                    GetOPTypeRet = dsOP.Tables[0].NewRow();
                }
            }

            catch (Exception e1)
            {
                GetOPTypeRet = null;
                throw;
            } // New Exception("kcOP.LoadOPType: " & e1.Message)

            finally
            {
                if (dsOP != null)
                {
                    dsOP.Dispose();
                }
            }

            return GetOPTypeRet;

        }

        public string BR_CheckIn(long LotStamp, string LotNo, string LinkName, DataTable dtAttrib, 
            DataTable dtEquipment, string UserNo, string ShiftNo, string LotRecord = defString,
            DateTime CheckInTime = default(DateTime), string RuleNo = "", DataTable dtLoginState = null, 
            DataTable dtAccessory = null, DataTable dtMTLLot = null, string LanguageMode = defString, 
            DataTable dtEquipmentChamber = null,
            DataTable dtSelfDesgin = null)
        {
            string BR_CheckInRet = default(string);
            // 此 Function 將更新CheckIn Data
            // 傳入值: LotNo,dtAttrib,dtEquipment
            // 傳回值: success(成功), fail(失敗)

            IDbConnection cnnTemp = null;
            DbDataReader drTemp;
            var CollectionSQL = new Collection();
            var CollectionSQL_Rows = new Collection();
            string strSQL = "";

            string LotSerial, OPNo, BRNo, SerialNo, LogGroupSerial, BaseLotNo, CurQTY, NodeId;
            int PhaseNo;
            DateTime datEventTime;
            long lngLotStamp;

            //20240119 自定义字段
            string tblid;
            int isselect;
            try
            {
                // //Create connection
                cnnTemp = CreateConnection(strConnectionString);

                // 1.取出Temp LotState的資料
                strSQL = "Select A.LotSerial,A.OPNo,A.SerialNo,B.BRNo,B.LogGroupSerial,B.LotStamp,B.BaseLotNo,B.CurQTY,B.PhaseNo,B.NodeId " + " From tblWIPTemp_LotState A, tblWIPLotState B " + " Where A.LotNo ='" + LotNo + "'" + " And A.LotNo = B.LotNo ";
                // cmmTemp = New OleDb.OleDbCommand(strSQL, cnnTemp) 
                drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
                if (drTemp.Read())
                {
                    LotSerial = Conversions.ToString(drTemp["LotSerial"]);
                    OPNo = Conversions.ToString(drTemp["OPNo"]);
                    SerialNo = Conversions.ToString(drTemp["SerialNo"]);
                    BRNo = Conversions.ToString(drTemp["BRNo"]); 
                    LogGroupSerial = Conversions.ToString(drTemp["LogGroupSerial"]);
                    lngLotStamp = Conversions.ToLong(drTemp["LotStamp"]);
                    BaseLotNo = Conversions.ToString(drTemp["BaseLotNo"]);
                    CurQTY = Conversions.ToString(drTemp["CurQTY"]);
                    PhaseNo = Conversions.ToInteger(drTemp["PhaseNo"]); // 2020/11/20 Steven Mantis:	0082084: [PAD]eRunCard_調整 BR 生產記錄
                    NodeId = drTemp["NodeId"].ToString(); // 2023/06/05, 0135702: [6.0.7] SDD220425_01-03_進站設備派工查核調整, 19245
                }
                else
                {
                    throw new iMESException.MESException("0000-202003", "[%LotNo%] : " + LotNo);
                }
                drTemp.Close();


                datEventTime = DateTime.Now;

                // 若無指定CheckInTime,則同datEventTime.因機時、工時使用CheckInTime,必須一定要有資料.
                if (CheckInTime == defDateTime)
                {
                    CheckInTime = datEventTime;
                }

                // 20210909 13871,生產批下線歷程,add parameter
                if (objLotLog == null)
                    objLotLog = new iMESWIPReleaseLogHandler.clsLotReleaseLogHandle(ActiveId_CI, UserNo, CheckInTime);
                if (objLotLog.ColSQL == null)
                    objLotLog.ColSQL = CollectionSQL;
                if (objLotLog.ColSQL_Rows == null)
                    objLotLog.ColSQL_Rows = CollectionSQL_Rows;

                // 寫入管制時間
                udWIP.clsWIP objUdWIP;
                objUdWIP = new udWIP.clsWIP();
                objUdWIP.SHR_LimitedTimeControl_ByBR(ref objReverse, LotNo, LogGroupSerial, LotSerial, UserNo, CheckInTime, ref cnnTemp, ref CollectionSQL);


                // 2.Update Temp/Content LotAttrib 
                objLot.SHR_UpdAttrib(LotNo, LogGroupSerial, ref dtAttrib, ref CollectionSQL, datEventTime);

                // 3.Equipment CheckIn
                objLot.SHR_CIEquipment(LotNo, LogGroupSerial, LotSerial, LotSerial, UserNo, datEventTime, ref cnnTemp, ref CollectionSQL, ref dtEquipment, SerialNo, dtAccessory: dtAccessory, dtAttrib: dtAttrib, CheckInTime: CheckInTime, EquipmentChamber: dtEquipmentChamber);

                // 4.Lot Record
                if (!string.IsNullOrEmpty(LotRecord) && (LotRecord ?? "") != defString)
                {
                    strSQL = "Insert into tblWIPCont_LotRecord(LogGroupSerial,BaseLotNo,LotNo,LotSerial,OPNo,LotRecord,UserNo,EventTime)" + " Values('" + LogGroupSerial + "','" + BaseLotNo + "','" + LotNo + "','" + LotSerial + "','" + OPNo + "','" + LotRecord + "','" + UserNo + "'," + "To_Date('" + Strings.Format(datEventTime, "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'))";
                    CollectionSQL.Add(strSQL);
                    // Reverse
                    strSQL = "Delete From tblWIPCont_LotRecord Where LotSerial='" + LotSerial + "'";
                    Collection argcolSQL_Rows = null;
                    objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL, colSQL_Rows: argcolSQL_Rows);
                }

                // 2019/09/06 Eric 存入tblWIPTemp_MaterialLot
                if (dtMTLLot != null && dtMTLLot.Rows.Count > 0)
                {
                    foreach (DataRow r in dtMTLLot.Rows)
                    {
                        strSQL = "Insert into tblWIPTemp_MaterialLot(LotNo,MaterialNo,MaterialLotNo)" + " Values('" + LotNo + "','" + r["MaterialNo"].ToString() + "','" + r["MaterialLotNo"].ToString() + "')";
                        CollectionSQL.Add(strSQL);
                        // Reverse
                        strSQL = "Delete From tblWIPTemp_MaterialLot Where LotNo='" + LotNo + "' and MaterialNo='" + r["MaterialNo"].ToString() + "' and MaterialLotNo='" + r["MaterialLotNo"].ToString() + "'";
                        Collection argcolSQL_Rows1 = null;
                        objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL, colSQL_Rows: argcolSQL_Rows1);
                    }
                }

                //20240119 存入自定义表tbl_21674Desgin

                if (dtSelfDesgin != null && dtSelfDesgin.Rows.Count > 0)
                {
                    foreach (DataRow r in dtSelfDesgin.Rows)
                    {
                        strSQL = "Update tbl_21674Desgin Set TblId = '" + r["TblId"] + "',LotNo = '" + LotNo + "',IsSelect = '" + 1 + "' where TblId ='" + r["TblId"] + "'";
                        CollectionSQL.Add(strSQL);

                        // Reverse 回复处理之后释放该表自定义编号的选取状态
                        strSQL = "Update tbl_21674Desgin Set LotNo = '" + null + "',IsSelect = '" + 0 + "' where TblId ='" + r["TblId"] + "'";
                        Collection argcolSQL_Rows1 = null;
                        objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL, colSQL_Rows: argcolSQL_Rows1);
                    }
                }



                // 4.5 UPDate tblWIPEQPConsumeState.CurQTY & tblWIPEQPConsumeState.CurPeriod (Undo必須為同一料批才可Undo)
                if (dtEquipment != null && dtEquipment.Rows.Count > 0)
                {
                    objLot.SHR_UpdWIPEQPConsumeState(LotSerial, Conversions.ToDecimal(CurQTY), dtEquipment, ref CollectionSQL);
                }

                // 2020/02/26 Grace Mantis 67753, 取得生產批於作業站中, check in 日期的設備派工資料
                if (dtEquipment != null && dtEquipment.Rows.Count > 0)
                {

                    foreach (DataRow dr in dtEquipment.Rows)
                    {
                        DataSet dsEQPTemp;

                        using (var objWIP = new kcWIP.clsWIP())
                        {
                            dsEQPTemp = objWIP.ShowWIPEQPDispatchState(dr["EquipmentNo"].ToString(), LotNo, OPNo, CheckInTime);
                        }

                        if (!(dsEQPTemp == null))
                        {

                            foreach (DataRow drEQP in dsEQPTemp.Tables[0].Rows)
                            {

                                using (var objWIP = new kcWIP.clsWIP())
                                {
                                    // 寫Log
                                    objWIP.AddWIPEQPDispatchLog(dr["EquipmentNo"].ToString(), LotNo, OPNo, CheckInTime, Convert.ToInt32(drEQP["DispatchOrder"]), CollectionSQL);
                                    // Reverse
                                    strSQL = "Delete From tblWIPEQPDispatchLog " + " Where EquipmentNo='" + dr["EquipmentNo"].ToString() + "' " + "   And OPNO='" + OPNo + "' " + "   And LotNo='" + LotNo + "' " + "   And DispatchDate=To_Date('" + Strings.Format(CheckInTime, "yyyy/MM/dd") + "','YYYY/MM/DD') ";
                                    // 2020/04/08 Grace 增加SQL置換, 避免使用MSSQL執行Reverse時報錯
                                    strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                                    Collection argcolSQL_Rows2 = null;
                                    objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL, colSQL_Rows: argcolSQL_Rows2);

                                    // 刪除派工 & 調整排序
                                    objWIP.DelWIPEQPDispatchState(dr["EquipmentNo"].ToString(), LotNo, OPNo, CheckInTime, CollectionSQL);

                                    // 取得刪除前的資料
                                    strSQL = "Select * " + "  From tblWIPEQPDispatchState Where EquipmentNo='" + dr["EquipmentNo"].ToString() + "' " + "   And OPNO='" + OPNo + "' " + "   And LotNo='" + LotNo + "' " + "   And DispatchDate=To_Date('" + Strings.Format(CheckInTime, "yyyy/MM/dd") + "','YYYY/MM/DD') ";
                                    strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                                    // cmmTemp = New OleDb.OleDbCommand(strSQL, cnnTemp) 
                                    drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
                                    if (drTemp.Read())
                                    {

                                        // Reverse
                                        strSQL = Conversions.ToString(" Insert into tblWIPEQPDispatchState(EquipmentNo,LotNo,OPNO,DispatchDate,DispatchOrder,EventUser,EventDate) " + " Values('" + drTemp["EquipmentNo"].ToString() + "','" + LotNo + "','" + OPNo + "',To_Date('" + Strings.Format(drTemp["DispatchDate"], "yyyy/MM/dd") + "','YYYY/MM/DD')," +
                                            drTemp["DispatchOrder"] + "," + " '" + drTemp["EventUser"] + "',To_Date('" + Strings.Format(drTemp["EventDate"], "yyyy/MM/dd H:mm:ss") +
                                            "','YYYY/MM/DD HH24:MI:SS')) ");
                                        // 2020/04/08 Grace 增加SQL置換, 避免使用MSSQL執行Reverse時報錯
                                        strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                                        Collection argcolSQL_Rows3 = null;
                                        objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL, colSQL_Rows: argcolSQL_Rows3);

                                        // Reverse
                                        if (Conversions.ToBoolean(Operators.ConditionalCompareObjectEqual(drTemp["DispatchOrder"], 1, false)))
                                        {
                                            // <1 找不到資料
                                            strSQL = Conversions.ToString("Update tblWIPEQPDispatchState set DispatchOrder = DispatchOrder + 1 " + " Where EquipmentNo='" + dr["EquipmentNo"].ToString() + "' " + "   And OPNo='" + OPNo + "' " + "   And DispatchDate=To_Date('" + Strings.Format(CheckInTime, "yyyy/MM/dd") + "','YYYY/MM/DD') " + "   And DispatchOrder = " +
                                                drTemp["DispatchOrder"] + "");
                                            // 2020/04/08 Grace 增加SQL置換, 避免使用MSSQL執行Reverse時報錯
                                            strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                                            Collection argcolSQL_Rows4 = null;
                                            objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL, colSQL_Rows: argcolSQL_Rows4);
                                        }
                                        else
                                        {
                                            strSQL = Conversions.ToString("Update tblWIPEQPDispatchState set DispatchOrder = DispatchOrder + 1 " + " Where EquipmentNo='" + dr["EquipmentNo"].ToString() + "' " + "   And OPNo='" + OPNo + "' " + "   And DispatchDate=To_Date('" + Strings.Format(CheckInTime, "yyyy/MM/dd") + "','YYYY/MM/DD') " + "   And DispatchOrder < " +
                                                drTemp["DispatchOrder"] + "");
                                            // 2020/04/08 Grace 增加SQL置換, 避免使用MSSQL執行Reverse時報錯
                                            strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                                            Collection argcolSQL_Rows5 = null;
                                            objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL, colSQL_Rows: argcolSQL_Rows5);
                                        }
                                    }
                                    drTemp.Close();

                                }
                            }
                        }
                    }
                }

                //2023/07/24, 0141393: [SA QA]RTD生产批进站成功后删除派工现况表方式调整 ,19245
                ////2023/06/05, 0135702: [6.0.7] SDD220425_01-03_進站設備派工查核調整, 19245
                //if (dtEquipment != null && dtEquipment.Rows.Count > 0)
                //{
                //    foreach (DataRow dr in dtEquipment.Rows)
                //    {
                //        DataSet dsEQPTemp;

                //        using (var objWIP = new kcWIP.clsWIP())
                //        {
                //            dsEQPTemp = objWIP.ShowWIPEQPLOTDISPATCH(dr["EquipmentNo"].ToString(), LotNo, OPNo, NodeId, CheckInTime);
                //        }

                //        if (dsEQPTemp != null && dsEQPTemp.Tables[0].Rows.Count > 0)
                //        {
                //            foreach (DataRow drEQP in dsEQPTemp.Tables[0].Rows)
                //            {
                //                using (var objWIP = new kcWIP.clsWIP())
                //                {
                //                    // 寫Log
                //                    objWIP.AddWIPEQPLOTDISPATCHLOG(dr["EquipmentNo"].ToString(), LotNo, OPNo, NodeId, CheckInTime, CollectionSQL);
                //                    // Reverse
                //                    strSQL = "Delete From tblWIPEQPLotDispatchLog " +
                //                    " Where EquipmentNo='" + dr["EquipmentNo"].ToString() + "' " +
                //                    "   And OPNO='" + OPNo + "' " +
                //                    "   And LotNo='" + LotNo + "' " +
                //                    "   And NodeId='" + NodeId + "' " +
                //                    "   And DispatchDate=To_Date('" + Strings.Format(CheckInTime, "yyyy/MM/dd") + "','YYYY/MM/DD') ";

                //                    strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                //                    objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL);

                //                    // 刪除派工
                //                    objWIP.DelWIPEQPLOTDISPATCHSTATE(dr["EquipmentNo"].ToString(), LotNo, OPNo, NodeId, CheckInTime, CollectionSQL);

                //                    // 取得刪除前的資料
                //                    strSQL = "Select * " +
                //                    "  From tblWIPEQPLotDispatchState Where EquipmentNo='" + dr["EquipmentNo"].ToString() + "' " +
                //                    "   And OPNO='" + OPNo + "' " +
                //                    "   And LotNo='" + LotNo + "' " +
                //                    "   And NodeId='" + NodeId + "' " +
                //                    "   And DispatchDate=To_Date('" + Strings.Format(CheckInTime, "yyyy/MM/dd") + "','YYYY/MM/DD') ";
                //                    strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                //                    drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
                //                    if (drTemp.Read())
                //                    {
                //                        // Reverse
                //                        strSQL = " Insert into tblWIPEQPLotDispatchState(EquipmentNo,LotNo,OPNO,NodeId,DispatchDate,DispatchOrder,DispatchType,DispatchShift,EventUser,EventDate) " +
                //                        " Values('" + drTemp["EquipmentNo"].ToString() + "','" + LotNo + "','" + OPNo + "','" + NodeId +
                //                        "',To_Date('" + Strings.Format(drTemp["DispatchDate"], "yyyy/MM/dd") + "','YYYY/MM/DD'),'" +
                //                        drTemp["DispatchOrder"] + "','" + drTemp["DispatchType"] + "','" + drTemp["DispatchShift"] +
                //                        "','" + drTemp["EventUser"] + "',To_Date('" +
                //                        Strings.Format(drTemp["EventDate"], "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')) ";


                //                        strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                //                        objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL);

                //                    }
                //                    drTemp.Close();
                //                }
                //            }
                //        }
                //        else // 與現況的設備不符合 仍進站
                //        {
                //            using (var objWIP = new kcWIP.clsWIP())
                //            {
                //                // 寫Log
                //                objWIP.AddWIPEQPLOTDISPATCHLOG(dr["EquipmentNo"].ToString(), LotNo, OPNo, NodeId, CheckInTime, CollectionSQL, true);
                //                // Reverse
                //                strSQL = "Delete From tblWIPEQPLotDispatchLog " +
                //                " Where EquipmentNo='" + dr["EquipmentNo"].ToString() + "' " +
                //                "   And OPNO='" + OPNo + "' " +
                //                "   And LotNo='" + LotNo + "' " +
                //                "   And NodeId='" + NodeId + "' ";

                //                strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                //                objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL);

                //                // 刪除派工,,不須傳入設備
                //                objWIP.DelWIPEQPLOTDISPATCHSTATE(defString, LotNo, OPNo, NodeId, CheckInTime, CollectionSQL, true);

                //                // 取得刪除前的資料
                //                strSQL = "Select * " +
                //                "  From tblWIPEQPLotDispatchState Where OPNO='" + OPNo + "' " +
                //                "   And LotNo='" + LotNo + "' " +
                //                "   And NodeId='" + NodeId + "' ";
                //                strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                //                drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
                //                DataTable dtTemp = new DataTable();
                //                dtTemp.Load(drTemp);
                //                drTemp.Close();

                //                if (dtTemp.Rows.Count > 0)
                //                {
                //                    foreach (DataRow drData in dtTemp.Rows)
                //                    {
                //                        // Reverse
                //                        strSQL = " Insert into tblWIPEQPLotDispatchState(EquipmentNo,LotNo,OPNO,NodeId,DispatchDate,DispatchOrder,DispatchType,DispatchShift,EventUser,EventDate) " +
                //                            " Values('" + drData["EquipmentNo"].ToString() + "','" + LotNo + "','" + OPNo + "','" + NodeId +
                //                            "',To_Date('" + Strings.Format(drData["DispatchDate"], "yyyy/MM/dd") + "','YYYY/MM/DD'),'" +
                //                            drData["DispatchOrder"] + "','" + drData["DispatchType"] + "','" + drData["DispatchShift"] +
                //                            "','" + drData["EventUser"] + "',To_Date('" +
                //                            Strings.Format(drData["EventDate"], "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')) ";

                //                        strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                //                        objReverse.AddReverseUpdateContent(ref LotSerial, ref strSQL, CollectionSQL);
                //                    }
                //                }
                //            }
                //        }
                //    }
                //}

                // 5.變更LotState--------------------------------------------------------------------------------------------------
                if (LinkName == "HOLD")
                {
                    // 因BR已執行完成,故Hold解除的續Go狀態為Complete(4)
                    int argGoStatus = 4;
                    objLot.funSetLotStateToERFCreate(ref LotNo, ref argGoStatus, ref datEventTime, ref CollectionSQL, EventUserNo: UserNo);
                }
                else if (LinkName == "WAIT")
                {
                    // 因BR已執行完成,故Wait解除的續Go狀態為Complete(4)
                    // RuleNo Added by Jialing 2011/02/18 將RuleNo填入WAIT說明
                    // 已登錄之多人加工必須登出.
                    int argGoStatus1 = 4;
                    objLot.funSetLotStateToWait(ref LotNo, ref argGoStatus1, ref datEventTime, ref CollectionSQL, EventUserNo: UserNo, LotStamp: lngLotStamp, WaitDescription: RuleNo, COMultiUser: true);
                }
                else
                {
                    // 4代表成功完成BR,紀錄LinkName若TransferLot失敗可以重新再執行TransferLot
                    int argStatus = 4;
                    objLot.funSetLotStateToOther(ref LotNo, ref argStatus, ref datEventTime, ref CollectionSQL, LinkName, EventUserNo: UserNo);
                }

                // 6.變更LotLog & Add Cont_Employee--------------------------------------------------------------------------------
                objLot.SHR_UpdLog(LotNo, LotSerial, LogGroupSerial, OPNo, BRNo, "BR_CheckIn", ShiftNo, UserNo, datEventTime, LinkName, ref CollectionSQL, Check_In_Out_Time: CheckInTime, PhaseNo: PhaseNo);

                // 7.變更LotLog_Report 
                objLot.SHR_UpdLogReport(ref cnnTemp, ref CollectionSQL, LogGroupSerial, LotSerial, CheckInTime);

                // 2015-12-11, Joe, SPC
                using (var objSPC = new kcSPC.clsSPC())
                {
                    objSPC.UpdSPCContorl_Var(LotNo, UserNo, ref dtAttrib, ref CollectionSQL);
                }

                // 2017/10/28,Sammi.取消舊的多人加工機制,改用新的上工下工.
                // 2017/12/01,Sammi.人時AutoRun平攤需求,將上工下工資料,整合入舊的多人加工機制.
                using (var obj = new kcWIP.clsOperatorState())
                {
                    obj.SHR_CI_EMP(ref cnnTemp, ref CollectionSQL, ref objReverse, 1, 1, UserNo, datEventTime, CheckInTime, LotNo, OPNo, LogGroupSerial, LotSerial, dtEquipment);
                }

                // If LinkName = "WAIT" Then
                // Call SHR_CIMultiUser_CO(CollectionSQL, 1, 1, LotNo, BaseLotNo, OPNo, LogGroupSerial, LotSerial, UserNo, datEventTime, dtLoginState)
                // Else
                // Call SHR_CIMultiUser(CollectionSQL, 1, 1, LotNo, BaseLotNo, OPNo, LogGroupSerial, LotSerial, UserNo, datEventTime, dtLoginState)
                // End If

                // 2017/09/25 YF, 叫用工單達交率處理者，判斷是否回寫實際開工日
                // 2020/03/17 OwenLiu, Mantis:0068929 工單實際開工日/工單實際完工日 調整還原機制的共用處理
                new kcOE.WorkOrderRateHandler().ActualStartDateProcess(pLotNo: LotNo, pLotSerial: LotSerial, pEventTime: CheckInTime, pCollectionSQL: CollectionSQL, objReverse: objReverse);

                // 20200424 Edison 70441: [605標準版]L_CI_GEN 品檢卡控
                // ======================================= 70441 Start =======================================
                // 81459 新增品檢結果資料表
                string strQCFormNo = ""; // 檢驗單號
                var ErrorMsg = new Collection();
                string strExpMsg = "";
                string MailErrorMsg = "";
                var dtInspResult = new DataTable("InspResult");
                dtInspResult.Columns.Add("EquipmentNo", Type.GetType("System.String"));
                dtInspResult.Columns.Add("EquipmentName", Type.GetType("System.String"));
                dtInspResult.Columns.Add("QCItemNo", Type.GetType("System.String"));
                dtInspResult.Columns.Add("QCItemName", Type.GetType("System.String"));
                dtInspResult.Columns.Add("QCItemType", Type.GetType("System.String"));
                dtInspResult.Columns.Add("InspType", Type.GetType("System.String"));
                dtInspResult.Columns.Add("InspTypeName", Type.GetType("System.String"));
                dtInspResult.Columns.Add("MailGroupNo", Type.GetType("System.String"));
                dtInspResult.Columns.Add("CCMailGroupNo", Type.GetType("System.String"));

                foreach (DataRow rEQP in dtEquipment.Rows)
                {
                    objLot.ChkQCInspection(ref MailErrorMsg, LotNo, OPNo, Conversions.ToString(rEQP["EquipmentNo"]), ref CollectionSQL, UserNo: UserNo, EventTime: datEventTime, ErrorMsg: ErrorMsg, dtInspResult: dtInspResult, LanguageMode: LanguageMode);
                    if (ErrorMsg.Count > 0)
                    {
                        strExpMsg = Conversions.ToString("[%EquipmentNo%]: " + rEQP["EquipmentNo"] + " " + Constants.vbCrLf + " ");
                        break;
                    }
                }

                if (ErrorMsg.Count > 0)
                {

                    // ===== 自動開立PQC檢驗單
                    string QCFormNo;
                    var ds = new DataSet();
                    DataTable dt;
                    DataTable chkdt;
                    ds = objLot.ShowLotBasisJoinState(LotNo: LotNo);
                    DataRow[] drSel;
                    drSel = ds.Tables[0].Select("LotNo = '" + LotNo + "'");
                    if (drSel.Length > 0)
                    {
                        string ProductNo = drSel[0]["ProductNo"].ToString();
                        string ProductVersion = drSel[0]["ProductVersion"].ToString();
                        string CustomerNo = drSel[0]["CustomerNo"].ToString();
                        string Qty = drSel[0]["CurQty"].ToString();
                        string strIsValid = "1";
                        using (var objSPC = new kcSPC.clsSPC())
                        {
                            dt = dtInspResult.DefaultView.ToTable(true, "QCItemNo", "QCItemName", "QCItemType", "InspType");
                            chkdt = dtInspResult.DefaultView.ToTable(true, "QCItemNo", "QCItemName");


                            string strQCItemNo_Exis;
                            var dtChkQCFormNo = new DataTable("ChkQCFormNo");
                            dtChkQCFormNo.Columns.Add("QCFormNo", Type.GetType("System.String"));
                            for (int k = 0, loopTo = chkdt.Rows.Count - 1; k <= loopTo; k++)
                            {
                                strSQL = " Select Distinct A.*,B.STATUS From tblSPCIPQCFormQCItemMap A ";
                                strSQL = strSQL + " Left Join TBLSPCIPQCFORM B on A.QCFORMNO=B.QCFORMNO ";
                                strSQL = strSQL + " where A.QCItemNo = '" + chkdt.Rows[k]["QCItemNo"].ToString() + "' AND B.STATUS IN (0,1,2) AND B.LOTNO = '" + LotNo + "'";
                                strSQL = SQLCommandTuning(strDataBaseType, ref strSQL);
                                // cmmTemp = New OleDb.OleDbCommand(strSQL, cnnTemp) 
                                drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
                                if (drTemp.HasRows)
                                {
                                    string chkStr = string.Empty;
                                    while (drTemp.Read()) // 找出未確認,待驗,已驗中項目所屬單號
                                    {
                                        var dr = dtChkQCFormNo.NewRow();
                                        dr["QCFormNo"] = drTemp["QCFormNo"].ToString();
                                        dtChkQCFormNo.Rows.Add(dr);
                                    }
                                    DataRow[] delRow;
                                    delRow = dt.Select("QCItemNo = '" + chkdt.Rows[k]["QCItemNo"].ToString() + "'"); // 已存在項目不需重複開單，移除
                                    if (delRow.Count() > 0)
                                    {
                                        for (int CntRow = 0, loopTo1 = delRow.Count() - 1; CntRow <= loopTo1; CntRow++)
                                            dt.Rows.Remove(delRow[CntRow]);
                                    }
                                    strQCItemNo_Exis = chkdt.Rows[k]["QCItemNo"].ToString() + ",";
                                }
                                drTemp.Close();

                            }
                            dtChkQCFormNo = dtChkQCFormNo.DefaultView.ToTable(true); // 過濾重複單號，供前端顯示
                            foreach (DataRow drRow in dtChkQCFormNo.Rows)
                            {
                                QCFormNo = Conversions.ToString(drRow["QCFormNo"]);
                                strQCFormNo += QCFormNo + ",";
                            }

                            if (dt.Rows.Count > 0)
                            {
                                for (int j = 0; j <= 8; j++)
                                {
                                    DataRow[] drSel_A;
                                    drSel_A = dt.Select("InspType = " + j + ""); // 找出檢驗頻率,一種頻率開出一張單
                                    if (drSel_A.Count() > 0)
                                    {
                                        using (var objSYSEng = new kcSYS.clsSYSEng())
                                        {
                                            QCFormNo = objSYSEng.GetIPQCFormNo(true);
                                            strQCFormNo += QCFormNo + ",";
                                        }
                                        objSPC.AddIPQCForm(QCFormNo, ProductNo, Conversions.ToDecimal(Qty), CustomerNo, LotNo, UserNo, OPNo: OPNo, ProductVersion: ProductVersion, S_OffLineHold: Conversions.ToInteger(false));
                                        for (int i = 0, loopTo2 = drSel_A.Count() - 1; i <= loopTo2; i++)
                                        {
                                            objSPC.AddIPQCFormQCItemMap(QCFormNo, drSel_A[i]["QCItemNo"].ToString(), drSel_A[i]["QCItemName"].ToString(), drSel_A[i]["QCItemType"].ToString());
                                            DataRow[] delRow;
                                            delRow = dt.Select("QCItemNo = '" + drSel_A[i]["QCItemNo"].ToString() + "'");
                                            if (delRow.Count() > 0)
                                            {
                                                for (int CntRow = 0, loopTo3 = delRow.Count() - 1; CntRow <= loopTo3; CntRow++)
                                                    dt.Rows.Remove(delRow[CntRow]);
                                            }
                                        }
                                    }
                                }
                            }

                        }
                    }
                    strQCFormNo = strQCFormNo.TrimEnd(',');
                    // =====

                    if (!string.IsNullOrEmpty(MailErrorMsg))
                    {
                        strExpMsg += MailErrorMsg + Constants.vbCrLf;
                    }
                    strExpMsg = "[%QC Inspection Items Has Not been Completed%],[%Please Execute PQC Inspection%]" + Constants.vbCrLf;
                    // For i As Integer = 1 To ErrorMsg.Count
                    strExpMsg += "[%IPQCNO%]: " + strQCFormNo;
                    // Next
                    throw new iMESException.MESException("IPQCNO", strExpMsg);
                }

                // 2020/11/20 Reo Mantis 82084 [PAD]eRunCard_調整 BR 生產記錄
                objLot.UpdWIPRuleCheckLog(LogGroupSerial, datEventTime, colSQL: CollectionSQL);
                // ======================================= 70441  End  =======================================

                // 8.檢查是否允許執行
                for (int i = 1, loopTo4 = CollectionSQL.Count; i <= loopTo4; i++)
                    CollectionSQL_Rows.Add(-1);

                // 12.檢查是否允許執行
                objLot.ChkLotStamp_RowCount(ref cnnTemp, ref CollectionSQL, ref CollectionSQL_Rows, LotNo, LotStamp);

                // 20210909 13871,生產批下線歷程
                objLotLog.funCreateSQL(LotNo: LotNo, SysActiveId: ActiveId_CI, ReferenceLotNo: LotNo);
                if (LinkName == "WAIT")
                {
                    var objWaitData = new iMESWIPReleaseLogHandler.clsLotReleaseLogHandle.clsLotData.clsWait()
                    { WaitType = 0, WaitNo = MaxWaitNo };
                    objLotLog.funCreateSQL(WaitData: objWaitData, LotNo: LotNo, SysActiveId: 11, ReferenceLotNo: LotNo);
                }

                // 呼叫執行SQL指令
                ExecuteSQLNoneQuery_ChkRowCount(strDataBaseType, strConnectionString, CollectionSQL, CollectionSQL_Rows);

                // //Return success
                BR_CheckInRet = "success";
            }
            catch (Exception e1)
            {
                BR_CheckInRet = "fail";
                throw;
            }
            finally
            {
                CloseConnection(cnnTemp);

            }
            return BR_CheckInRet;

        }


        public string LoadSelfDesginInfo(string SelfDesginInfo = defString, string AdditionalXml = "")
        {
            string LoadSelfDesginRet = null;
            // 此 Function 將資料以XML方式取出
            // 傳入值: 索引值
            // 傳回值: XML(成功), fail(失敗)


            DataSet dsOP = null;

            try
            {

                dsOP = ShowSelfDesginInfo(SelfDesginInfo, AdditionalXml);

                // //Combine return value
                LoadSelfDesginRet = CombineXMLReturnValue("loadselfdesgininfo", "SelfDesginInfo", "DataSet", FormatXMLSchema(dsOP.GetXmlSchema()), dsOP.GetXml(), "");
            }

            catch (Exception e1)
            {
                LoadSelfDesginRet = "fail";
                throw;
            } // New Exception("kcOP.LoadOPType: " & e1.Message)

            finally
            {
                if (dsOP != null)
                {
                    dsOP.Dispose();
                }
            }

            return LoadSelfDesginRet;

        }
        public string LoadSelfDesginInfo_CO(string SelfDesginLotNo = defString, string AdditionalXml = "")
        {
            string LoadSelfDesginRet = null;
            // 此 Function 將資料以XML方式取出
            // 傳入值: 索引值
            // 傳回值: XML(成功), fail(失敗)
            DataSet dsDS = null;
            try
            {
                dsDS = ShowSelfDesginInfo_CO(SelfDesginLotNo, AdditionalXml);
                // //Combine return value
                LoadSelfDesginRet = CombineXMLReturnValue("loadselfdesgininfo", "SelfDesginInfo", "DataSet", FormatXMLSchema(dsDS.GetXmlSchema()), dsDS.GetXml(), "");
            }
            catch (Exception e1)
            {
                LoadSelfDesginRet = "fail";
                throw;
            } // New Exception("kcOP.LoadOPType: " & e1.Message)
            finally
            {
                if (dsDS != null)
                {
                    dsDS.Dispose();
                }
            }
            return LoadSelfDesginRet;
        }

        public DataSet ShowSelfDesginInfo(string SelfDesginInfo = defString, string AdditionalXml = "")
        {
            DataSet ShowSelfDesginRet = null;

            // 此 Function 將資料以 Dataset 方式取出
            // 傳入值: 索引值
            // 傳回值: Dataset(成功), Nothing(失敗)


            DataSet dsSD = null;
            IDbConnection cnnTemp = null;

            try
            {
                // //Create connection
                cnnTemp = CreateConnection(strConnectionString);

                strSQL = "Select * From tbl_21674Desgin Where TBLId Is Not Null";
                /*if (SelfDesginInfo != defString)
                {
                    strSQL = strSQL + " And OPType = '" + SelfDesginInfo + "'";
                }
                if (IssueState != defInteger)
                {
                    strSQL = strSQL + " And IssueState = " + IssueState;
                }

                if (!string.IsNullOrEmpty(AdditionalXml))
                {
                    // 加上additional的condition
                    strSQL = strSQL + SeparateAddXML_Condition(AdditionalXml);
                }*/

                // //Select data
                dsSD = new DataSet();
                ExecuteSQLQuery_Adapter(strSQL, dsSD, "SelfDesginInfo", cnnTemp);

                // //Return data
                ShowSelfDesginRet = dsSD;
            }

            catch (Exception e1)
            {
                ShowSelfDesginRet = null;
                throw;
            }

            finally
            {
                CloseConnection(cnnTemp);
                if (dsSD != null)
                {
                    dsSD.Dispose();
                }
            }

            return ShowSelfDesginRet;
        }
        public DataSet ShowSelfDesginInfo_CO(string SelfDesginLotNo = defString, string AdditionalXml = "")
        {
            DataSet ShowSelfDesginRet = null;

            // 此 Function 將資料以 Dataset 方式取出
            // 傳入值: 索引值
            // 傳回值: Dataset(成功), Nothing(失敗)


            DataSet dsSD = null;
            IDbConnection cnnTemp = null;

            try
            {
                // //Create connection
                cnnTemp = CreateConnection(strConnectionString);

                strSQL = "Select TbLid,LotNo From tbl_21674Desgin Where LotNo = '"+ SelfDesginLotNo+"'";
                /*if (SelfDesginInfo != defString)
                {
                    strSQL = strSQL + " And OPType = '" + SelfDesginInfo + "'";
                }
                if (IssueState != defInteger)
                {
                    strSQL = strSQL + " And IssueState = " + IssueState;
                }

                if (!string.IsNullOrEmpty(AdditionalXml))
                {
                    // 加上additional的condition
                    strSQL = strSQL + SeparateAddXML_Condition(AdditionalXml);
                }*/

                // //Select data
                dsSD = new DataSet();
                ExecuteSQLQuery_Adapter(strSQL, dsSD, "SelfDesginInfo", cnnTemp);

                // //Return data
                ShowSelfDesginRet = dsSD;
            }

            catch (Exception e1)
            {
                ShowSelfDesginRet = null;
                throw;
            }

            finally
            {
                CloseConnection(cnnTemp);
                if (dsSD != null)
                {
                    dsSD.Dispose();
                }
            }

            return ShowSelfDesginRet;
        }
    }
}