This repo is archived. You can view files and clone it, but cannot push or open issues or pull requests.
SXS20240115/SRC/MESAgent/MESAutoRun/AutoRunLib/EAIMessageSynchronizer.cs

633 lines
26 KiB
C#
Raw Normal View History

2024-01-15 10:57:41 +08:00
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<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 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((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
{
}
}
/// <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);
}
}
}