using System; using System.Collections.Generic; using System.Data; using System.Linq; using iMESCIO.CDO.Tables; using iMESCIO.SCI.DPM.Request; using iMESCIO.SCI.DPM.Response; using iMESCIO.SCI.ERP.Request; using iMESCIO.SCI.ERP.Response; using iMESCIO.SCI.SMES.Request; using iMESCIO.SCI.SMES.Response; using iMESCore.Base.ProjectBase.Base; using iMESCore.Settings; using MESDAO.Tables; using Microsoft.VisualBasic; using Microsoft.VisualBasic.CompilerServices; using static iMESCore.DataBase.iMESSql; using static iMESCore.Base.iMESComSubroutine; namespace AutoRunLib_C { public class EAIMessageSynchronizer { public enum WorkCode { ContinueRun = 0, // 繼續執行作業 StopSame = 1, // 停止相同的作業 StopAll = 2 // 停止所有作業 } private string strDataBaseType; // DataBase Type:oracle, mysql, access private string strConnectionString; // Connection string private string strReportDataBaseType; private string strReportConnectionString; // Report DB Connection string private string strERPconnectionString; private string strERPDataBaseType; private string strERPReportConnectionString; private string InXML, OutXML; private string RequestKey = ""; private AppSettings objSetting = new AppSettings(); private string strLanguageMode = "zh-cht"; private string strResourceDir = "Resources"; // //Initial Object-------------------------------------------------------------------------------------------------------------------------------- public EAIMessageSynchronizer() { // //Get database type strDataBaseType = objSetting.GetDataBaseType(); // //Get connection string strConnectionString = objSetting.GetConnectionString(strDataBaseType); // //Get Message Queue Type // strMQType = objSetting.GetMQType() strReportDataBaseType = objSetting.GetReportDataBaseType(); // //Get connection string strReportConnectionString = objSetting.GetReportConnectionString(strReportDataBaseType); // ERP // //Get ERP database type strERPDataBaseType = objSetting.GetDataBaseType_ERP(); // //Get ERP connection string strERPconnectionString = objSetting.GetConnectionString_ERP(strERPDataBaseType); try { strResourceDir = objSetting["ResourceDir"].ToString(); } catch (Exception) { } try { strLanguageMode = objSetting["LanguageMode"].ToString(); } catch (Exception) { } // 'T100 整合項目增加, 取得 Web.Config 設定項目, 2015/12/15 Add. // Try // '從Web.config取出目前的DatabaseType // strERPCreator = System.Configuration.ConfigurationSettings.AppSettings.Get("defCreator") // '2016-03-09, Joe, 取出預設ERP單位屬性編號 // strERPUnitNo = System.Configuration.ConfigurationSettings.AppSettings.Get("defERPUnitNoProperty") // '2016-03-02, Joe, 取出預設語系並轉換成ERP對應語系,後續T100多語系資料需用到 // strDefLanguage = System.Configuration.ConfigurationSettings.AppSettings.Get("LanguageMode") // Select Case strDefLanguage.ToUpper // Case "ZH-CHS" // strLanguage_T100 = "zh_CN" // Case "EN" // strLanguage_T100 = "en_US" // Case Else // strLanguage_T100 = "zh_TW" // End Select // Catch ex As Exception // '發生錯誤時丟回本身的Function Name及系統錯誤訊息 // End Try } // //Property-------------------------------------------------------------------------------------------------------------------------------- public string ConnectionString { get { return strConnectionString; } } public string DataBaseType { get { return strDataBaseType; } } public void StartSyncing(Collection colParameters = null) { var StopRunList = new List(); var objERPSetting = new List(); var objQueue = new List(); string Parameter01, Parameter02; WorkCode ReturnWorkCode; bool bSendMail = false; do { try { // Parameter01為參數一 // 作為Mail通知群組(GroupNo),放在最前面防止連線失敗無法寄送通知。 if (!(colParameters["Parameter01"] == null) & !string.IsNullOrEmpty(Strings.Trim(Conversions.ToString(colParameters["Parameter01"])))) { Parameter01 = colParameters["Parameter01"].ToString().Trim(); } else { throw new Exception(TranslateMsg("Mail GroupNo (Parameter 01) [%NOT SET%]!", strLanguageMode, strResourceDir)); } // Parameter02為參數二 // 重新拋轉上限(數值) if (!(colParameters["Parameter02"] == null) & !string.IsNullOrEmpty(Strings.Trim(Conversions.ToString(colParameters["Parameter02"])))) { if (Information.IsNumeric(colParameters["Parameter02"]) == false) { throw new Exception("(Parameter 02) [%is not%] [%Numeric%]!"); } Parameter02 = colParameters["Parameter02"].ToString().Trim(); } else { throw new Exception(TranslateMsg("Limit Qty (Parameter 02) [%NOT SET%]!", strLanguageMode, strResourceDir)); } // 取得ERP整合設定資訊 objERPSetting = GetERPSetting(); // 取得要拋送給ERP的資訊 objQueue = GetSendQueue(); if (objQueue == null) break; string StopData; var SendERPSetting = new CDO_TBLSYSERPSETTING(); bool exitTry1 = false; foreach (CDO_TBLSYSSENDTOEAIQUEUE objQ in objQueue) { InXML = ""; RequestKey = ""; // 找出目前要拋送的目的服務是否有在StopRunList中,如存在則不允許執行 StopData = StopRunList.Where(x => (x ?? "") == (objQ.SENDTO ?? "")).FirstOrDefault(); if (string.IsNullOrEmpty(StopData)) { // 取出要拋送的目的服務的ERP整合設定資訊 SendERPSetting = objERPSetting.Where(x => (x.ERP_NAME ?? "") == (objQ.SENDTO ?? "")).FirstOrDefault(); if (SendERPSetting == null) { // Throw New Exception("[%ERP_Name%]:" & objQ.SENDTO & "[%IS NOT FOUND%]!") // Exit Try continue; } // 組Req uest XML InXML = CombineRequestXML(SendERPSetting, objQ); // 將資訊拋給ERP using (var ws = new wsERP_EAI.IntegrationEntry()) { ws.Url = SendERPSetting.ERP_WSURL; OutXML = ws.invokeSrv(InXML); } // 處理執行結果 ReturnWorkCode = HandleSendResult(OutXML, objQ, SendERPSetting, Parameter01, Parameter02); // 依回傳的結果判定是否繼續執行 bool exitTry = false; switch (ReturnWorkCode) { case WorkCode.ContinueRun: { // 繼續執行 continue; } case WorkCode.StopSame: { // 將此次失敗的ERP名稱加到StopRunList StopRunList.Add(objQ.SENDTO); // 繼續執行 continue; } case WorkCode.StopAll: { // 全部停止執行 exitTry1 = exitTry = true; break; } } if (exitTry) { break; } } } if (exitTry1) { break; } } catch (Exception ex) { throw; } } while (false); } /// /// 取得ERP整合的設定資料 /// /// List(Of CDO_TBLSYSERPSETTING) private List GetERPSetting() { var DAO = new DAO_TBLSYSERPSETTING(); var Data = new List(); try { // 取出ERP整合資訊 Data = (List)DAO.Query(null, new QueryRelatedInfo() { ReturnType = ReturnMode.List }); } catch (Exception ex) { throw; } return Data; } /// /// 取得Queue資料 /// /// List(Of CDO_TBLSYSSENDTOEAIQUEUE) private List GetSendQueue() { var DAO = new DAO_TBLSYSSENDTOEAIQUEUE(); var Data = new List(); try { // 取出待拋轉資訊 Data = (List)DAO.Query(null, new QueryRelatedInfo() { ReturnType = ReturnMode.List }); } catch (Exception ex) { throw; } return Data; } /// /// 組出RequestXML /// /// private string CombineRequestXML(CDO_TBLSYSERPSETTING pERPSetting, CDO_TBLSYSSENDTOEAIQUEUE pSendContent) { string CombineRequestXMLRet = default(string); DataRow[] drERPSetting; string strFilter = ""; try { // pSendContent.enterprise_no = drERPSetting(0)("ERP_ENTID").ToString // pSendContent.site_no = drERPSetting(0)("ERP_ORG").ToString // 轉XML string RequestHead = ""; RequestHead += ""; string RequestDataKey = "" + pERPSetting.ERP_ENTID + "" + pERPSetting.ERP_ORG + ""; string RequestXML_Body = pSendContent.PAYLOAD; RequestKey = modAutoRunLibrary.GetRequestKey(RequestHead); string RequestHeader = "" + RequestHead + RequestDataKey + "" + RequestXML_Body + ""; // CDO to XML CombineRequestXMLRet = RequestHeader; } catch (Exception ex) { throw; } return CombineRequestXMLRet; } /// /// 同步結果處理 /// /// private WorkCode HandleSendResult(string pEAIResult, CDO_TBLSYSSENDTOEAIQUEUE pSendSrc, CDO_TBLSYSERPSETTING pEAISetting, string pJobParam01, string pJobParam02) { WorkCode HandleSendResultRet = default(WorkCode); //IDbConnection cnnTemp = null; //IDbCommand cmmTemp; string strSQL; //System.Data.OleDbDataAdapter daTemp; var dsTemp = new DataSet(); var objReturn = default(WorkCode); var objEAIResult = default(object); bool ProcessResult = false; string ProcessMessage = ""; try { // 物件初始化 switch (pSendSrc.SERVICENAME ?? "") { case "issue.wo.item.process": // MES發料 { objEAIResult = new SCI_Response_issue_wo_item_process(); break; } case "stockin.data.create": // 完工入庫 { objEAIResult = new SCI_Response_stockin_data_create(); break; } case "workorder.create": // DPM 拋報工單 { objEAIResult = new SCI_Response_workorder_create(); break; } } // 將中台回的結果轉成物件 try { (objEAIResult as SCI_Response_workorder_create).ParseXmlToObject(pEAIResult); if (Conversions.ToBoolean(Operators.ConditionalCompareObjectEqual((objEAIResult as SCI_Response_workorder_create).code, "0", false))) { ProcessResult = true; } else { ProcessMessage = Conversions.ToString((objEAIResult as SCI_Response_workorder_create).description); } } catch (Exception ex) { ProcessMessage = OutXML; } // 紀錄TransactionLog string argstrException = null; modAutoRunLibrary.addTransactionLog(InXML, OutXML, DateTime.Now.ToString("yyyyMMddHHmmssss"), "MES", "StartSyncing", Environment.MachineName, "AutoRun", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), Conversions.ToString(Interaction.IIf(ProcessResult == Conversions.ToBoolean("0"), "success", "fail")), ProcessMessage, pSendSrc.SERVICENAME, strException: argstrException); // 判斷中台回的結果 if (ProcessResult) { // 成功 HandleSendResultRet = WorkCode.ContinueRun; // 處理執行成功資訊及歷程 HandleSendSuccess(pEAIResult, pSendSrc); } else { // 失敗 // 處理執行失敗資訊及歷程 HandleSendFail(pEAIResult, ProcessMessage, pSendSrc, pJobParam02); // 寄送Mail string argFileName = "N/A"; string argEmailSubject = "AutuRunJob : StartSyncing Fail![" + pSendSrc.SERVICENAME + "]"; string argEmailBody = TranslateMsg("[%SENDID%]:" + pSendSrc.SENDID + " [%EXECUTE%] [%ISSUEMOMATERIAL%] [%FAIL%]! [%ERRORMESSAGE%]:", strLanguageMode, strResourceDir) + ProcessMessage; modAutoRunLibrary.SendMultiEmail(ref argFileName, ref argEmailSubject, argEmailBody, pJobParam01); } } catch (Exception ex) { throw; } finally { //CloseConnection(cnnTemp); } return objReturn; } /// /// 同步結果處理-成功 /// /// private void HandleSendSuccess(string pEAIResult, CDO_TBLSYSSENDTOEAIQUEUE pSendSrc) { string strSQL; var objQueueLog = new CDO_TBLSYSSENDTOEAIQUEUE_LOG(); var objEAIResult = new object(); var DAO = new DAO_TBLSYSSENDTOEAIQUEUE(); var DAO_Log = new DAO_TBLSYSSENDTOEAIQUEUE_LOG(); var cdoERPDocLog = new CDO_TBLSYSERPDOCUMENTLOG(); var daoERPDocLog = new DAO_TBLSYSERPDOCUMENTLOG(); try { // 執行成功後呼叫各服務各自處理邏輯 switch (pSendSrc.SERVICENAME ?? "") { case "issue.wo.item.process": // MES發料 { objEAIResult = new SCI_Response_issue_wo_item_process(); // 將中台回的結果轉成物件 try { (objEAIResult as SCI_Response_issue_wo_item_process).ParseXmlToObject(pEAIResult); } catch (Exception ex) { throw new Exception("[%XML FORMAT ERROR%]"); } // 解析Request XML var cdoInXML = new SCI_Request_issue_wo_item_process(); cdoInXML.ParseXmlToObject(InXML); object argdaoTransaction = DAO; AddERPDocumentLog(8, Conversions.ToString((objEAIResult as SCI_Response_issue_wo_item_process).return_no), cdoInXML.doc_no, pSendSrc, ref argdaoTransaction); DAO = (DAO_TBLSYSSENDTOEAIQUEUE)argdaoTransaction; break; } case "stockin.data.create": // 完工入庫 { objEAIResult = new SCI_Response_stockin_data_create(); // 將中台回的結果轉成物件 try { (objEAIResult as SCI_Response_stockin_data_create).ParseXmlToObject(pEAIResult); } catch (Exception ex) { throw new Exception("[%XML FORMAT ERROR%]"); } // 解析Request XML var cdoInXML = new SCI_Request_stockin_data_create(); cdoInXML.ParseXmlToObject(InXML); object argdaoTransaction1 = DAO; AddERPDocumentLog(4, Conversions.ToString((objEAIResult as SCI_Response_stockin_data_create).stock_in_no), cdoInXML.source_no, pSendSrc, ref argdaoTransaction1); DAO = (DAO_TBLSYSSENDTOEAIQUEUE)argdaoTransaction1; break; } case "workorder.create": // DPM報工單 { objEAIResult = new SCI_Response_workorder_create(); // 將中台回的結果轉成物件 try { (objEAIResult as SCI_Response_workorder_create).ParseXmlToObject(pEAIResult); } catch (Exception ex) { throw new Exception("[%XML FORMAT ERROR%]"); } // 解析Request XML var cdoInXML = new SCI_Request_workorder_create(); cdoInXML.ParseXmlToObject(InXML); break; } } // 將Queue資訊搬至Log objQueueLog.SENDID = pSendSrc.SENDID; objQueueLog.SENDTO = pSendSrc.SENDTO; objQueueLog.SERVICENAME = pSendSrc.SERVICENAME; objQueueLog.SERVICEVERSION = pSendSrc.SERVICEVERSION; objQueueLog.SENDCONTENT = pSendSrc.PAYLOAD; objQueueLog.SENDCOUNT = pSendSrc.SENDCOUNT; objQueueLog.RETURNINFO = Conversions.ToString((objEAIResult as SCI_Response_workorder_create).description); objQueueLog.RUNRESULT = "success"; objQueueLog.CREATOR = pSendSrc.CREATOR; objQueueLog.CREATEDATE = pSendSrc.CREATEDATE; // 2017-07-17, Joe, 將ERP入庫單號寫入Queue中,還原時才能與MES發料資訊做對應一起還原 objQueueLog.RELATIONERPNO = pSendSrc.RELATIONERPNO; objQueueLog.LOTSERIAL = pSendSrc.LOTSERIAL; DAO_Log.Add(objQueueLog, DAO); // 刪除已拋轉成功的Queue DAO.Delete(pSendSrc, DAO); } catch (Exception ex) { throw; } finally { } } /// /// 同步結果處理-失敗 /// /// private void HandleSendFail(string pEAIResult, string pEAIMessage, CDO_TBLSYSSENDTOEAIQUEUE pSendSrc, string pJobParam02) { string strSQL; var objQueueLog = new CDO_TBLSYSSENDTOEAIQUEUE_LOG(); var DAO = new DAO_TBLSYSSENDTOEAIQUEUE(); var DAO_Log = new DAO_TBLSYSSENDTOEAIQUEUE_LOG(); try { // 錯誤次數加1 pSendSrc.SENDCOUNT = pSendSrc.SENDCOUNT + 1; pSendSrc.EXCEPTION = pEAIResult; // 將此筆Queue回寫DB DAO.Update(pSendSrc, DAO); // 發送Mail // 判斷目前執行的同步次數是否已達到最大限制次數 if (string.IsNullOrEmpty(pJobParam02) == false && Convert.ToInt32(pJobParam02) != -1 && pSendSrc.SENDCOUNT > Convert.ToInt32(pJobParam02)) { // 將Queue資訊搬至Log objQueueLog.SENDID = pSendSrc.SENDID; objQueueLog.SENDTO = pSendSrc.SENDTO; objQueueLog.SERVICENAME = pSendSrc.SERVICENAME; objQueueLog.SERVICEVERSION = pSendSrc.SERVICEVERSION; objQueueLog.SENDCONTENT = pSendSrc.PAYLOAD; objQueueLog.SENDCOUNT = pSendSrc.SENDCOUNT; objQueueLog.RETURNINFO = pEAIMessage; objQueueLog.RUNRESULT = "fail"; objQueueLog.EXCEPTION = pSendSrc.EXCEPTION; objQueueLog.CREATOR = pSendSrc.CREATOR; objQueueLog.CREATEDATE = pSendSrc.CREATEDATE; // 2017-07-17, Joe, 將ERP入庫單號寫入Queue中,還原時才能與MES發料資訊做對應一起還原 objQueueLog.RELATIONERPNO = pSendSrc.RELATIONERPNO; DAO_Log.Add(objQueueLog, DAO); // 刪除已拋轉成功的Queue DAO.Delete(pSendSrc, DAO); } } catch (Exception ex) { throw; } finally { } } private object AddERPDocumentLog(int pDocType, string ERPNo, string MESNo, CDO_TBLSYSSENDTOEAIQUEUE pSendSrc, ref object daoTransaction) { var cdoERPDocLog = new CDO_TBLSYSERPDOCUMENTLOG(); var daoERPDocLog = new DAO_TBLSYSERPDOCUMENTLOG(); try { // 將資訊寫入ERP Document Log cdoERPDocLog.TRANSID = RequestKey; cdoERPDocLog.DOCUMENTTYPE = pDocType; // 單據類別 1:工單發料,2:工單退料,3:報工單,4:完工入庫,5:不良品入庫單,6:外包出貨單,7:外包回貨單,8:MES發料 cdoERPDocLog.MESNO = MESNo; cdoERPDocLog.ERPNO = ERPNo; cdoERPDocLog.CREATEDATE = pSendSrc.CREATEDATE; // 2017-07-17, Joe, 將ERP入庫單號寫入Queue中,還原時才能與MES發料資訊做對應一起還原 cdoERPDocLog.RELATIONERPNO = pSendSrc.RELATIONERPNO; cdoERPDocLog.SENDID = pSendSrc.SENDID; daoERPDocLog.Add(cdoERPDocLog, (iMESDBBase)daoTransaction); } catch (Exception ex) { throw; } return default(Object); } } }