This repo is archived. You can view files and clone it, but cannot push or open issues or pull requests.
SXS20240115/SRC/MESAgent/MESAutoRun_STD/AutoRunLib/EAIMessageSynchronizer.cs
2024-01-23 16:49:54 +08:00

658 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
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<string>();
var objERPSetting = new List<CDO_TBLSYSERPSETTING>();
var objQueue = new List<CDO_TBLSYSSENDTOEAIQUEUE>();
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 iMESCore.Base.Invoke.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);
}
/// <summary>
/// 取得ERP整合的設定資料
/// </summary>
/// <returns>List(Of CDO_TBLSYSERPSETTING)</returns>
private List<CDO_TBLSYSERPSETTING> GetERPSetting()
{
var DAO = new DAO_TBLSYSERPSETTING();
var Data = new List<CDO_TBLSYSERPSETTING>();
try
{
// 取出ERP整合資訊
Data = (List<CDO_TBLSYSERPSETTING>)DAO.Query(null, new QueryRelatedInfo() { ReturnType = ReturnMode.List });
}
catch (Exception ex)
{
throw;
}
return Data;
}
/// <summary>
/// 取得Queue資料
/// </summary>
/// <returns>List(Of CDO_TBLSYSSENDTOEAIQUEUE)</returns>
private List<CDO_TBLSYSSENDTOEAIQUEUE> GetSendQueue()
{
var DAO = new DAO_TBLSYSSENDTOEAIQUEUE();
var Data = new List<CDO_TBLSYSSENDTOEAIQUEUE>();
try
{
// 取出待拋轉資訊
Data = (List<CDO_TBLSYSSENDTOEAIQUEUE>)DAO.Query(null, new QueryRelatedInfo() { ReturnType = ReturnMode.List });
}
catch (Exception ex)
{
throw;
}
return Data;
}
/// <summary>
/// 組出RequestXML
/// </summary>
/// <returns></returns>
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 = "<host prod=\"" + pERPSetting.MESPRODUCTNAME + "\" ver=\"" + pERPSetting.MESPRODUCTVER + "\" ip=\"" + pERPSetting.MESIP + "\" id=\"" + pERPSetting.MESID + "\" acct=\"" + pERPSetting.ERP_USER + "\" lang=\"" + pERPSetting.ERP_LANG + "\" timestamp=\"" + Strings.Format(DateTime.Now, "yyyyMMddHHmmssfff") + "\"/>";
RequestHead += "<service prod=\"" + pERPSetting.CALLEDPRODUCTNAME + "\" name=\"" + pSendContent.SERVICENAME + "\" ip=\"" + pERPSetting.CALLEDIP + "\" id=\"" + pERPSetting.CALLEDID + "\"/>";
string RequestDataKey = "<datakey><key name=\"EntId\">" + pERPSetting.ERP_ENTID + "</key><key name=\"CompanyId\">" + pERPSetting.ERP_ORG + "</key></datakey>";
string RequestXML_Body = pSendContent.PAYLOAD;
RequestKey = modAutoRunLibrary.GetRequestKey(RequestHead);
string RequestHeader = "<request key=\"" + RequestKey + "\" type=\"sync\">" + RequestHead + RequestDataKey + "<payload>" + RequestXML_Body + "</payload></request>";
// CDO to XML
CombineRequestXMLRet = RequestHeader;
}
catch (Exception ex)
{
throw;
}
return CombineRequestXMLRet;
}
/// <summary>
/// 同步結果處理
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 同步結果處理-成功
/// </summary>
/// <returns></returns>
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(funGetParameterValue(objEAIResult, "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
{
}
}
/// <summary>
/// 同步結果處理-失敗
/// </summary>
/// <returns></returns>
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:外包回貨單8MES發料
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);
}
/// <summary>
/// 20230207,13871,部分函式存取Object obj的成員,但此obj可能有多種型別故使用此方式取的值
/// </summary>
/// <param name="obj"></param>
/// <param name="key"></param>
/// <returns></returns>
private static object funGetParameterValue(object obj, string key)
{
object result = "";
try
{
Type t = obj.GetType();
System.Reflection.PropertyInfo p = t.GetProperty(key);
if (p != null)
{
result = p.GetValue(obj);
}
}
catch (Exception)
{
throw;
}
return result;
}
}
}