test/MESEAI/EAItc/clsERP.cs

4172 lines
190 KiB
C#
Raw Permalink Normal View History

2026-07-31 15:42:16 +08:00
using iMESCIO.SCI.SMES.Request;
using iMESCIOC.Request.EAP;
using iMESCIOC.Request.WMS_Request;
using iMESCore.Base;
using iMESCore.DataBase;
using iMESCore.DataBase;
using iMESCore.Settings;
using iMESCore.Settings;
using kcOE;
using kcSYS;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.ApplicationServices;
using Microsoft.VisualBasic.CompilerServices;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using static iMESCore.Base.iMESComXML;
using static iMESCore.Base.iMESConst;
using static iMESCore.DataBase.iMESSql;
namespace tcEAI_C
{
public class clsERP
{
#region --- Combine (Exception, Message) ---
public static bool combineException(ref List<ArrayList> strException, string code = null, string sysmsg = null, string mesmsg = null, string stack = null)
{
bool result = false;
try
{
var al = new ArrayList();
al.Add(code);
al.Add(sysmsg);
al.Add(mesmsg);
al.Add(stack);
strException.Add(al);
result = true;
}
catch (Exception ex)
{
result = false;
}
return default(bool);
}
public static bool combineMessage(ref List<ArrayList> strMessage, string mcode = null, string mtype = null, string mmsg = null)
{
bool result = false;
try
{
var al = new ArrayList();
al.Add(mcode);
al.Add(mtype);
al.Add(mmsg);
strMessage.Add(al);
result = true;
}
catch (Exception ex)
{
result = false;
}
return default(bool);
}
public static bool combineFileMessage(ref List<ArrayList> aryFileMessage, string mmsg)
{
bool result = false;
try
{
var al = new ArrayList();
al.Add(mmsg);
aryFileMessage.Add(al);
result = true;
}
catch (Exception ex)
{
result = false;
}
return result;
}
#endregion
#region "add by 14166 for 加密接口"
/// <summary>
/// 检查用户
/// </summary>
/// <param name="UserNo"></param>
/// <param name="UserPassword"></param>
/// <param name="strMessage"></param>
/// <param name="strException"></param>
/// <returns></returns>
public static string funCheckUser(string UserNo, string UserPassword)
{
string funCheckUserRet = default(string);
funCheckUserRet = "fail";
AppSettings objSetting = new AppSettings();
DbDataReader drTemp = null;
IDbConnection cnnTemp = null;
string strSQL = "";
var objSYS = new kcSYS.clsSYSFunction();
string PasswordDecoding = "";//接口传入密码
string sysPassword = "";//MES系统绑定DS密码
try
{
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString); // Create connection
strSQL = " select PASSWORD from tblusruserbasis where userno='" + UserNo + "' ";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
sysPassword = drTemp["PASSWORD"].ToString();
}
else
{
throw new iMESException.MESException("0000-202001", "[%UserNo%] : " + "DS");
}
drTemp.Close();
sysPassword = objSYS.PasswordDecoding(sysPassword);
//SM2解密
// 生成密钥对
string privateKey = "Ja4UIUJz7XRNDhIiuWXwL78qd1Pc7SC0/Z9LzyF4SL8=";
//string publicKey = "BGe1BZDFN+NhCQtc2qlVk8nUlXrIwcyjT3mMt7Xx3BkDNBGBQjFPV0+h3/cGUYXo2TFI1SShS7hWl9zi6SxUHvg=";
//解密
PasswordDecoding = Decrypt(UserPassword, privateKey);
if (sysPassword != PasswordDecoding)
{
throw new iMESException.MESException("", "用户:" + UserNo + "权限校验失败");
}
//if (strException.Count > 0)
// goto exitfun;
funCheckUserRet = "success";
//exitfun:
;
}
catch (Exception ex)
{
throw;
//clsERP.combineException(ref strException, sysmsg: ex.Message, mesmsg: "[%CheckUserFail%]", stack: iMESCore.Base.iMESComXML.CInput(ex.StackTrace));
}
finally
{
CloseConnection(cnnTemp);
}
return funCheckUserRet;
}
/// <summary>
/// 生成 SM2 密钥对,密钥对使用 Base64 进行编码
/// </summary>
/// <param name="privateKey"></param>
/// <param name="publicKey"></param>
public static void GenerateSM2KeyPair(out string privateKey, out string publicKey)
{
// 获取 SM2 曲线参数
X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");
KeyGenerationParameters parameters = new ECKeyGenerationParameters(new ECDomainParameters(curve), new SecureRandom());
// 创建 SM2 密钥对生成器
ECKeyPairGenerator generator = new ECKeyPairGenerator();
generator.Init(parameters);
// 创建密钥对
var keyPair = generator.GenerateKeyPair();
// 私钥
ECPrivateKeyParameters privateKeyParameters = (ECPrivateKeyParameters)keyPair.Private;
privateKey = Base64.ToBase64String(privateKeyParameters.D.ToByteArrayUnsigned());
// 公钥
ECPublicKeyParameters publicKeyParameters = (ECPublicKeyParameters)keyPair.Public;
publicKey = Base64.ToBase64String(publicKeyParameters.Q.GetEncoded());
}
/// <summary>
/// SM2公钥加密
/// </summary>
/// <param name="strs"></param>
/// <param name="publicKey"></param>
/// <returns></returns>
public static string Encrypt(string strs, string publicKey)
{
//获取SM2曲线参数
X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");
ECPoint q = curve.Curve.DecodePoint(Convert.FromBase64String(publicKey));
ECDomainParameters domainParameters = new ECDomainParameters(curve);
ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters("EC", q, domainParameters);
//创建SM2加密器
SM2Engine engine = new SM2Engine();
engine.Init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
//把待加密的字符串转换成字节数组
byte[] bytes = Encoding.UTF8.GetBytes(strs);
//执行加密
byte[] result = engine.ProcessBlock(bytes, 0, bytes.Length);
//将加密结果转换成Base64字符串并返回
return Convert.ToBase64String(result);
}
/// <summary>
/// SM2私钥解密
/// </summary>
/// <param name="strs"></param>
/// <param name="privateKey"></param>
/// <returns></returns>
public static string Decrypt(string strs, string privateKey)
{
try
{
//获取SM2曲线参数
X9ECParameters curve = ECNamedCurveTable.GetByName("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(curve);
BigInteger bigInteger = new BigInteger(1, Convert.FromBase64String(privateKey));
ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(bigInteger, domainParameters);
//创建SM2解密器
SM2Engine engine = new SM2Engine();
engine.Init(false, privateKeyParameters);
//把待解密的Base64字符串转换成字节数组
byte[] bytes = Convert.FromBase64String(strs);
//执行解密
byte[] result = engine.ProcessBlock(bytes, 0, bytes.Length);
//将解密结果转换成字符串,并返回
return Encoding.UTF8.GetString(result);
}
catch (FormatException)
{
throw new ArgumentException("Base64格式无效", nameof(strs));
}
catch (Exception ex)
{
// 其他所有异常包装后重新抛出
throw new InvalidOperationException($"SM2解密失败: {ex.Message}", ex);
}
//try
//{
// // 获取SM2曲线参数
// var curve = ECNamedCurveTable.GetByName("sm2p256v1");
// var domainParameters = new ECDomainParameters(curve);
// var privateKeyBytes = Convert.FromBase64String(_privateKey);
// var bigInteger = new BigInteger(1, privateKeyBytes);
// var privateKeyParameters = new ECPrivateKeyParameters(bigInteger, domainParameters);
// // 创建SM2解密器
// using var engine = new SM2Engine();
// engine.Init(false, privateKeyParameters);
// // 解密
// var encryptedBytes = Convert.FromBase64String(encryptedText);
// var resultBytes = engine.ProcessBlock(encryptedBytes, 0, encryptedBytes.Length);
// return Encoding.UTF8.GetString(resultBytes);
//}
//catch (FormatException)
//{
// throw new ArgumentException("Base64格式无效", nameof(encryptedText));
//}
//catch (Exception ex)
//{
// // 记录日志
// LogError($"SM2解密失败: {ex.Message}");
// throw new CryptographicException("解密过程中发生错误", ex);
//}
}
#endregion
public static bool addTransactionLog_ErrorCode(string TransactionID, string ModuleID, string FunctionID, string ComputerName, string CurUserNo, string SendTime, string Result, string KeyValue, List<ArrayList> strMessage, List<ArrayList> strException, string InXml, string OutXml, string ExceptionFun, int KeepDays, int KeepXML, string ErrorCode = "0000-999999", string LogClass = null)
{
bool r = false;
var CollectionSQL = new Collection();
try
{
AppSettings objSetting = new AppSettings();
// 2017/12/06 OwenLiu, mantis:0042964 修正ERP交易紀錄刪除舊資料因時間不同步造成的問題
var datEventTime = DateTime.Now;
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
List<List<clsDbParameter>> parameters = new List<List<clsDbParameter>>();
List<clsDbParameter> pars1 = new List<clsDbParameter>();
List<clsDbParameter> pars2 = new List<clsDbParameter>();
parameters.Add(pars1);
// Transaction(ID)
string g = Guid.NewGuid().ToString();
// 2022/12/2,Ning,122356: 台基---erp交易记录无法查询
g = g.Replace(Constants.vbNullChar, "");
if (TransactionID == null)
pars1.Add(new clsDbParameter("TransactionID", DBNull.Value));
else
pars1.Add(new clsDbParameter("TransactionID", TransactionID));
if (ModuleID == null)
pars1.Add(new clsDbParameter("ModuleID", DBNull.Value));
else
pars1.Add(new clsDbParameter("ModuleID", ModuleID));
if (FunctionID == null)
pars1.Add(new clsDbParameter("FunctionID", DBNull.Value));
else
pars1.Add(new clsDbParameter("FunctionID", FunctionID));
if (ComputerName == null)
pars1.Add(new clsDbParameter("ComputerName", DBNull.Value));
else
pars1.Add(new clsDbParameter("ComputerName", ComputerName));
if (CurUserNo == null)
pars1.Add(new clsDbParameter("CurUserNo", DBNull.Value));
else
pars1.Add(new clsDbParameter("CurUserNo", CurUserNo));
if (SendTime == null || !Information.IsDate(SendTime))
pars1.Add(new clsDbParameter("SendTime", DBNull.Value));
else
pars1.Add(new clsDbParameter("SendTime", Convert.ToDateTime(SendTime)));
if (Result == null)
pars1.Add(new clsDbParameter("Result", DBNull.Value));
else
pars1.Add(new clsDbParameter("Result", Result));
if (KeyValue == null)
pars1.Add(new clsDbParameter("KeyValue", DBNull.Value));
else
pars1.Add(new clsDbParameter("KeyValue", KeyValue));
// 2017/12/06 OwenLiu, mantis:0042964 修正ERP交易紀錄刪除舊資料因時間不同步造成的問題
pars1.Add(new clsDbParameter("CreateDate", datEventTime));
if (LogClass == null)
pars1.Add(new clsDbParameter("LogClass", DBNull.Value));
else
pars1.Add(new clsDbParameter("LogClass", LogClass));
if (Result != null && Result.ToUpper() == "SUCCESS")
pars1.Add(new clsDbParameter("ErrorCode", DBNull.Value));
else
pars1.Add(new clsDbParameter("ErrorCode", ErrorCode));
if (Result != null && Result.ToUpper() == "SUCCESS")
pars1.Add(new clsDbParameter("ErrorType", DBNull.Value));
else if (ErrorCode == "0000-999999")
pars1.Add(new clsDbParameter("ErrorType", 2));
else
pars1.Add(new clsDbParameter("ErrorType", 1));
CollectionSQL.Add("insert into tblERPTransactionLog(id,transactionid,moduleid,functionid,computername,curuserno,sendtime,result,keyvalue,createdate,logclass,errorcode,errortype) " +
"values('" + g + "',:TransactionID, :ModuleID, :FunctionID, :ComputerName, :CurUserNo, :SendTime, :Result, :KeyValue, :CreateDate, :LogClass, :ErrorCode, :ErrorType)");
// ----- Transaction XML Log 組參數-----
if (KeepXML != 0)
{
parameters.Add(pars2);
if (strMessage.Count == 0)
{
pars2.Add(new clsDbParameter("Message", DBNull.Value));
}
else
{
// mcode, mtype, mmsg
string str = string.Empty;
foreach (ArrayList al in strMessage)
{
// 2018/05/10 OwenLiu, 調整TransactionLog針對 ArrayList處理邏輯以便與中台EAI共用
if (!string.IsNullOrEmpty(str))
str += Convert.ToString(ControlChars.Cr);
if (!string.IsNullOrEmpty(Convert.ToString(al[0])))
{
str = str + "mcode: " + al[0] + ";".ToString();
}
if (!string.IsNullOrEmpty(Convert.ToString(al[0])))
{
str = str + "mtype: " + al[1] + ";".ToString();
}
// str += "mmsg: " & al.Item(2)
if (!string.IsNullOrEmpty(Convert.ToString(al[0])))
{
str = str + "mmsg: " + al[2] + ";".ToString();
}
}
pars2.Add(new clsDbParameter("Message", str));
}
if (strException.Count == 0)
{
pars2.Add(new clsDbParameter("Exception", DBNull.Value));
}
else
{
// code, sysmsg, mesmsg, stack
string str = string.Empty;
foreach (ArrayList al in strException)
{
// 2018/05/10 OwenLiu, 調整TransactionLog針對 ArrayList處理邏輯以便與中台EAI共用
if (!string.IsNullOrEmpty(str))
str += Convert.ToString(ControlChars.Cr);
if (!string.IsNullOrEmpty(Convert.ToString(al[0])))
{
str = str + "code: " + al[0] + ";".ToString();
}
if (!string.IsNullOrEmpty(Convert.ToString(al[1])))
{
str = str + "sysmsg: " + al[1] + ";".ToString();
}
if (!string.IsNullOrEmpty(Convert.ToString(al[2])))
{
str = str + "mesmsg: " + al[2].ToString().Replace("[%", "").Replace("%]", "") + ";";
}
if (!string.IsNullOrEmpty(Convert.ToString(al[3])))
{
str = str + "stack: " + al[3].ToString();
}
}
pars2.Add(new clsDbParameter("Exception", str));
}
if (InXml == null)
pars2.Add(new clsDbParameter("InXml", DBNull.Value));
else
pars2.Add(new clsDbParameter("InXml", InXml));
if (OutXml == null)
pars2.Add(new clsDbParameter("OutXml", DBNull.Value));
else
pars2.Add(new clsDbParameter("OutXml", OutXml));
if (ExceptionFun == null)
pars2.Add(new clsDbParameter("ExceptionFun", DBNull.Value));
else
pars2.Add(new clsDbParameter("ExceptionFun", ExceptionFun));
// -----執行Transaction XML Log-----
CollectionSQL.Add("insert into tblERPTransactionXMLLog(id,messagexml,exceptionxml,inxml,outxml,exceptionfun) values('" + g +
"',:Message, :Exception, :InXml, :OutXml, :ExceptionFun)");
}
ExecuteSQLNoneQuery_UPD_Parameter(strDataBaseType, strConnectionString, CollectionSQL, parameters);
r = true;
}
catch (Exception ex)
{
r = false;
throw;
}
return r;
}
#region-----------add by 14166 for -----------
/// <summary>
/// (ref strMessage, ref strException, UserNo, UserName, UserLevel, Creator, CreateDate, Description, IssueState, ChangeDate, ResetPassword, UserType, UserDP, UserEmail);
/// </summary>
/// <param name="aryMessage"></param>
/// <param name="aryException"></param>
/// <param name="UserNo"></param>
/// <param name="UserName"></param>
/// <param name="UserLever"></param>
/// <param name="UserDP"></param>
/// <param name="UserEmail"></param>
/// <returns></returns>
public static bool funAddUser(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string UserNo = defString, string UserName = defString, string UserLever = defString, string Creator = defString, string CreateDate = defString, string Description = defString, string IssueState = defString, string ChangeDate = defString, string ResetPassword = defString, string UserType = defString, string UserDP = defString, string UserEmail = defString, string Password = defString)
{
bool result = false;
DataRow dr;
int i, j;
string strSQLAddField, strSQLAddValue;
Collection MTLCollection = new Collection();
Collection CollectionSQL = new Collection();
string strSQL = "";
IDbConnection cnnTemp = null;
DbDataReader drTemp;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
bool blnAdd = false; ;
string PasswordDecoding = "";
try
{
try
{
// //Create connection
cnnTemp = CreateConnection(strConnectionString);
//默认用户密码123
using (var objsys = new clsSYSFunction())
{
PasswordDecoding = objsys.PasswordEncoding(Password);
}
try
{
strSQL = " SELECT * FROM TBLUSRUSERBASIS WHERE USERNO='" + UserNo + "' ";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
throw new iMESException.MESException("0000-003000", "[%UserNo : " + UserNo + "人员已存在!%]");
}
else
{
blnAdd = true;
}
drTemp.Close();
// ----- Exception => Fail -----
if (aryException.Count > 0)
goto exitfun;
// Add
if (blnAdd)
{
strSQLAddField = " INSERT INTO TBLUSRUSERBASIS (USERNO,USERNAME,USERLEVEL,PASSWORD,DEPARTMENTNO,EMAILADDRESS,DESCRIPTION,USERTYPE,ISSUESTATE,RESETPASSWORD,CREATOR,CREATEDATE,CHANGEDATE";
strSQLAddValue = " Values ('" + UserNo + "','" + UserName + "','" + UserLever + "','" + PasswordDecoding + "','" + UserDP + "','" + UserEmail + "','" + Description + "','" + UserType + "','" + IssueState + "','" + ResetPassword + "','" + Creator + "',To_Date('" + Strings.Format(Conversions.ToDate(CreateDate), "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),To_Date('" + Strings.Format(Conversions.ToDate(ChangeDate), "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')";
// 當沒有額外的欄位時,直接給定strSQL
strSQL = strSQLAddField + ")" + strSQLAddValue + ")";
CollectionSQL.Add(strSQL);
}
else
{
// Edit
//strSQL = " UPDATE TBLUSRUSERBASIS set USERNAME='" + UserName + "',USERLEVEL='" + UserLever + "',DEPARTMENTNO='" + UserDP + "',EMAILADDRESS='" + UserEmail + "' WHERE USERNO='" + UserNo + "' ";
strSQL = " UPDATE TBLUSRUSERBASIS set USERNAME='" + UserName + "',USERLEVEL='" + UserLever + "' WHERE USERNO='" + UserNo + "' ";
CollectionSQL.Add(strSQL);
}
// 呼叫執行SQL指令
ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
result = true;
//clsERP.combineMessage(ref aryMessage, null, null, "[%AddUserSuccess%]");
}
catch (Exception ex)
{
// trans.Rollback()
clsERP.combineException(ref aryException, null, ex.Message, "[%AddUserFail%]", CInput(ex.StackTrace));
}
}
catch (Exception ex)
{
clsERP.combineException(ref aryException, null, ex.Message, "[%AddUserFail%]", CInput(ex.StackTrace));
}
exitfun:
;
}
catch (Exception ex)
{
clsERP.combineException(ref aryException, null, ex.Message, "[%AddUserFail%]", CInput(ex.StackTrace));
}
finally
{
CloseConnection(cnnTemp);
}
return result;
}
public static bool funDelUser(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string UserNo = defString, string UserName = defString, string UserLever = defString, string Creator = defString, string CreateDate = defString, string Description = defString, string IssueState = defString, string ChangeDate = defString, string ResetPassword = defString, string UserType = defString, string UserDP = defString, string UserEmail = defString, string Password = defString)
{
bool result = false;
Collection CollectionSQL = new Collection();
string strSQL = "";
IDbConnection cnnTemp = null;
DbDataReader drTemp;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
try
{
try
{
// //Create connection
cnnTemp = CreateConnection(strConnectionString);
////默认用户密码123
//using (var objsys = new clsSYSFunction())
//{
// PasswordDecoding = objsys.PasswordEncoding(Password);
//}
try
{
strSQL = " SELECT * FROM TBLUSRUSERBASIS WHERE USERNO='" + UserNo + "' ";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (!drTemp.Read())
{
throw new iMESException.MESException("0000-003000", "[%UserNo : " + UserNo + "人员不存在!%]");
}
drTemp.Close();
// ----- Exception => Fail -----
if (aryException.Count > 0)
goto exitfun;
strSQL = "DELETE FROM TBLUSRUSERBASIS WHERE USERNO='" + UserNo + "' ";
CollectionSQL.Add(strSQL);
// 呼叫執行SQL指令
ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
result = true;
}
catch (Exception ex)
{
// trans.Rollback()
clsERP.combineException(ref aryException, null, ex.Message, "[%DelUserFail%]", CInput(ex.StackTrace));
}
}
catch (Exception ex)
{
clsERP.combineException(ref aryException, null, ex.Message, "[%DelUserFail%]", CInput(ex.StackTrace));
}
exitfun:
;
}
catch (Exception ex)
{
clsERP.combineException(ref aryException, null, ex.Message, "[%DelUserFail%]", CInput(ex.StackTrace));
}
finally
{
CloseConnection(cnnTemp);
}
return result;
}
#endregion
#region
public static bool funAddMaterial_WIP(string SubInventoryTransferNo, string Description, string Creator, int Status, DateTime CreateDate = default(DateTime), DataTable dtMTL = null, List<ArrayList> aryMessage = null, List<ArrayList> aryException = null, List<ArrayList> aryAlert = null)
{
bool AddMaterial_WIPRet = default(bool);
bool r = false;
string strSQL = default(string);
IDbConnection cnnTemp = null;
DbDataReader drTemp;
AppSettings objSetting = new AppSettings();
var CollectionSQL = new Collection();
try
{
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString);
try
{
if (dtMTL.Rows.Count > 0)
{
//status0为发料1为退料
if (Status == 0)
{
foreach (DataRow row in dtMTL.Rows)
{
//若是同仓库编号、同物料编号、同物料批号,则数量进行叠加,若是其中一项不一样,则进行新增;
strSQL = " select * from TBLINVWIPINVENTORY_RAW where INVENTORYNO = '" + row["ToInventoryNo"] + "' and MATERIALNO = '" + row["MaterialNo"] + "' and MATERIALLOTNO = '" + row["MaterialLotNo"] + "' ";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
//叠加
strSQL = " update TBLINVWIPINVENTORY_RAW set QTY = QTY + " + Convert.ToInt32(row["TransferQty"]) + " where INVENTORYNO = '" + row["ToInventoryNo"] + "' and MATERIALNO = '" + row["MaterialNo"] + "' and MATERIALLOTNO = '" + row["MaterialLotNo"] + "' ";
CollectionSQL.Add(strSQL);
}
else
{
//TBLMTLMATERIALBASIS
strSQL = " select * from TBLMTLMATERIALBASIS where MATERIALNO = '" + row["MaterialNo"] + "' ";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
//新增
strSQL = " insert into TBLINVWIPINVENTORY_RAW(INVENTORYNO,MATERIALNO,MATERIALLOTNO,UNITNO,QTY,INPUTDATE,LOCATORNO,MATERIALTYPE) ";
strSQL += " values('" + row["ToInventoryNo"] + "','" + row["MaterialNo"] + "','" + row["MaterialLotNo"] + "','" + row["MaterialUnitNo"] + "'," + Convert.ToInt32(row["TransferQty"]) + ",To_Date('" + Strings.Format(CreateDate, "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),'N/A','" + drTemp["MATERIALTYPE"] + "') ";
CollectionSQL.Add(strSQL);
}
else
{
combineException(ref aryException, mesmsg: "[%物料基本资料无相关信息%]");
}
}
//记录调拨以及取消调拨记录
strSQL = " insert into TBLINVWIPINVENTORY_RAWLOG(subinventorytransferno,materialno,materiallotno,transferqty,materialunitno,frominventoryno,fromlocatorno,toinventoryno,tolocatorno,description,creator,createdate,Status) ";
strSQL += " values('" + SubInventoryTransferNo + "','" + row["MaterialNo"] + "','" + row["MaterialLotNo"] + "'," + Convert.ToInt32(row["TransferQty"]) + ",'" + row["MaterialUnitNo"] + "','" + row["FromInventoryNo"] + "','" + row["FromLocatorNo"] + "','" + row["ToInventoryNo"] + "','" + row["ToLocatorNo"] + "','" + Description + "','" + Creator + "',To_Date('" + Strings.Format(CreateDate, "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')," + Status + ") ";
CollectionSQL.Add(strSQL);
}
}
else if (Status == 1)
{
foreach (DataRow row in dtMTL.Rows)
{
//取消调拨:则直接扣减数量即可,若是扣减数量 > 库存数,则直接回复失败:库存不足;
strSQL = " select * from TBLINVWIPINVENTORY_RAW where INVENTORYNO = '" + row["FromInventoryNo"] + "' and MATERIALNO = '" + row["MaterialNo"] + "' and MATERIALLOTNO = '" + row["MaterialLotNo"] + "' ";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
if (Convert.ToInt32(row["TransferQty"]) > Convert.ToInt32(drTemp["QTY"]))
{
combineException(ref aryException, mesmsg: "[%库存不足%]");
}
else
{
//扣减
strSQL = " update TBLINVWIPINVENTORY_RAW set QTY = QTY - " + Convert.ToInt32(row["TransferQty"]) + " where INVENTORYNO = '" + row["FromInventoryNo"] + "' and MATERIALNO = '" + row["MaterialNo"] + "' and MATERIALLOTNO = '" + row["MaterialLotNo"] + "' ";
CollectionSQL.Add(strSQL);
//记录调拨以及取消调拨记录
strSQL = " insert into TBLINVWIPINVENTORY_RAWLOG(subinventorytransferno,materialno,materiallotno,transferqty,materialunitno,frominventoryno,fromlocatorno,toinventoryno,tolocatorno,description,creator,createdate,Status) ";
strSQL += " values('" + SubInventoryTransferNo + "','" + row["MaterialNo"] + "','" + row["MaterialLotNo"] + "'," + Convert.ToInt32(row["TransferQty"]) + ",'" + row["MaterialUnitNo"] + "','" + row["FromInventoryNo"] + "','" + row["FromLocatorNo"] + "','" + row["ToInventoryNo"] + "','" + row["ToLocatorNo"] + "','" + Description + "','" + Creator + "',To_Date('" + Strings.Format(CreateDate, "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')," + Status + ") ";
CollectionSQL.Add(strSQL);
}
}
}
}
}
else
{
combineException(ref aryException, mesmsg: "[%无调拨信息%]");
}
if (aryException.Count > 0)
goto exitfun;
ExecuteSQLNoneQuery_UPD(objSetting.GetDataBaseType(), objSetting.GetConnectionString(), CollectionSQL);
r = true;
combineMessage(ref aryMessage, mmsg: "[%AddMaterial_WIPSuccess%]");
}
catch (Exception ex)
{
combineException(ref aryException, sysmsg: ex.Message, mesmsg: "[%AddMaterial_WIPFail%]", stack: iMESCore.Base.iMESComXML.CInput(ex.StackTrace));
}
exitfun:
;
}
catch (Exception ex)
{
combineException(ref aryException, sysmsg: ex.Message, mesmsg: "[%AddMaterial_WIPFail%]", stack: iMESCore.Base.iMESComXML.CInput(ex.StackTrace));
}
finally
{
CloseConnection(cnnTemp);
AddMaterial_WIPRet = r;
}
return AddMaterial_WIPRet;
}
#endregion
#region MES箱号变更
#endregion
#region 湿
#endregion
#region MES退料
#endregion
#region "WMS发料回传前,先回传发料明细关联reel信息,datahub调用MES服务,推送发料明细数据至MES;"
public static bool funAddMaterial_WIP(string factory, DataTable dtReel)
{
bool funAddMaterial_WIP = default(bool);
bool r = false;
string strSQL = default(string);
IDbConnection cnnTemp = null;
DbDataReader drTemp;
AppSettings objSetting = new AppSettings();
var CollectionSQL = new Collection();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString);
DataRow[] dataRows = null;
try
{
if (dtReel.Rows.Count == 0)
{
throw new Exception("无明细数据!");
}
//先取出dtReel所有的MATERIALNO字段拼接成IN语句
string strMaterialNo = "";
for (int i = 0; i <= dtReel.Rows.Count - 1; i++)
{
if (strMaterialNo == "")
{
strMaterialNo = "'" + dtReel.Rows[i]["MCODE"] + "'";
}
else
{
strMaterialNo = strMaterialNo + ",'" + dtReel.Rows[i]["MCODE"] + "'";
}
}
strSQL = "SELECT MATERIALNO,MATERIALTYPE,UNITNO FROM TBLMTLMATERIALBASIS WHERE MATERIALNO IN (" + strMaterialNo + ") AND ISSUESTATE = 2";
DataTable dtMaterial = new DataTable("TBLMTLMATERIALBASIS");
ExecuteSQLQuery_Adapter(strSQL, dtMaterial, cnnTemp);
if (dtMaterial.Rows.Count == 0)
{
throw new Exception("MES无物料信息");
}
for (int i = 0; i <= dtReel.Rows.Count - 1; i++)
{
//物料单位
string strUnitNo = "";
dataRows = dtMaterial.Select("MATERIALNO = '" + dtReel.Rows[i]["MCODE"] + "'");
if (dataRows.Length > 0)
{
strUnitNo = dataRows[0]["UNITNO"].ToString();
}
else
{
throw new Exception($"{dtReel.Rows[i]["MCODE"]}找不到对应的物料信息!");
}
//数量
decimal QTY = 0;
if (dtReel.Rows[i]["QTY"].ToString() != "")
{
QTY = Convert.ToDecimal(dtReel.Rows[i]["QTY"]);
}
//物料类别 MATERIALTYPE 来着dtMaterial
string strMaterialType = "";
if (dataRows.Length > 0)
{
strMaterialType = dataRows[0]["MATERIALTYPE"].ToString();
}
//输入时间 INPUTDATE 来着于 dtReel的MTIME时间格式orcal
DateTime InputDate = DateTime.Now;
if (dtReel.Rows[i]["MTIME"].ToString() != "")
{
//InputDate = Convert.ToDateTime(dtReel.Rows[i]["MDATE"]);
InputDate = DateTime.ParseExact(dtReel.Rows[i]["MDATE"].ToString(), "yyyyMMdd", CultureInfo.InvariantCulture);
}
////制造日期 MANUFACTUREDATE 来着于 dtReel的VENDERDATE时间格式
DateTime ManufactureDate = ConvertYearWeekToMonday(dtReel.Rows[i]["VENDERDATE"].ToString());
//if (dtReel.Rows[i]["VENDERDATE"].ToString() != "")
//{
// ManufactureDate = Convert.ToDateTime(dtReel.Rows[i]["VENDERDATE"]);
//}
//超限日期 EXDATE
DateTime EXDATE = DateTime.Now;
if (dtReel.Rows[i]["EXDATE"].ToString() != "")
{
EXDATE = DateTime.ParseExact(dtReel.Rows[i]["EXDATE"].ToString(), "yyyyMMdd", CultureInfo.InvariantCulture);
}
string MONO = "";
strSQL = $"SELECT * from TBLCUSMATERIALSUMDETAIL where MATERIALINNO = '{dtReel.Rows[i]["RECEIPTNO"].ToString()}'";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
MONO = drTemp["MONO"].ToString();
}
drTemp.Close();
////插入 TBLINVWIPINVENTORY_RAW
//strSQL = @"INSERT INTO TBLINVWIPINVENTORY_RAW(INVENTORYNO, MATERIALNO, MATERIALLOTNO, UNITNO, QTY, MATERIALTYPE, INPUTDATE,MANUFACTUREDATE,RECEIPTNO,REELID,EXDATE,DATECODE,LOTCODE,VENDORCODE,VENDORITEMCODE,MANUFACTURER,SNSCALE) ";
//strSQL += " VALUES('" + dtReel.Rows[i]["STORAGECODE"].ToString() + "','" + dtReel.Rows[i]["MCODE"].ToString() + "','" + dtReel.Rows[i]["REELID"].ToString() + "', '" + strUnitNo + "'," + QTY + ",'" + strMaterialType + "','" + dtReel.Rows[i]["MTIME"].ToString() +
// "','"+ dtReel.Rows[i]["VENDERDATE"] + "','" + dtReel.Rows[i]["RECEIPTNO"].ToString() + "' ,'" + dtReel.Rows[i]["REELID"].ToString() + "',To_Date('" + Strings.Format(EXDATE, "yyyy/MM/dd HH:mm:ss") + $"','YYYY/MM/DD HH24:MI:SS'),'{dtReel.Rows[i]["DATECODE"].ToString()}','{dtReel.Rows[i]["VENDERLOTNO"].ToString()}','{dtReel.Rows[i]["VENDORCODE"].ToString()}','{dtReel.Rows[i]["VENDORITEMCODE"].ToString()}','{dtReel.Rows[i]["MANUFACTURER"].ToString()}','{dtReel.Rows[i]["SNSCALE"].ToString()}')";
//CollectionSQL.Add(strSQL);
////插入 TBLINVWIPINVENTORY_RAWLOG
//strSQL = @"INSERT INTO TBLINVWIPINVENTORY_RAWLOG(INVENTORYNO, MATERIALNO, MATERIALLOTNO, UNITNO, QTY, MATERIALTYPE, INPUTDATE,MANUFACTUREDATE,RECEIPTNO,REELID,EXDATE,EVENTTIME,DATECODE,LOTCODE,VENDORCODE,VENDORITEMCODE,MANUFACTURER,SNSCALE) ";
//strSQL += " VALUES('" + dtReel.Rows[i]["STORAGECODE"].ToString() + "','" + dtReel.Rows[i]["MCODE"].ToString() + "','" + dtReel.Rows[i]["REELID"].ToString() + "', '" + strUnitNo + "'," + QTY + ",'" + strMaterialType + "','"+ dtReel.Rows[i]["MTIME"].ToString() +
// "','"+ dtReel.Rows[i]["VENDERDATE"] + "','" + dtReel.Rows[i]["RECEIPTNO"].ToString() + "' ,'" + dtReel.Rows[i]["REELID"].ToString() + "',To_Date('" + Strings.Format(EXDATE, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),To_Date('" + Strings.Format(DateTime.Now, "yyyy/MM/dd HH:mm:ss") + $"','YYYY/MM/DD HH24:MI:SS'),'{dtReel.Rows[i]["DATECODE"].ToString()}','{dtReel.Rows[i]["VENDERLOTNO"].ToString()}','{dtReel.Rows[i]["VENDORCODE"].ToString()}','{dtReel.Rows[i]["VENDORITEMCODE"].ToString()}','{dtReel.Rows[i]["MANUFACTURER"].ToString()}','{dtReel.Rows[i]["SNSCALE"].ToString()}')";
//CollectionSQL.Add(strSQL);
//插入 TBLINVWIPINVENTORY_RAW
strSQL = @"INSERT INTO TBLINVWIPINVENTORY_RAW(INVENTORYNO, MATERIALNO, MATERIALLOTNO, UNITNO, QTY, MATERIALTYPE, INPUTDATE,MANUFACTUREDATE,RECEIPTNO,REELID,EXDATE,DATECODE,LOTCODE,VENDORCODE,VENDORITEMCODE,MANUFACTURER,SNSCALE,VENDERLOTNO,EXPIREDATE,MONO) ";
strSQL += " VALUES('" + dtReel.Rows[i]["STORAGECODE"].ToString() + "','" + dtReel.Rows[i]["MCODE"].ToString() + "','" + dtReel.Rows[i]["REELID"].ToString() + "', '" + strUnitNo + "'," + QTY + ",'" + strMaterialType + "',To_Date('" + Strings.Format(InputDate, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')" +
",To_Date('" + Strings.Format(ManufactureDate, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),'" + dtReel.Rows[i]["RECEIPTNO"].ToString() + "' ,'" + dtReel.Rows[i]["REELID"].ToString() +
"',To_Date('" + Strings.Format(EXDATE, "yyyy/MM/dd HH:mm:ss") + $"','YYYY/MM/DD HH24:MI:SS'),'{dtReel.Rows[i]["DATECODE"].ToString()}','{dtReel.Rows[i]["VENDERLOTNO"].ToString()}','{dtReel.Rows[i]["VENDORCODE"].ToString()}','{dtReel.Rows[i]["VENDORITEMCODE"].ToString()}','{dtReel.Rows[i]["MANUFACTURER"].ToString()}','{dtReel.Rows[i]["SNSCALE"].ToString()}','{dtReel.Rows[i]["VENDERLOTNO"].ToString()}',To_Date('" + Strings.Format(EXDATE, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),'"+MONO+"')";
CollectionSQL.Add(strSQL);
//插入 TBLINVWIPINVENTORY_RAWLOG
strSQL = @"INSERT INTO TBLINVWIPINVENTORY_RAWLOG(INVENTORYNO, MATERIALNO, MATERIALLOTNO, UNITNO, QTY, MATERIALTYPE, INPUTDATE,MANUFACTUREDATE,RECEIPTNO,REELID,EXDATE,EVENTTIME,DATECODE,LOTCODE,VENDORCODE,VENDORITEMCODE,MANUFACTURER,SNSCALE,VENDERLOTNO,EXPIREDATE,MONO) ";
strSQL += " VALUES('" + dtReel.Rows[i]["STORAGECODE"].ToString() + "','" + dtReel.Rows[i]["MCODE"].ToString() + "','" + dtReel.Rows[i]["REELID"].ToString() + "', '" + strUnitNo + "'," + QTY + ",'" + strMaterialType + "',To_Date('" + Strings.Format(InputDate, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')" +
",To_Date('" + Strings.Format(ManufactureDate, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),'" + dtReel.Rows[i]["RECEIPTNO"].ToString() + "' ,'" + dtReel.Rows[i]["REELID"].ToString() +
"',To_Date('" + Strings.Format(EXDATE, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),To_Date('" + Strings.Format(DateTime.Now, "yyyy/MM/dd HH:mm:ss") + $"','YYYY/MM/DD HH24:MI:SS'),'{dtReel.Rows[i]["DATECODE"].ToString()}','{dtReel.Rows[i]["VENDERLOTNO"].ToString()}','{dtReel.Rows[i]["VENDORCODE"].ToString()}','{dtReel.Rows[i]["VENDORITEMCODE"].ToString()}','{dtReel.Rows[i]["MANUFACTURER"].ToString()}','{dtReel.Rows[i]["SNSCALE"].ToString()}','{dtReel.Rows[i]["VENDERLOTNO"].ToString()}',To_Date('" + Strings.Format(EXDATE, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),'"+MONO+"')";
CollectionSQL.Add(strSQL);
}
if (CollectionSQL.Count > 0)
{
ExecuteSQLNoneQuery_UPD(objSetting.GetDataBaseType(), objSetting.GetConnectionString(), CollectionSQL);
}
exitfun:
;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
CloseConnection(cnnTemp);
}
return funAddMaterial_WIP;
}
public static DateTime ConvertYearWeekToMonday(string yearWeek)
{
if (string.IsNullOrEmpty(yearWeek) || yearWeek.Length != 4)
throw new ArgumentException("输入格式必须为4位数字前2位为年份后2位为周数");
int year = int.Parse(yearWeek.Substring(0, 2)) + 2000; // 26 -> 2026
int week = int.Parse(yearWeek.Substring(2, 2)); // 21 -> 21
return GetMondayOfWeek(year, week);
}
/// <summary>
/// 获取指定年份第几周的周一日期
/// </summary>
public static DateTime GetMondayOfWeek(int year, int week)
{
// 1. 计算该年1月1日
DateTime jan1 = new DateTime(year, 1, 1);
// 2. 计算1月1日所在周的周一
int daysOffset = ((int)jan1.DayOfWeek + 6) % 7; // 周一=0, 周日=6
DateTime firstMonday = jan1.AddDays(-daysOffset);
// 3. 计算目标周周一第1周从第一个周一开始
DateTime targetMonday = firstMonday.AddDays((week - 1) * 7);
return targetMonday;
}
#endregion
#region "SPC 接收数据"
//计量
public static bool funGetJLSPCData(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string SPCSerial_QMS, string MaterialNo, string MTLVendor, string Employee, string LotNo, string OPNo, string QCItemNo, string DC, string PartNo, List<decimal> listTestValue)
{
bool funGetJLSPCData = default(bool);
//bool r = false;
//string strSQL = default(string);
//IDbConnection cnnTemp = null;
//DbDataReader drTemp;
AppSettings objSetting = new AppSettings();
//string strDataBaseType = objSetting.GetDataBaseType();
//string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
//cnnTemp = CreateConnection(strConnectionString);
DataSet dsData = new DataSet();
DataRow addrow;
DataRow addrow2;
string strReturn = "";
int intSerial;
try
{
if (dsData.Tables.Contains("SPCData"))
{
dsData.Tables.Remove("SPCData");
}
dsData.Tables.Add("SPCData");
dsData.Tables["SPCData"].Columns.Add("Execute", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("Result", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("LotNo", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("QCItemNo", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("Employee", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("OP", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("OpNo", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("ComponentNo", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("LotSerial", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("intResult", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("SPCSerial_QMS", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("Material", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("MTLVendor", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("DC", System.Type.GetType("System.String"));
dsData.Tables["SPCData"].Columns.Add("PartNo", System.Type.GetType("System.String"));
if (dsData.Tables.Contains("TestValue"))
{
dsData.Tables.Clear();
}
else
{
dsData.Tables.Add("TestValue");
dsData.Tables["TestValue"].Columns.Add("LotNo", System.Type.GetType("System.String"));
dsData.Tables["TestValue"].Columns.Add("QCItemNo", System.Type.GetType("System.String"));
dsData.Tables["TestValue"].Columns.Add("SerialNo", System.Type.GetType("System.Int32"));
dsData.Tables["TestValue"].Columns.Add("TestValue", System.Type.GetType("System.Double"));
dsData.Tables["TestValue"].Columns.Add("MEMO", System.Type.GetType("System.String"));
dsData.Tables["TestValue"].Columns.Add("ComponentNo", System.Type.GetType("System.String"));
dsData.Tables["TestValue"].Columns.Add("LotSerial", System.Type.GetType("System.String"));
}
addrow = dsData.Tables["SPCData"].NewRow();
addrow["Execute"] = "True";
addrow["LotNo"] = LotNo;
addrow["QCItemNo"] = QCItemNo;
addrow["Employee"] = Employee;
addrow["OP"] = OPNo;
addrow["OpNo"] = OPNo;
addrow["LotSerial"] = 0;
//addrow["PartNo"] = PartNo;
addrow["SPCSerial_QMS"] = SPCSerial_QMS;
addrow["Material"] = MaterialNo;
addrow["MTLVendor"] = MTLVendor;
addrow["DC"] = DC;
addrow["PartNo"] = PartNo;
dsData.Tables["SPCData"].Rows.Add(addrow);
intSerial = 0;
foreach (decimal TestValue in listTestValue)
{
intSerial += 1;
addrow2 = dsData.Tables["TestValue"].NewRow();
addrow2["LotNo"] = LotNo;
addrow2["QCItemNo"] = QCItemNo;
addrow2["SerialNo"] = intSerial;
addrow2["TestValue"] = TestValue;
addrow2["LotSerial"] = 0;
addrow2["ComponentNo"] = "";
dsData.Tables["TestValue"].Rows.Add(addrow2);
}
string LotSerialTmp = string.Empty;
string LogGroupSerialTmp = string.Empty;
string LotStampTmp = string.Empty;
string ProductNoTmp = string.Empty;
string CustomerNoTmp = "N/A";
var drDataTmp = dsData.Tables["SPCData"].Rows[0];
var dvValue = default(DataView);
dvValue = dsData.Tables["TestValue"].DefaultView;
bool blnChkOnly = false;
bool blnAttachChart = true;
//tcSPC_IC.clsSPC objtc_SPC = new tcSPC_IC.clsSPC();
//objtc_SPC.funAutoBRSPCContorl_Var(ref LotSerialTmp, ref LogGroupSerialTmp, ref LotStampTmp, ref ProductNoTmp, ref CustomerNoTmp, ref drDataTmp, dvValue, blnChkOnly: blnChkOnly, blnAttachChart: blnAttachChart);
strReturn = funAutoBRSPCContorl_Var_M(ref LotSerialTmp, ref LogGroupSerialTmp, ref LotStampTmp, ref ProductNoTmp, ref CustomerNoTmp, ref drDataTmp, dvValue, blnChkOnly: blnChkOnly, blnAttachChart: blnAttachChart);
if (!strReturn.ToLower().Contains("success"))
{
throw new Exception(strReturn);
}
exitfun:
;
}
catch (Exception ex)
{
// 一行调用,拿到完整异常字符串
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
dsData?.Dispose();
//CloseConnection(cnnTemp);
}
return funGetJLSPCData;
}
//计数 计数不需要开立异常单或者任何法则检查,只需要做数据收集(多计数品管项目)
public static bool funGetJSSPCData(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string SPCSerial_QMS, string MaterialNo, string MTLVendor, string Employee, string LotNo, string ProDuct, string EquipMent, string DC, List<QCItemDetail> listQCItemDetail)
{
bool funGetJSSPCData = default(bool);
//bool r = false;
//string strSQL = default(string);
IDbConnection cnnTemp = null;
//DbDataReader drTemp;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString);
string SpcSerial = string.Empty;
Collection CollectionSQL = new Collection();
Collection CollectionSQL_Rows = new Collection();
DateTime nowTime = DateTime.Now;
var oSQLContent = new Dictionary<uint, iMESCore.DataBase._SQLContent>();
uint intSQLIndex = 1U;
kcSPC.clsSPC objSPC = new kcSPC.clsSPC();
try
{
foreach (var item in listQCItemDetail)
{
//这里的回写序号,防止多人操作时序号被占用,导致数据录不进,且序号不要求连续
SpcSerial = objSPC.InitSPCSerial(ref cnnTemp);
if (string.IsNullOrEmpty(SpcSerial))
{
throw new Exception("[%SpcSerial生成失败%]");
}
//参考兆驰
//计量计数项目基础资料
funCreateSPCATTBASIS(ref aryMessage, ref aryException, ref CollectionSQL,
SpcSerial, item.QCITEMNO, LotNo, item.SAMPLEQTY.ToString(), item.GOODQTY.ToString(), item.DefectQty.ToString(),
"0", item.RESULT, SPCSerial_QMS, MaterialNo, MTLVendor,
Employee, ProDuct, EquipMent, DC, nowTime.ToString("yyyy/MM/dd H:mm:ss"));
//TBLSPCATTDETAILLOG 计数线上检验明细资料历史纪录
//不良原因填QMS顾问固定的
funCreateSPCATTDETAIL(ref aryMessage, ref aryException, ref CollectionSQL,
SpcSerial, item.QCITEMNO, "QMS", item.DefectQty.ToString(), nowTime.ToString("yyyy/MM/dd H:mm:ss"));
//TBLSPCATTDETAILLOGSECTION 计数线上检验区域明细资料历史纪录档
//funCreateSPCATTSECTION(ref aryMessage, ref aryException, ref CollectionSQL,
// SpcSerial,"", "QMS","2", item.DefectQty.ToString());
}
//执行数据库
if (CollectionSQL.Count > 0)
{
for (int k = 1, loopTo10 = CollectionSQL.Count; k <= loopTo10; k++)
CollectionSQL_Rows.Add(-1);
funAddSQLContent(oSQLContent, ref intSQLIndex, CollectionSQL, CollectionSQL_Rows);
ExecuteSQLNoneQuery_ArrayBinding(strDataBaseType, strConnectionString, oSQLContent);
}
exitfun:
;
}
catch (Exception ex)
{
// 一行调用,拿到完整异常字符串
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
if (objSPC != null)
{
objSPC.Dispose();
}
CloseConnection(cnnTemp);
}
return funGetJSSPCData;
}
// 2020/11/25 Grace 增加傳入前端畫面輸入的要因, 若有傳, 直接使用
public static string funAutoBRSPCContorl_Var_M(ref string LotSerial, ref string LogGroupSerial, ref string LotStamp, ref string ProductNo, ref string CustomerNo,
ref DataRow drData, DataView dvValue = null,
string MClassNo = defString, bool blnChkOnly = true, bool blnAttachChart = false,
Collection CollectionSQL = null,
DataTable dtQCItemFactorAll = null, string UserNo = defString, string ShiftNo = defString, bool BrControl = false, bool EAPControl = false, bool blnReleaseLog = true, bool blnHoldLot = true)
{
string funAutoBRSPCContorl_VarRet = default(string);
// 此 Function 將自動判別檢測數據_計量
// 傳入值: drData (一次傳入一組檢驗資料,內有LotNo,OpNo,QCItemNo,PratNo,EmployeeTestValue 等
// 傳回值funAutoBRSPCContorl_Var: success(成功), QCItemNo(找不到品管項目編號), LotNo(找不到批號)...
// 傳回值: drData(檢測結果)
IDbConnection cnnTemp = null;
// 'Dim cmmTemp As OleDb.OleDbCommand
DbDataReader drTemp = null;
string strSQL;
var kcQC = new kcQC.clsQCBasis();
var kcWIP = new kcWIP.clsLot();
var kcSPC = new kcSPC.clsSPC();
var udSPC = new udSPC.clsSPC();
var udWIP = new udWIP.clsWIP();
// Table
DataSet dsTemp;
var dtQCItemBasis = default(DataTable);
var dtQCItemFactor = default(DataTable);
DataTable dtLotData;
var dtWIPFactor = default(DataTable);
DataTable dtQCItem; // 主要是儲存Check後的結果
DataRow drAdd;
DataRow[] drSel;
// 傳入的資料
var LotNo = default(string);
var OpNo = default(string);
var QCItemNo = default(string);
var QCItemName = default(string);
var Employee = default(string);
int i, j;
var ERFAction = default(string);
var ERFMsg = default(string);
var strSPCSerial = new string[2];
int intResult;
int intERFSource;
string LinkName;
// Dim LotSerial As String
// Dim LogGroupSerial As String
string ExecuteSPCSerial;
string PopulationQty = "";
// Dim ProductNo As String
// Dim CustomerNo As String = "N/A" '開異常單時 customerNo不能 Null
// Dim LotStamp As String
bool MailNotice = false;
string[] aryAdditionalSQL;
string[] aryUpdateSQLReplace; // Added by Neil 2008/05/19
bool blnCheckOK = true; // Added by Neil 2008/05/19 作為各項檢查的指標任何一項檢查不過則為False
var strCheckNotOKMessage = default(string); // Added by Neil 2008/05/19
DataSet dsChartData = null; // Added by Neil 2008/05/20 存放管制圖資料
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
tcSPC_IC.clsSPC objtc_SPC = new tcSPC_IC.clsSPC();
try
{
funAutoBRSPCContorl_VarRet = "error"; // Initial
// ===== 整理傳入的資料 =========
if (drData.Table.Columns.Contains("LotNo"))
{
LotNo = drData["LotNo"] + "".ToString();
}
if (drData.Table.Columns.Contains("QCItemNo"))
{
QCItemNo = (drData["QCItemNo"] + "").ToString().ToUpper(); // 請注意一定要轉大寫
}
if (drData.Table.Columns.Contains("OpNo"))
{
OpNo = drData["OpNo"] + "".ToString();
}
if (drData.Table.Columns.Contains("Employee"))
{
Employee = drData["Employee"] + "".ToString();
}
DataTable dtTestValue;
if (dvValue != null)
{
dtTestValue = dvValue.Table.Clone();
var loopTo = dvValue.Count - 1;
for (i = 0; i <= loopTo; i++)
dtTestValue.ImportRow(dvValue[i].Row);
}
else
{
dtTestValue = new DataTable("TestValue");
dtTestValue.Columns.Add("QCItemNo", Type.GetType("System.String"));
dtTestValue.Columns.Add("SerialNo", Type.GetType("System.Int32"));
dtTestValue.Columns.Add("TestValue", Type.GetType("System.Double"));
dtTestValue.Columns.Add("MEMO", Type.GetType("System.String"));
dtTestValue.Columns.Add("ComponentNo", Type.GetType("System.String"));
for (j = 0; j <= 19; j++)
{
if (drData.Table.Columns.Contains("S" + Strings.Format(j + 1, "00")) && !(drData["S" + Strings.Format(j + 1, "00")] is DBNull) && !string.IsNullOrEmpty(drData["S" + Strings.Format(j + 1, "00")].ToString()))
{
drAdd = dtTestValue.NewRow();
drAdd["QCItemNo"] = QCItemNo;
drAdd["SerialNo"] = j + 1;
drAdd["TestValue"] = drData["S" + Strings.Format(j + 1, "00")];
dtTestValue.Rows.Add(drAdd);
}
else
{
break;
}
}
}
if (dtTestValue.Rows.Count == 0)
{
strCheckNotOKMessage = "No Data";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/19
}
// ===== 檢查資料是否正確 =========
// 1.取出品管項目
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtQCItemBasis = kcQC.ShowQCItemForVariables(QCItemNo, IssueState: 2).Tables[0];
if (dtQCItemBasis == null || dtQCItemBasis.Rows.Count == 0)
{
strCheckNotOKMessage = "QCItemNo Error";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/19
}
}
// 2 取出Lot資料
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtLotData = kcWIP.ShowLotBasisJoinState(LotNo).Tables[0];
if (dtLotData == null || dtLotData.Rows.Count == 0)
{
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItemBasis.Rows[0]["LotIsValid"], 1, false))) // 必須檢查批號有效,但找不到批號資料
{
strCheckNotOKMessage = "LotData Error";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/19
}
}
else
{
PopulationQty = dtLotData.Rows[0]["CurQty"].ToString();
LotSerial = dtLotData.Rows[0]["LotSerial"] + "".ToString();
LogGroupSerial = dtLotData.Rows[0]["LogGroupSerial"] + "".ToString();
LotStamp = dtLotData.Rows[0]["LotStamp"] + "".ToString();
ProductNo = dtLotData.Rows[0]["ProductNo"] + "".ToString();
CustomerNo = dtLotData.Rows[0]["CustomerNo"] + "".ToString();
OpNo = dtLotData.Rows[0]["OpNo"] + "".ToString();
}
}
// ===== 整理要因資料 =========
// 3.1 取出 QCItemFactor
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
if (!(dtQCItemFactorAll == null))
{
dtQCItemFactor = dtQCItemFactorAll;
}
else
{
dtQCItemFactor = kcQC.ShowQCItemFactor(QCItemNo).Tables[0];
}
dtQCItemFactor = kcQC.ShowQCItemFactor(QCItemNo).Tables[0];
if (dtQCItemFactor == null || dtQCItemFactor.Rows.Count == 0)
{
strCheckNotOKMessage = "QCItemFactor Error";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/19
}
}
// 3.2 取得檢驗批的要因資料
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtWIPFactor = udSPC.LoadLotFactorValue(LotNo).Tables[0];
foreach (DataColumn dcFactor in drData.Table.Columns)
{
if (dcFactor.ColumnName.ToUpper() == "OPNO")
{
drSel = dtWIPFactor.Select("ParameterNo = 'OP'");
//0144256: [607]SC107匯入報錯 19120
if (drSel != null && drSel.Length > 0)
{
drSel[0]["Value"] = drData[dcFactor];
}
}
drSel = dtWIPFactor.Select("ParameterNo = '" + dcFactor.ColumnName + "'");
if (drSel.Length > 0)
{
drSel[0]["Value"] = drData[dcFactor];
}
}
}
// 3.3.將取得的要因值填入品管項目要因,取不到值的則填入N/A
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtQCItemFactor.Columns.Add("FactorValue", Type.GetType("System.String"));
var loopTo1 = dtQCItemFactor.Rows.Count - 1;
for (i = 0; i <= loopTo1; i++)
{
drSel = dtWIPFactor.Select("ParameterNo = '" + dtQCItemFactor.Rows[i]["FactorNo"] + "'".ToString());
if (drSel.Length > 0)
{
dtQCItemFactor.Rows[i]["FactorValue"] = drSel[0]["Value"];
}
else if (drData.Table.Columns.Contains(Convert.ToString(dtQCItemFactor.Rows[i]["FactorNo"])) && !(drData[dtQCItemFactor.Rows[i]["FactorNo"].ToString()] is DBNull) && Convert.ToBoolean(Operators.ConditionalCompareObjectNotEqual(drData[dtQCItemFactor.Rows[i]["FactorNo"].ToString()], "", false)))
{
dtQCItemFactor.Rows[i]["FactorValue"] = drData[dtQCItemFactor.Rows[i]["FactorNo"].ToString()]; // 從傳入的drData 中取得要因
}
else
{
dtQCItemFactor.Rows[i]["FactorValue"] = "N/A";
}
}
//0190824: 【澳洋】SPC接口 Edison 251023 補上SC101取得自定義要因值的做法
var dtTempSPCFactorData = new DataTable();
var dtValueList = new DataTable("ConditionValueList");
dtValueList.Columns.Add("InspLotNo", typeof(string));
var drValueList = dtValueList.NewRow();
drValueList["InspLotNo"] = LotNo;
dtValueList.Rows.Add(drValueList);
foreach (DataRow drw in dtQCItemFactor.Rows)
{
dtValueList.Columns.Add(Convert.ToString(drw["FactorNo"]), typeof(string));
dtValueList.Rows[0][drw["FactorNo"].ToString()] = drw["FactorValue"].ToString();
}
using (var objSys = new kcSYS.clsSYSMesParameter())
{
// 以SQLCMDMap方式取要因值
IDbConnection argcnnTemp = null;
objSys.LoadMesParameterValueBySQLCMD(ref dtValueList, cnnTemp: argcnnTemp);
}
if (dtValueList.Rows.Count > 0)
{
foreach (DataRow drw in dtQCItemFactor.Rows)
{
// 填入要因預設值
drw["FactorValue"] = dtValueList.Rows[0][drw["FactorNo"].ToString()].ToString().Trim();
if (dtQCItemFactorAll == null)
continue;
var drSel2 = dtQCItemFactorAll.Select("ParameterNo = '" + drw["FactorNo"].ToString() + "'");
// 填入要因預設值
if (drSel2.Length > 0)
{
foreach (DataRow dr in drSel2)
{
dr["FactorValue"] = dtValueList.Rows[0][drw["FactorNo"].ToString()].ToString().Trim();
}
}
}
}
// 取得暫存要因資料
strSQL = " Select * From tblWIPTemp_SPCFactorData Where LotNo = '" + LotNo + "' And OPNO = '" + OpNo + "' And LotSerial = '" + LotSerial + "'";
dtTempSPCFactorData = new DataTable("WIPTemp_SPCFactorData");
using (IDbConnection cnnQ = CreateConnection(strConnectionString))
{
ExecuteSQLQuery_Adapter(SQLCommandTuning(strDataBaseType, ref strSQL), dtTempSPCFactorData, connection: cnnQ);
if (dtTempSPCFactorData.Rows.Count > 0)
{
foreach (DataRow drw in dtQCItemFactor.Rows)
{
var drtTempSPCFactorData = dtTempSPCFactorData.Select(
"FactorNo = '" + drw["FactorNo"].ToString() +
"' And QCItemNo ='" + drw["QCItemNo"].ToString() + "'");
// 填入要因預設值
if (drtTempSPCFactorData.Length > 0)
{
drw["FactorValue"] = drtTempSPCFactorData[0]["FactorValue"];
if (dtQCItemFactorAll == null)
continue;
var drQCItemFactorAll = dtQCItemFactorAll.Select(
"ParameterNo = '" + drw["FactorNo"].ToString() +
"' And QCItemNo ='" + drw["QCItemNo"].ToString() + "'");
// 填入要因預設值
if (drQCItemFactorAll.Length > 0)
{
foreach (DataRow dr in drQCItemFactorAll)
{
dr["FactorValue"] = drtTempSPCFactorData[0]["FactorValue"];
}
}
}
}
}
}
}
// ===== 檢查此筆檢測資料是否已經存過 =========
var LatestLotsMappingCreateDateTmp = defDateTime;
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
if (blnChkOnly == true)
{
if (kcSPC.ShowVarFactorLog(ref LatestLotsMappingCreateDateTmp, QCItemNo, LotNo).Tables["SPCVarFactorLog"].Rows.Count > 0)
{
strCheckNotOKMessage = "Already Exist";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/19
}
}
}
// ===== Check 規格與管制法則 =========
var FactorSerial = default(string);
string strChkTemp;
var dtViolation = new DataTable("Violation"); // 執行 funChkQCChartValue 後回傳結果
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtViolation.Columns.Add("QCItemNo", Type.GetType("System.String"));
dtViolation.Columns.Add("SPCSerial", Type.GetType("System.String"));
dtViolation.Columns.Add("ComponentNo", Type.GetType("System.String"));
dtViolation.Columns.Add("SPCID", Type.GetType("System.String"));
dtViolation.Columns.Add("SerialNo", Type.GetType("System.String")); // Raw ID , 非Raw=-1
dtViolation.Columns.Add("ViolationID", Type.GetType("System.String")); // 違反類型WE001, WE002, ..,WE008
if (blnAttachChart == true) // 若blnAttachChart = True 則建立dsXlsChartData基本架構待經過funChkQCChartValue後取得資料後續畫管制圖用
{
dsChartData = new DataSet();
DataRow tmprow;
dsChartData.Tables.Add("ChartInfo");
dsChartData.Tables["ChartInfo"].Columns.Add("SpecLineType");
dsChartData.Tables["ChartInfo"].Columns.Add("SampleSize");
dsChartData.Tables["ChartInfo"].Columns.Add("TUCL");
dsChartData.Tables["ChartInfo"].Columns.Add("TLCL");
dsChartData.Tables["ChartInfo"].Columns.Add("TCL");
dsChartData.Tables["ChartInfo"].Columns.Add("TUS");
dsChartData.Tables["ChartInfo"].Columns.Add("TLS");
dsChartData.Tables["ChartInfo"].Columns.Add("XUCL");
dsChartData.Tables["ChartInfo"].Columns.Add("XLCL");
dsChartData.Tables["ChartInfo"].Columns.Add("XCL");
dsChartData.Tables["ChartInfo"].Columns.Add("XUS");
dsChartData.Tables["ChartInfo"].Columns.Add("XLS");
dsChartData.Tables["ChartInfo"].Columns.Add("GUCL");
dsChartData.Tables["ChartInfo"].Columns.Add("GLCL");
dsChartData.Tables["ChartInfo"].Columns.Add("GCL");
dsChartData.Tables["ChartInfo"].Columns.Add("GUS");
dsChartData.Tables["ChartInfo"].Columns.Add("GLS");
dsChartData.Tables["ChartInfo"].Rows.Add(dsChartData.Tables["ChartInfo"].NewRow());
// dsChartData.Tables.Add("TrendData")
// dsChartData.Tables.Add("XbarData")
// dsChartData.Tables.Add("GraphData")
}
string argEnterpriseNo = "";
strChkTemp = kcSPC.funChkQCChartValue(LotNo, QCItemNo, Employee,
dtQCItemFactor, dtTestValue, ref FactorSerial, ref dtViolation,
ref ERFAction, ref ERFMsg, dsChartData,
EnterpriseNo: argEnterpriseNo);
if (Convert.ToBoolean(Strings.InStr(strChkTemp, "fail"))) // 無管制圖或檢查過程錯誤
{
strCheckNotOKMessage = "ChkQCChartValue" + strChkTemp;
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/19
}
}
// 若純檢查,只要做到這裡為止 'Added by Yun 2007/11/2
if (blnChkOnly == true)
{
funAutoBRSPCContorl_VarRet = strCheckNotOKMessage; // last modify by Neil 2008/06/03
return funAutoBRSPCContorl_VarRet;
}
// Added by Neil 2008/05/19
if (blnCheckOK == false)
{
drData["Execute"] = strCheckNotOKMessage; // Add Yun 2017/11/28 將Check 結果傳出
// 檢查沒過回寫狀態
if (drData.Table.Columns.Contains("UpdateSQL") && !(drData["UpdateSQL"] is DBNull))
{
if (drData.Table.Columns.Contains("UpdateSQLReplace") && !(drData["UpdateSQLReplace"] is DBNull))
{
var CollectSQL = new Collection();
// drData("Execute") = strCheckNotOKMessage 'Marked Yun 2017/11/28 移到上面
objtc_SPC.CollectUpdateSQL(ref drData, ref CollectSQL);
if (CollectSQL.Count != 0)
{
kcSPC.ExecuteSQL(CollectSQL);
}
}
}
funAutoBRSPCContorl_VarRet = strCheckNotOKMessage;
return funAutoBRSPCContorl_VarRet;
}
// 備用
DataTable dtComponent;
dtComponent = new DataTable("Component");
dtComponent.Columns.Add("SPCSerial", Type.GetType("System.String"));
dtComponent.Columns.Add("QCItemNo", Type.GetType("System.String"));
dtComponent.Columns.Add("ComponentNo", Type.GetType("System.String"));
dtComponent.Columns.Add("CompResult", Type.GetType("System.String"));
// ===== 整理生產批(各品管項目綜合)結果,並存入資料庫 =========
if (Strings.InStr(ERFAction, "Hold") > 0)
{
LinkName = "Hold";
intResult = 1;
}
else if (Strings.InStr(ERFAction, "Alarm") > 0)
{
LinkName = "Alarm";
intResult = 4;
}
else if (Strings.InStr(ERFAction, "Alert") > 0)
{
LinkName = "Alert";
intResult = 4;
}
else if (Strings.InStr(ERFAction, "Wait") > 0)
{
LinkName = "Wait";
intResult = 2;
}
else if (Strings.InStr(ERFAction, "Warning") > 0)
{
LinkName = "Warning";
intResult = 3;
}
else
{
LinkName = "Pass";
intResult = 0;
}
drData["Result"] = LinkName; // 回傳出去給人看的所以用字串
drData["intResult"] = intResult;
// Add QCItem Test Value
dtQCItem = new DataTable("QCItem");
dtQCItem.Columns.Add("QCItemNo", Type.GetType("System.String"));
dtQCItem.Columns.Add("FactorSerial", Type.GetType("System.String"));
dtQCItem.Columns.Add("RetestLotNo", Type.GetType("System.String"));
dtQCItem.Columns.Add("ERFMsg", Type.GetType("System.String"));
dtQCItem.Columns.Add("Result", Type.GetType("System.String")); // 紀錄結果 0,1,2,....
dtQCItem.Columns.Add("SPCSerial", Type.GetType("System.String")); // 在UpdVar_TestValue中會將SPCSerial 填入
drAdd = dtQCItem.NewRow();
drAdd["QCItemNo"] = QCItemNo;
drAdd["FactorSerial"] = FactorSerial;
drAdd["RetestLotNo"] = "";
drAdd["ERFMsg"] = ERFMsg;
drAdd["Result"] = intResult.ToString();
dtQCItem.Rows.Add(drAdd);
//EAP过站组件信息
if (EAPControl)
{
DataView dataView = dtTestValue.DefaultView;
DataTable QcItemNoDistinct = dataView.ToTable(true, "ComponentNo", "QCItemNo");
DataRow[] drSelCom;
// 將資料存入暫存Table
for (int q = 0; q < QcItemNoDistinct.Rows.Count; q++)
{
var drcomData = dtComponent.NewRow();
drcomData["QCItemNo"] = QCItemNo;
if (QcItemNoDistinct.Rows[q]["QCItemNo"].ToString() == QCItemNo)
{
drcomData["ComponentNo"] = QcItemNoDistinct.Rows[q]["ComponentNo"].ToString();
}
if (dtViolation.Rows.Count > 0)
{
drSelCom = dtViolation.Select("ComponentNo='" + QcItemNoDistinct.Rows[q]["ComponentNo"].ToString() + "'");
if (drSelCom.Length > 0)
{
drcomData["CompResult"] = "1";
}
else
{
drcomData["CompResult"] = "0";
}
}
else
{
drcomData["CompResult"] = "0";
}
dtComponent.Rows.Add(drcomData);
}
}
var colSQL = new Collection();
string strGSPCSerialTmp = defString;
kcSPC.UpdVar_TestValue(ref strGSPCSerialTmp, dtQCItemFactor, dtQCItem, dtTestValue, LotNo, LotSerial, Employee, dtComponent: dtComponent, colSQL: colSQL, LogGroupSerial: LogGroupSerial, OPNo: OpNo);
// 取得 SPCSerial
strSPCSerial[0] = dtQCItem.Rows[0]["SPCSerial"].ToString();
if (drData.Table.Columns.Contains("SPCSerial"))
{
drData["SPCSerial"] = dtQCItem.Rows[0]["SPCSerial"];
}
// 2020/01/20 ,Yenru Add ERFMSG
if (drData.Table.Columns.Contains("ERFMsg"))
{
drData["ERFMsg"] = dtQCItem.Rows[0]["ERFMsg"];
}
//回写法则编号
string ruleno = "";
if (drData.Table.Columns.Contains("RuleNo"))
{
if (dtViolation.Rows.Count > 0)
{
for (int r = 0; r < dtViolation.Rows.Count; r++)
{
if (dtViolation.Rows[r]["QCItemNo"].ToString() == QCItemNo && dtViolation.Rows[r]["ComponentNo"].ToString() == drData["ComponentNo"].ToString())
{
ruleno = dtViolation.Rows[r]["ViolationID"].ToString();
}
}
}
drData["RuleNo"] = ruleno;
}
// Add SPC待檢清單
kcSPC.UpdSpcLotQCList(LotNo, OpNo, 1, dtQCItem, strSPCSerial, colSQL);
//争对EAP处理
if (EAPControl)
{
//对生产批的处理
if (BrControl || intResult != 0)
{
// WIP的BR_SPCControl
DataTable dtSamplePara = new DataTable("SamplePara");
dtSamplePara.Columns.Add("ParameterNo", Type.GetType("System.String"));
dtSamplePara.Columns.Add("ParameterValue", Type.GetType("System.String"));
kcWIP.BR_SPCControl(long.Parse(LotStamp), LotNo, ref LinkName, QCItemNo, UserNo, ShiftNo, colSQL, dtSamplePara, strMsg: ERFMsg, blnFirstLotOf2ndInsp: false, blnReleaseLog: blnReleaseLog);
funAutoBRSPCContorl_VarRet = LinkName;
// 紀錄Cont_QCItem
var loopTo13 = dtQCItem.Rows.Count - 1;
string[] comp_SPCSerial;
string[] comp_ERFMsg;
for (i = 0; i <= loopTo13; i++)
{
comp_SPCSerial = strSPCSerial[i].Split(';'); // 當計算方式為 ByComponent時會用;隔開
var loopTo14 = comp_SPCSerial.Length - 1;
for (int c = 0; c <= loopTo14; c++)
kcSPC.AddWIPQCItemContent(LotNo, LotSerial, OpNo, QCItemNo, Convert.ToString(dtQCItem.Rows[i]["QCItemNo"]), 1, comp_SPCSerial[c], UserNo, LogGroupSerial, colSQL);
}
}
}
// Add Limit
dsTemp = kcSPC.ShowQCChartDetail(FactorSerial);
if (!(dsTemp.Tables["QCChartDetail"] == null) && dsTemp.Tables["QCChartDetail"].Rows.Count > 0)
{
dsTemp.Tables["QCChartDetail"].Columns.Add("SPCSerial", Type.GetType("System.String"));
var loopTo2 = dsTemp.Tables["QCChartDetail"].Rows.Count - 1;
for (i = 0; i <= loopTo2; i++)
dsTemp.Tables["QCChartDetail"].Rows[i]["SPCSerial"] = dtQCItem.Rows[0]["SPCSerial"];
kcSPC.AddSPCVarLimitContent(dsTemp.Tables["QCChartDetail"], colSQL);
}
// Add Violation
if (!(dtViolation == null) && dtViolation.Rows.Count > 0)
{
var loopTo3 = dtViolation.Rows.Count - 1;
if (EAPControl && Convert.ToInt32(dtQCItemBasis.Rows[0]["CalType"]) == 1)
{
DataTable dtComSpcserial = dtComponent;
for (i = 0; i <= loopTo3; i++)
{
for (int s = 0; s < dtComSpcserial.Rows.Count; s++)
{
if (dtViolation.Rows[i]["QCItemNo"].ToString() == dtComSpcserial.Rows[s]["QCItemNo"].ToString() && dtViolation.Rows[i]["ComponentNo"].ToString() == dtComSpcserial.Rows[s]["ComponentNo"].ToString())
{
dtViolation.Rows[i]["SPCSerial"] = dtComSpcserial.Rows[s]["SPCSerial"];
}
}
}
}
else
{
for (i = 0; i <= loopTo3; i++)
dtViolation.Rows[i]["SPCSerial"] = dtQCItem.Rows[0]["SPCSerial"];
}
kcSPC.AddSPCViolationContent(dtViolation, colSQL);
}
//0173294: [6.0.7]SDD240326_01-04 / Execute_InLineSPC_Judge 將異常單訊息上提到新增ERFCrerateData之前 Edison 241126
var strMsg = default(string);
// ↓===================================================================================================================
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 4, false)) || Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 1, false)))
{
strMsg = "Auto SPC " + "[" + QCItemNo + "]" + Strings.Replace(dtQCItem.Rows[0]["ERFMsg"].ToString(), "$", "");
}
string strSPCSerialPlitByDot = string.Join(",",
dtViolation.AsEnumerable()
.Select(row => row.Field<string>("SPCSerial"))
.Distinct());
if (!blnHoldLot && strMsg != default(string))
kcWIP.AddERFCreateData(LotNo, OpNo, "1", 0, strMsg, PopulationQty, UserNo, strSPCSerialPlitByDot, Conversions.ToInteger(dtQCItemBasis.Rows[0]["LotIsValid"]), 1, LotSerial: LotSerial, colSQL: colSQL);
// 額外需執行的指令
if (drData.Table.Columns.Contains("AdditionalSQL") && !(drData["AdditionalSQL"] is DBNull))
{
aryAdditionalSQL = Strings.Split(drData["AdditionalSQL"].ToString(), "|");
var loopTo4 = aryAdditionalSQL.Length - 1;
for (i = 0; i <= loopTo4; i++)
colSQL.Add(aryAdditionalSQL[i]);
}
// 額外需執行的指令 Added by Neil 2008/05/19
if (drData.Table.Columns.Contains("UpdateSQL") && !(drData["UpdateSQL"] is DBNull))
{
objtc_SPC.CollectUpdateSQL(ref drData, ref colSQL);
}
// 呼叫執行SQL指令
if (CollectionSQL == null)
{
// Call ExecuteSQLNoneQuery_UPD(DataBaseType, strConnectionString, CollectionSQL)
// 執行彙總的 SQL 指令
kcSPC.ExecuteSQL(colSQL);
drData["Execute"] = "success"; // 表示SPC資料已儲存成功
}
else
{
// 2020/11/23 Grace 不執行指令,將指令傳出
var loopTo5 = colSQL.Count;
for (i = 1; i <= loopTo5; i++)
CollectionSQL.Add(colSQL[i]);
}
// ↑===================================================================================================================
// 開立異常單
string ERFNo;
intERFSource = 1;
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 1, false)) && blnAttachChart == true)
{
if (MClassNo == defString)
{
// 取得MClassNo (取不到則不開 ===============================================
cnnTemp = CreateConnection(strConnectionString);
strSQL = "Select MClassNo, QCItemName From tblQCItemForVariables Where QCItemNo = '" + QCItemNo + "'";
// 'cmmTemp = New OleDb.OleDbCommand(strSQL, cnnTemp) 'Select data
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
MClassNo = drTemp["MClassNo"] + "".ToString();
QCItemName = drTemp["QCItemName"] + "".ToString();
if (!string.IsNullOrEmpty(MClassNo)) // Added by Yun 2007/12/19
{
ERFNo = udWIP.InitERFNo(InitNo: "SPC");
kcWIP.UpdERF_Create(1, -1, LotNo, intERFSource, ERFNo, 0, MClassNo, strMsg, Employee, CreateERF: true, OPNo: OpNo, CustomerNo: CustomerNo, ProductNo: ProductNo, SPCSerial: strSPCSerial[0], QCItemType: 1, MailNotice: false);
// 建立異常單附件並發送 Added by Neil 2008/05/21============================================================================
// Dim dtHoldReason As New DataTable("HoldReason")
var AttachFileContent = default(byte[]); // Added by Neil 2008/05/21 mail附件
if (objtc_SPC.funCreateAttachFile(ERFNo + ".pdf", QCItemNo, LotNo, ERFNo, ProductNo, CustomerNo, OpNo, MClassNo, Strings.Replace(Convert.ToString(dtQCItem.Rows[0]["ERFMsg"]), "$", ""), Employee, dsChartData, drData, dtTestValue, dtQCItemFactor, ref AttachFileContent, true, QCItemName) == true)
{
kcSPC.SendAlertMail(OpNo, MClassNo, QCItemNo, "1", "[ERF Create Notice]: ERFNo:" + ERFNo + " LotNo:" + LotNo, "ERFNo:" + ERFNo, ERFNo + ".pdf", AttachFileContent);
}
}
}
drTemp.Close();
CloseConnection(cnnTemp);
}
}
// ===== 發Mail =========
// ↓===================================================================================================================
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 4, false))) // Alert 發 mail
{
// Last Modify:Neil 2008/05/22
var AttachAlertFileContent = default(byte[]); // Added by Neil 2008/05/21 mail附件
if (objtc_SPC.funCreateAttachFile("Alert.pdf", QCItemNo, LotNo, "", ProductNo, CustomerNo, OpNo, MClassNo, Strings.Replace(Convert.ToString(dtQCItem.Rows[0]["ERFMsg"]), "$", ""), Employee, dsChartData, drData, dtTestValue, dtQCItemFactor, ref AttachAlertFileContent, false, QCItemName) == true)
{
kcSPC.SendAlertMail(OpNo, MClassNo, QCItemNo, "1", "[Alert Mail]: QCItemNo:" + QCItemNo, "QCItemNo:" + QCItemNo, "Alert.pdf", AttachAlertFileContent);
}
}
// ↑===================================================================================================================
if (EAPControl)
{
if (!BrControl)
{
if (intResult == 0)
{
funAutoBRSPCContorl_VarRet = "success"; // 表示 Function 執行成功
}
}
}
else
{
funAutoBRSPCContorl_VarRet = "success"; // 表示 Function 執行成功
}
}
catch (Exception e1)
{
funAutoBRSPCContorl_VarRet = "fail";
// 發生錯誤時丟回本身的Function Name及系統錯誤訊息
throw;
} // New Exception("kcSPC.funBRSPConlinetrans: " & e1.Message)
finally
{
if (kcWIP != null)
kcWIP = null;
if (kcQC != null)
kcQC = null;
if (kcSPC != null)
kcSPC = null;
if (objtc_SPC != null)
objtc_SPC = null;
if (cnnTemp != null)
CloseConnection(cnnTemp);
}
return funAutoBRSPCContorl_VarRet;
}
/// <summary>
/// 计数标准-标版备用
/// </summary>
/// <param name="LotSerial"></param>
/// <param name="LogGroupSerial"></param>
/// <param name="LotStamp"></param>
/// <param name="ProductNo"></param>
/// <param name="CustomerNo"></param>
/// <param name="drData"></param>
/// <param name="dvError"></param>
/// <param name="MClassNo"></param>
/// <param name="blnChkOnly"></param>
/// <param name="blnCreateERF"></param>
/// <param name="blnChkAttRule"></param>
/// <param name="CollectionSQL"></param>
/// <param name="AQLRejectNum"></param>
/// <param name="LotRuleNo"></param>
/// <param name="dtQCItemFactorAll"></param>
/// <param name="UserNo"></param>
/// <param name="ShiftNo"></param>
/// <param name="BrControl"></param>
/// <param name="EAPControl"></param>
/// <param name="dtAttDetailLogComponent"></param>
/// <param name="blnReleaseLog"></param>
/// <param name="blnHoldLot"></param>
/// <returns></returns>
public string funAutoBRSPCContorl_Att(ref string LotSerial, ref string LogGroupSerial, ref string LotStamp, ref string ProductNo, ref string CustomerNo,
ref DataRow drData, DataView dvError = null,
string MClassNo = defString, bool blnChkOnly = true, bool blnCreateERF = true,
bool blnChkAttRule = true, Collection CollectionSQL = null,
long AQLRejectNum = defInteger, string LotRuleNo = defString,
DataTable dtQCItemFactorAll = null, string UserNo = defString, string ShiftNo = defString, bool BrControl = false, bool EAPControl = false, DataTable dtAttDetailLogComponent = null, bool blnReleaseLog = true, bool blnHoldLot = true)
{
string funAutoBRSPCContorl_AttRet = default(string);
// 此 Function 將自動判別檢測數據_計數
// 傳入值: drData (一次傳入一組檢驗資料,內有LotNo,OpNo,QCItemNo,PratNo,Employee
// 傳入 : dtError (不良原因)
// 傳回值funAutoBRSPCContorl_Att: success(成功), QCItemNo(找不到品管項目編號), LotNo(找不到批號)...
// 傳回值: drData(檢測結果)
IDbConnection cnnTemp = null;
// 'Dim cmmTemp As OleDb.OleDbCommand
DbDataReader drTemp = null;
string strSQL;
var kcQC = new kcQC.clsQCBasis();
var kcWIP = new kcWIP.clsLot();
var kcSPC = new kcSPC.clsSPC();
var udSPC = new udSPC.clsSPC();
var udWIP = new udWIP.clsWIP();
// Table
DataSet dsTemp;
var dtQCItemBasis = default(DataTable);
var dtQCItemFactor = default(DataTable);
var dtFactorOnline = default(DataTable);
DataTable dtLotData;
var dtWIPFactor = default(DataTable);
DataTable dtQCItem; // 主要是儲存Check後的結果
var dtError = default(DataTable);
DataRow drAdd;
DataRow[] drSel;
// 傳入的資料
var LotNo = default(string);
var OpNo = default(string);
var QCItemNo = default(string);
string QCItemName;
var Employee = default(string);
decimal SampleQty = default(decimal), ScrapQty = default(decimal), DefectQty = default(decimal), GoodQty = default(decimal);
int i, j;
string ERFAction;
var ERFMsg = default(string);
var strSPCSerial = new string[2];
var intResult = default(int);
int intERFSource;
var LinkName = default(string);
// Dim LotSerial As String
// Dim LogGroupSerial As String
string ExecuteSPCSerial;
string PopulationQty = "";
// Dim ProductNo As String
// Dim CustomerNo As String = "N/A" '開異常單時 customerNo不能 Null
// Dim LotStamp As String
bool MailNotice = false;
string[] aryAdditionalSQL;
int LimitLotNum; // 計數品管項目的最大顯示批數
string[] aryUpdateSQLReplace; // Added by Neil 2008/05/22
bool blnCheckOK = true; // Added by Neil 2008/05/22 作為各項檢查的指標任何一項檢查不過則為False
var strCheckNotOKMessage = default(string); // Added by Neil 2008/05/22
tcSPC_IC.clsSPC objtc_SPC = new tcSPC_IC.clsSPC();
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
try
{
funAutoBRSPCContorl_AttRet = "error"; // Initial
// ===== 整理傳入的資料 =========
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
if (drData.Table.Columns.Contains("LotNo"))
{
LotNo = drData["LotNo"] + "".ToString();
}
else
{
strCheckNotOKMessage = "No LotNo";
// Exit Function
blnCheckOK = false;
} // Added by Neil 2008/05/22
}
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
if (drData.Table.Columns.Contains("QCItemNo"))
{
QCItemNo = drData["QCItemNo"] + "".ToString().ToUpper(); // 請注意一定要轉大寫
}
else
{
strCheckNotOKMessage = "No QCItemNo";
// Exit Function
blnCheckOK = false;
} // Added by Neil 2008/05/22
}
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
if (drData.Table.Columns.Contains("OpNo"))
{
OpNo = drData["OpNo"] + "".ToString();
}
if (drData.Table.Columns.Contains("Employee"))
{
Employee = drData["Employee"] + "".ToString();
}
if (drData.Table.Columns.Contains("Product"))
{
ProductNo = drData["Product"] + "".ToString();
}
if (drData.Table.Columns.Contains("SampleQty"))
{
SampleQty = Convert.ToDecimal(drData["SampleQty"]);
}
else
{
strCheckNotOKMessage = "No SampleQty";
// Exit Function
blnCheckOK = false;
} // Added by Neil 2008/05/22
}
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
if (drData.Table.Columns.Contains("ScrapQty"))
{
ScrapQty = Convert.ToDecimal(drData["ScrapQty"]);
}
else
{
strCheckNotOKMessage = "No ScrapQty";
// Exit Function
blnCheckOK = false;
} // Added by Neil 2008/05/22
}
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
if (drData.Table.Columns.Contains("DefectQty"))
{
DefectQty = Convert.ToDecimal(drData["DefectQty"]);
}
else
{
DefectQty = 0m;
}
if (drData.Table.Columns.Contains("GoodQty"))
{
GoodQty = Convert.ToDecimal(drData["GoodQty"]);
}
else
{
strCheckNotOKMessage = "No GoodQty";
// Exit Function
blnCheckOK = false;
} // Added by Neil 2008/05/22
}
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
// 不良原因
if (dvError != null)
{
dtError = dvError.Table.Clone();
var loopTo = dvError.Count - 1;
for (i = 0; i <= loopTo; i++)
dtError.ImportRow(dvError[i].Row);
if (funChkReasonsExist(dtError, ref ScrapQty, ref DefectQty, ref GoodQty, ref SampleQty) == false)
{
strCheckNotOKMessage = "ReasonNo is not exist";
blnCheckOK = false;
}
}
// ===== 檢查資料是否正確 =========
// 1.取出品管項目
dtQCItemBasis = kcQC.ShowQCItemForAttributes(QCItemNo, IssueState: 2).Tables[0];
if (dtQCItemBasis == null || dtQCItemBasis.Rows.Count == 0)
{
strCheckNotOKMessage = "QCItemNo Error";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/22
}
}
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
// 2 取出Lot資料
dtLotData = kcWIP.ShowLotBasisJoinState(LotNo).Tables[0];
if (dtLotData == null || dtLotData.Rows.Count == 0)
{
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItemBasis.Rows[0]["LotIsValid"], 1, false))) // 必須檢查批號有效,但找不到批號資料
{
strCheckNotOKMessage = "LotData Error";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/22
}
}
else
{
PopulationQty = dtLotData.Rows[0]["CurQty"].ToString();
LotSerial = dtLotData.Rows[0]["LotSerial"] + "".ToString();
LogGroupSerial = dtLotData.Rows[0]["LogGroupSerial"] + "".ToString();
LotStamp = dtLotData.Rows[0]["LotStamp"] + "".ToString();
ProductNo = dtLotData.Rows[0]["ProductNo"] + "".ToString();
CustomerNo = dtLotData.Rows[0]["CustomerNo"] + "".ToString();
OpNo = dtLotData.Rows[0]["OpNo"] + "".ToString();
}
}
// ===== 整理要因資料 =========
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
// 3.1 取出 QCItemFactor
if (!(dtQCItemFactorAll == null))
{
dtQCItemFactor = dtQCItemFactorAll;
}
else
{
dtQCItemFactor = kcQC.ShowQCItemFactor(QCItemNo).Tables[0];
}
if (dtQCItemFactor == null || dtQCItemFactor.Rows.Count == 0)
{
strCheckNotOKMessage = "QCItemFactor Error";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/22
}
}
// 3.2 取得檢驗批的要因資料
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtWIPFactor = udSPC.LoadLotFactorValue(LotNo).Tables[0];
}
// 3.3.將取得的要因值填入品管項目要因,取不到值的則填入N/A
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtQCItemFactor.Columns.Add("FactorValue", Type.GetType("System.String"));
dtFactorOnline = dtQCItemFactor.Clone(); // 複製Table Schema
var loopTo1 = dtQCItemFactor.Rows.Count - 1;
for (i = 0; i <= loopTo1; i++)
{
drSel = dtWIPFactor.Select("ParameterNo = '" + dtQCItemFactor.Rows[i]["FactorNo"] + "'".ToString());
if (drSel.Length > 0)
{
dtQCItemFactor.Rows[i]["FactorValue"] = drSel[0]["Value"];
}
else if (drData.Table.Columns.Contains(Convert.ToString(dtQCItemFactor.Rows[i]["FactorNo"])) && !(drData[dtQCItemFactor.Rows[i]["FactorNo"].ToString()] is DBNull) && Convert.ToBoolean(Operators.ConditionalCompareObjectNotEqual(drData[dtQCItemFactor.Rows[i]["FactorNo"].ToString()], "", false)))
{
dtQCItemFactor.Rows[i]["FactorValue"] = drData[dtQCItemFactor.Rows[i]["FactorNo"].ToString()]; // 從傳入的drData 中取得要因
}
else
{
dtQCItemFactor.Rows[i]["FactorValue"] = "N/A";
}
// 取出線上管制要因
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItemFactor.Rows[i]["FactorOnline"], "Y", false)))
{
dtFactorOnline.ImportRow(dtQCItemFactor.Rows[i]);
}
}
}
// '===== 檢查此筆檢測資料是否已經存過 =========
// If blnChkOnly = True Then
// If kcSPC.ShowVarFactorLog(, , QCItemNo, LotNo).Tables("SPCVarFactorLog").Rows.Count > 0 Then
// funAutoBRSPCContorl_Var = "Already Exist"
// Exit Function
// End If
// End If
// 若純檢查,只要做到這裡為止
if (blnChkOnly == true)
{
funAutoBRSPCContorl_AttRet = "";
return funAutoBRSPCContorl_AttRet;
}
// '===== Check 規格與管制法則 =========
var dtViolation = new DataTable("Violation"); // 執行 funChkAttRule 後回傳結果
if (blnChkAttRule == true)
{
if (blnCheckOK == true) // 前項檢查通過才繼續下面的動作
{
dtViolation.Columns.Add("SPCSerial", Type.GetType("System.String"));
dtViolation.Columns.Add("ViolationID", Type.GetType("System.String")); // 違反類型WE001, WE002, ..,WE008
dtViolation.Columns.Add("PChartFlag", Type.GetType("System.Int16")); // 0:否 1:是
if (!(dtQCItemBasis.Rows[0]["LimitLotNum"] is DBNull))
{
LimitLotNum = Conversions.ToInteger(dtQCItemBasis.Rows[0]["LimitLotNum"]);
}
else
{
LimitLotNum = defInteger;
}
// 檢查法則(取出LinkeName,ERFMsg,intResult,dtViolation)
if (Convert.ToBoolean(objtc_SPC.funChkAttRule(QCItemNo, dtError, Convert.ToString(dtQCItemBasis.Rows[0]["RuleNo"] +
""), (long)Math.Round(SampleQty), ref LinkName, ref ERFMsg, ref intResult, ref dtViolation, ScrapQty / SampleQty, dtFactorOnline, LimitLotNum, AQLRejectNum, LotRuleNo)) == false)
{
strCheckNotOKMessage = "Check Rule Error";
// Exit Function
blnCheckOK = false; // Added by Neil 2008/05/22
}
}
}
// Added by Neil 2008/05/19
if (blnCheckOK == false)
{
drData["Execute"] = strCheckNotOKMessage; // 從下面搬移過來 Yun 2009/6/4
// 檢查沒過回寫狀態
if (drData.Table.Columns.Contains("UpdateSQL") && !(drData["UpdateSQL"] is DBNull))
{
if (drData.Table.Columns.Contains("UpdateSQLReplace") && !(drData["UpdateSQLReplace"] is DBNull))
{
var CollectSQL = new Collection();
// drData("Execute") = strCheckNotOKMessage '搬移 Yun 2009/6/4
objtc_SPC.CollectUpdateSQL(ref drData, ref CollectSQL);
if (CollectSQL.Count != 0)
{
kcSPC.ExecuteSQL(CollectSQL);
}
}
}
funAutoBRSPCContorl_AttRet = strCheckNotOKMessage;
return funAutoBRSPCContorl_AttRet;
}
drData["Result"] = LinkName; // 回傳出去給人看的所以用字串
drData["intResult"] = intResult;
// Add QCItem Test Value
dtQCItem = new DataTable("QCItem");
dtQCItem.Columns.Add("QCItemNo", Type.GetType("System.String"));
dtQCItem.Columns.Add("QCAttSPSerial", Type.GetType("System.String"));
dtQCItem.Columns.Add("SampleQty", Type.GetType("System.Int32"));
dtQCItem.Columns.Add("GoodQty", Type.GetType("System.Int32"));
dtQCItem.Columns.Add("ScrapQty", Type.GetType("System.Int32"));
dtQCItem.Columns.Add("DefectQty", Type.GetType("System.Int32"));
dtQCItem.Columns.Add("Result", Type.GetType("System.Int32"));
dtQCItem.Columns.Add("ERFMsg", Type.GetType("System.String"));
dtQCItem.Columns.Add("SPCSerial", Type.GetType("System.String")); // 產生SPCSerial後可存在此欄位
if (blnChkAttRule == true)
{
drAdd = dtQCItem.NewRow();
drAdd["QCItemNo"] = QCItemNo;
drAdd["QCAttSPSerial"] = "";
drAdd["SampleQty"] = SampleQty;
drAdd["GoodQty"] = GoodQty;
drAdd["ScrapQty"] = ScrapQty;
drAdd["DefectQty"] = DefectQty;
drAdd["Result"] = intResult.ToString();
drAdd["ERFMsg"] = ERFMsg;
drAdd["SPCSerial"] = "";
if (MClassNo != defString)
{
drAdd["MClassNo"] = MClassNo;
}
dtQCItem.Rows.Add(drAdd);
// 2020/01/20 ,Yenru Add ERFMSG
if (drData.Table.Columns.Contains("ERFMsg"))
{
drData["ERFMsg"] = dtQCItem.Rows[0]["ERFMsg"];
}
//回写法则编号
string ruleno = "";
if (drData.Table.Columns.Contains("RuleNo"))
{
drData["RuleNo"] = dtQCItemBasis.Rows[0]["RuleNo"];
}
}
else
{
drAdd = dtQCItem.NewRow();
drAdd["QCItemNo"] = drData["QCItemNo"];
drAdd["QCAttSPSerial"] = "";
drAdd["SampleQty"] = drData["SampleQty"];
drAdd["GoodQty"] = drData["GoodQty"];
drAdd["ScrapQty"] = drData["ScrapQty"];
drAdd["DefectQty"] = 0;
drAdd["Result"] = drData["DefaultResult"];
drAdd["ERFMsg"] = "";
drAdd["SPCSerial"] = "";
if (MClassNo != defString)
{
drAdd["MClassNo"] = MClassNo;
}
dtQCItem.Rows.Add(drAdd);
}
// 收集要執行的指令
var colSQL = new Collection();
string strReturnValue;
// Update SPC Log
if (!dtQCItem.Columns.Contains("Rank"))
{
dtQCItem.Columns.Add("Rank", Type.GetType("System.String")); // 2010/06/28 Lai
}
if (!dtQCItem.Columns.Contains("RankDetail"))
{
dtQCItem.Columns.Add("RankDetail", Type.GetType("System.String")); // 2010/06/28 Lai
}
strReturnValue = kcSPC.UpdAtt_TestValue(dtQCItemFactor, dtQCItem, dtError, LotNo, LotSerial, Creator: Employee, colSQL: colSQL, LogGroupSerial: LogGroupSerial);
// 取得 SPCSerial
strSPCSerial = Strings.Split(strReturnValue, "|");
if (drData.Table.Columns.Contains("SPCSerial"))
{
drData["SPCSerial"] = strSPCSerial[0];
}
// Add SPC待檢清單
kcSPC.UpdSpcLotQCList(LotNo, OpNo, 0, dtQCItem, strSPCSerial, colSQL);
//争对EAP处理
if (EAPControl)
{
//对生产批的处理
if (BrControl || intResult != 0)
{
// WIP的BR_SPCControl
DataTable dtSamplePara = new DataTable("SamplePara");
dtSamplePara.Columns.Add("ParameterNo", Type.GetType("System.String"));
dtSamplePara.Columns.Add("ParameterValue", Type.GetType("System.String"));
kcWIP.BR_SPCControl(long.Parse(LotStamp), LotNo, ref LinkName, QCItemNo, UserNo, ShiftNo, colSQL, dtSamplePara, strMsg: ERFMsg, blnFirstLotOf2ndInsp: false, blnReleaseLog: blnReleaseLog);
funAutoBRSPCContorl_AttRet = LinkName;
// 紀錄Cont_QCItem
var loopTo13 = dtQCItem.Rows.Count - 1;
string[] comp_SPCSerial;
string[] comp_ERFMsg;
for (i = 0; i <= loopTo13; i++)
{
comp_SPCSerial = strSPCSerial[i].Split(';'); // 當計算方式為 ByComponent時會用;隔開
var loopTo14 = comp_SPCSerial.Length - 1;
for (int c = 0; c <= loopTo14; c++)
kcSPC.AddWIPQCItemContent(LotNo, LotSerial, OpNo, QCItemNo, Convert.ToString(dtQCItem.Rows[i]["QCItemNo"]), 1, comp_SPCSerial[c], UserNo, LogGroupSerial, colSQL);
}
}
}
string strPChcartViolationID;
// Add Att Violation
if (!(dtViolation == null) && dtViolation.Rows.Count > 0)
{
strPChcartViolationID = "";
var loopTo2 = dtViolation.Rows.Count - 1;
for (i = 0; i <= loopTo2; i++)
{
dtViolation.Rows[i]["SPCSerial"] = dtQCItem.Rows[0]["SPCSerial"];
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtViolation.Rows[i]["PChartFlag"], 1, false)))
{
strPChcartViolationID = strPChcartViolationID + (string.IsNullOrEmpty(strPChcartViolationID) ? "" : "|") +
dtViolation.Rows[i]["ViolationID"];
}
}
kcSPC.AddSPCAttViolationContent(dtViolation, colSQL);
kcSPC.AddSPCPChartFailLog(strSPCSerial[0], QCItemNo, (ScrapQty / SampleQty).ToString(), strPChcartViolationID, ProductNo, OpNo); // P-Chart 不良紀錄
}
//0173294: [6.0.7]SDD240326_01-04 / Execute_InLineSPC_Judge 將異常單訊息上提到新增ERFCrerateData之前 Edison 241126
var strMsg = default(string);
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 4, false)) || Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 3, false))) // Alert 或 Hold 要發 mail (4=Alert,計數的Result,與計量不同)
{
strMsg = "Auto SPC " + "[" + QCItemNo + "]" + Strings.Replace(dtQCItem.Rows[0]["ERFMsg"].ToString(), "$", "");
// Call kcSPC.SendAlertMail(OpNo, MClassNo, QCItemNo, "0", "[Alert Mail]:" & QCItemNo, strMsg)
}
string strSPCSerialPlitByDot = string.Join(",",
dtViolation.AsEnumerable()
.Select(row => row.Field<string>("SPCSerial"))
.Distinct());
if (!blnHoldLot && strMsg != default(string))
kcWIP.AddERFCreateData(LotNo, OpNo, "1", 0, strMsg, PopulationQty, UserNo, strSPCSerialPlitByDot, Conversions.ToInteger(dtQCItemBasis.Rows[0]["LotIsValid"]), 1, LotSerial: LotSerial, colSQL: colSQL);
if (!(dtAttDetailLogComponent == null))
{
var loopTo14 = dtAttDetailLogComponent.Rows.Count - 1;
for (i = 0; i <= loopTo14; i++)
kcSPC.AddSPCAttDetailLogComponent(strSPCSerial[0], dtAttDetailLogComponent.Rows[i]["ComponentNo"].ToString(), dtAttDetailLogComponent.Rows[i]["ErrorNo"].ToString(), Convert.ToDecimal(dtAttDetailLogComponent.Rows[i]["ErrorQty"]), dtAttDetailLogComponent.Rows[i]["Area"].ToString(), dtAttDetailLogComponent.Rows[i]["Memo"].ToString(), colSQL);
}
// 額外需執行的指令
if (drData.Table.Columns.Contains("AdditionalSQL") && Operators.ConditionalCompareObjectNotEqual(drData["AdditionalSQL"] + "", "", false))
{
aryAdditionalSQL = Strings.Split(drData["AdditionalSQL"].ToString(), "|");
var loopTo3 = aryAdditionalSQL.Length - 1;
for (i = 0; i <= loopTo3; i++)
colSQL.Add(aryAdditionalSQL[i]);
}
// 額外需執行的指令 Added by Neil 2008/05/22
if (drData.Table.Columns.Contains("UpdateSQL") && !(drData["UpdateSQL"] is DBNull))
{
objtc_SPC.CollectUpdateSQL(ref drData, ref colSQL);
}
// 呼叫執行SQL指令
if (CollectionSQL == null)
{
// Call ExecuteSQLNoneQuery_UPD(DataBaseType, strConnectionString, CollectionSQL)
// 執行彙總的 SQL 指令
kcSPC.ExecuteSQL(colSQL);
drData["Execute"] = "success"; // 表示SPC資料已儲存成功
}
else
{
// 2020/11/23 Grace 不執行指令,將指令傳出
var loopTo4 = colSQL.Count;
for (i = 1; i <= loopTo4; i++)
CollectionSQL.Add(colSQL[i]);
}
if (blnCreateERF == true)
{
// ===== 發Mail =========
// //Create connection
//var strMsg = default(string);
//// ↓===================================================================================================================
//if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 4, false)) || Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 3, false))) // Alert 或 Hold 要發 mail (4=Alert,計數的Result,與計量不同)
//{
// strMsg = "Auto SPC " + "[" + QCItemNo + "]" + Strings.Replace(dtQCItem.Rows[0]["ERFMsg"].ToString(), "$", "");
// // Call kcSPC.SendAlertMail(OpNo, MClassNo, QCItemNo, "0", "[Alert Mail]:" & QCItemNo, strMsg)
//}
// ↑===================================================================================================================
// 開立異常單
string ERFNo;
string OPName = defString; // added by Neil 2008/07/29
intERFSource = 1;
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(dtQCItem.Rows[0]["Result"], 3, false))) // Hold
{
if (MClassNo == defString)
{
// 取得MClassNo (取不到則不開) ======================================================== 'update by Yun 2007/12/19
cnnTemp = CreateConnection(strConnectionString);
strSQL = "Select MClassNo, QCItemName From tblQCItemForAttributes Where QCItemNo = '" + QCItemNo + "'";
// cmmTemp = New OleDb.OleDbCommand(strSQL, cnnTemp) 'Select data
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
MClassNo = drTemp["MClassNo"] + "".ToString();
QCItemName = drTemp["QCItemName"] + "".ToString();
if (!string.IsNullOrEmpty(MClassNo)) // Added by Yun 2007/12/19
{
ERFNo = udWIP.InitERFNo(InitNo: "SPC");
kcWIP.UpdERF_Create(1, Conversions.ToLong(LotStamp), LotNo, intERFSource, ERFNo, 0, MClassNo, strMsg, Employee, CreateERF: true, OPNo: OpNo, CustomerNo: CustomerNo, ProductNo: ProductNo, SPCSerial: strSPCSerial[0], QCItemType: 0);
}
}
drTemp.Close();
CloseConnection(cnnTemp);
}
}
}
if (EAPControl)
{
if (!BrControl)
{
if (intResult == 0)
{
funAutoBRSPCContorl_AttRet = "success"; // 表示 Function 執行成功
}
}
}
else
{
funAutoBRSPCContorl_AttRet = "success"; // 表示 Function 執行成功
}
}
catch (Exception e1)
{
funAutoBRSPCContorl_AttRet = "fail";
// 發生錯誤時丟回本身的Function Name及系統錯誤訊息
throw;
} // New Exception("kcSPC.funBRSPConlinetrans: " & e1.Message)
finally
{
if (kcWIP != null)
kcWIP = null;
if (kcQC != null)
kcQC = null;
if (kcSPC != null)
kcSPC = null;
if (objtc_SPC != null)
objtc_SPC = null;
if (cnnTemp != null)
CloseConnection(cnnTemp);
}
return funAutoBRSPCContorl_AttRet;
}
// Added by Neil 2008/07/29 檢查原因是否存在並更新ScrapQty,DefectQty,GoodQty資料
private bool funChkReasonsExist(DataTable dtError, ref decimal ScrapQty, ref decimal DefectQty, ref decimal GoodQty, ref decimal SampleQty)
{
bool funChkReasonsExistRet = default(bool);
IDbConnection cnnTemp = null;
// Dim cmmTemp As OleDb.OleDbCommand
DbDataReader drTemp = null;
var ScrapCount = default(decimal);
var DefectCount = default(decimal);
int inti;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
string strSQL = "";
try
{
// //Create connection
cnnTemp = CreateConnection(strConnectionString);
// cmmTemp = New OleDb.OleDbCommand
// cmmTemp.Connection = cnnTemp
funChkReasonsExistRet = true;
var loopTo = dtError.Rows.Count - 1;
for (inti = 0; inti <= loopTo; inti++)
{
// 檢查資料在 TBL_QUICS_SPCDETAILLOG 中是否存在
strSQL = "SELECT REASONTYPE FROM TBLQCREASONBASIS " + "WHERE " + "REASONNO = '" +
dtError.Rows[inti]["ErrorNo"] + "' AND ISSUESTATE = 2";
// cmmTemp.CommandText = strSQL
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read() == false) // 若不存在則結束
{
funChkReasonsExistRet = false;
return funChkReasonsExistRet;
}
else
{
switch (drTemp["ReasonType"].ToString())
{
case "0": // Scrap
{
ScrapCount = (decimal)((double)ScrapCount + Conversion.Val(dtError.Rows[inti]["ErrorQty"]));
break;
}
case "1": // Defect
{
DefectCount = (decimal)((double)DefectCount + Conversion.Val(dtError.Rows[inti]["ErrorQty"]));
break;
}
}
}
drTemp.Close();
}
ScrapQty = ScrapCount;
DefectQty = DefectCount;
GoodQty = SampleQty - (ScrapQty + DefectQty);
}
catch (Exception ex)
{
funChkReasonsExistRet = false;
throw;
}
finally
{
if (!(cnnTemp == null))
CloseConnection(cnnTemp);
}
return funChkReasonsExistRet;
}
//建立计数检验数据收集接口
public static bool funCreateSPCATTBASIS(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, ref Collection CollectionSQL, string SpcSerial, string QCItemNo, string LotNo, string SampleQty, string GoodQty, string ScrapQty, string DefectQty, string Result, string SPCSerial_QMS, string MaterialNo, string MTLVendor, string Employee, string ProDuct, string EquipMent, string DC, string CreateDate)
{
bool result = false;
//int i;
string strSQL = "";
string strSQL_Value = "";
//IDbConnection cnnTemp = null;
//DbDataReader drTemp = null;
//Collection CollectionSQL = new Collection();
//AppSettings objSetting = new AppSettings();
//string strDataBaseType = objSetting.GetDataBaseType();
//string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
decimal decResult = 0;
try
{
//cnnTemp = CreateConnection(strConnectionString);
//因为前面先锁住序号,所有这里不需要再次检查
////先检查是否已经存在相同数据
//strSQL = $@"Select * From tblSPCAttBasisLog Where SpcSerial ='{SpcSerial}'";
//drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
//if (drTemp.Read())
//{
// //combineException(ref aryException, null, null, "[%已经存在对应的计数检验数据!%]");
// //return result;
// throw new Exception("已经存在对应的计数检验数据!");
//}
//drTemp.Dispose();
//主档
strSQL = "Insert Into tblSPCAttBasisLog(SpcSerial,QCItemNo,LotNo,CreateDate,Creator,Product,Equipment,SPCSerial_QMS,MATERIAL,MTLVendor,EMPLOYEE,DC";
strSQL_Value = $@" Values('{SpcSerial}','{QCItemNo}','{LotNo}',To_Date('{Strings.Format(Convert.ToDateTime(CreateDate), "yyyy/MM/dd H:mm:ss")}','YYYY/MM/DD HH24:MI:SS'),'QMS','{ProDuct}',
'{EquipMent}','{SPCSerial_QMS}','{MaterialNo}','{MTLVendor}','{Employee}','{DC}'";
if (SampleQty != "")
{
strSQL += ",SampleQty";
strSQL_Value += $@",{SampleQty}";
}
if (GoodQty != "")
{
strSQL += ",GoodQty";
strSQL_Value += $@",{GoodQty}";
}
if (ScrapQty != "")
{
strSQL += ",ScrapQty";
strSQL_Value += $@",{ScrapQty}";
}
if (DefectQty != "")
{
strSQL += ",DefectQty";
strSQL_Value += $@",{DefectQty}";
}
if (Result != "")
{
if (Result.ToUpper() == "PASS")
{
//成功
decResult = 0;
}
else
{
//失败 //先默认4
decResult = 4;
}
strSQL += ",Result";
strSQL_Value += $@",{decResult}";
}
strSQL += ")";
strSQL_Value += ")";
CollectionSQL.Add(strSQL + strSQL_Value);
//ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
result = true;
}
catch (Exception ex)
{
//combineException(ref aryException, null, ex.Message, "[%新增计数检验数据失败%]", ex.StackTrace);
throw;
}
finally
{
//if (drTemp != null && !drTemp.IsClosed)
//{
// drTemp.Close();
//}
//CloseConnection(cnnTemp);
}
return result;
}
//建立计数检验数据明细记录接口
public static bool funCreateSPCATTDETAIL(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, ref Collection CollectionSQL, string SpcSerial, string QCItemNo, string ErrorNo, string strErrorQty, string CreateDate)
{
bool result = false;
string strSQL = "";
string strSQL_Value = "";
//IDbConnection cnnTemp = null;
//DbDataReader drTemp = null;
//Collection CollectionSQL = new Collection();
//AppSettings objSetting = new AppSettings();
//string strDataBaseType = objSetting.GetDataBaseType();
//string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
decimal ErrorQty = 0;
try
{
//cnnTemp = CreateConnection(strConnectionString);
//因为前面先锁住序号,所有这里不需要再次检查
////先检查是否已经存在相同数据
//strSQL = $@"Select * From tblSPCAttDetailLog Where SpcSerial ='{SpcSerial}'";
//drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
//if (drTemp.Read())
//{
// combineException(ref aryException, null, null, "[%已经存在对应的计数检验数据!%]");
// return result;
//}
//drTemp.Dispose();
if (!decimal.TryParse(strErrorQty, out ErrorQty))
{
throw new Exception("不良数量格式错误!");
}
//主档
strSQL = "Insert Into tblSPCAttDetailLog(SpcSerial,QCItemNo,ErrorNo,ErrorQty,CreateDate";
strSQL_Value = $@" Values('{SpcSerial}','{QCItemNo}','{ErrorNo}',{ErrorQty},To_Date('{Strings.Format(Convert.ToDateTime(CreateDate), "yyyy/MM/dd H:mm:ss")}','YYYY/MM/DD HH24:MI:SS')";
strSQL += ")";
strSQL_Value += ")";
CollectionSQL.Add(strSQL + strSQL_Value);
//ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
result = true;
}
catch (Exception ex)
{
//combineException(ref aryException, null, ex.Message, "[%新增计数检验数据失败%]", ex.StackTrace);
throw;
}
finally
{
//if (drTemp != null && !drTemp.IsClosed)
//{
// drTemp.Close();
//}
//CloseConnection(cnnTemp);
}
return result;
}
//建立计数检验数据区域明细接口
public static bool funCreateSPCATTSECTION(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, ref Collection CollectionSQL, string SpcSerial, string SectionNo, string ErrorNo, string Area, string strErrorQty)
{
bool result = false;
//int i;
string strSQL = "";
string strSQL_Value = "";
//IDbConnection cnnTemp = null;
//DbDataReader drTemp = null;
//Collection CollectionSQL = new Collection();
//AppSettings objSetting = new AppSettings();
//string strDataBaseType = objSetting.GetDataBaseType();
//string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
decimal ErrorQty = 0;
try
{
//cnnTemp = CreateConnection(strConnectionString);
//因为前面先锁住序号,所有这里不需要再次检查
////先检查是否已经存在相同数据
//strSQL = $@"Select * From tblSPCAttDetailLogSection Where SpcSerial ='{SpcSerial}'";
//drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
//if (drTemp.Read())
//{
// combineException(ref aryException, null, null, "[%已经存在对应的计数检验数据区域明细!%]");
// return result;
//}
//drTemp.Dispose();
//主档
strSQL = "Insert Into tblSPCAttDetailLogSection(SpcSerial,SectionNo,ErrorNo,Area";
strSQL_Value = $@" Values('{SpcSerial}','{SectionNo}','{ErrorNo}','{Area}'";
if (strErrorQty != "")
{
if (!decimal.TryParse(strErrorQty, out ErrorQty))
{
throw new Exception("不良数量格式错误!");
}
strSQL += ",ErrorQty";
strSQL_Value += $@",{ErrorQty}";
}
strSQL += ")";
strSQL_Value += ")";
CollectionSQL.Add(strSQL + strSQL_Value);
////sql集合一起执行
//ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
////成功后回写最大码
//funGetSPCSerialNo(true);
result = true;
}
catch (Exception ex)
{
//combineException(ref aryException, null, ex.Message, "[%新增计数检验数据失败%]", ex.StackTrace);
throw;
}
finally
{
//if (drTemp != null && !drTemp.IsClosed)
//{
// drTemp.Close();
//}
//CloseConnection(cnnTemp);
}
return result;
}
public static string funGetSPCSerialNo(bool ReserveSerialNo)
{
string funExeSerialCreate_SerialRet = default(string);
DbDataReader drTemp = null;
var colSQL = new Collection();
var colSQL_Rows = new Collection();
var arySerial = new ArrayList();
string SerialType = "SPCAPI";
string SerialString = "SPCSERIAL";
int SerialLength = 4;
int DecimalType = 1;
long SerialCount = 1;
int PadLeft = defInteger;
string strSQL = "";
IDbConnection cnnTemp = null;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
try
{
cnnTemp = CreateConnection(strConnectionString);
// 取出最大碼.
bool blnInsert;
long lngMaxSerialNo; // 起始碼.
long lngSerialNo_Last; // 最大一個序號.
var strSerialNo_Last_nn = default(string); // 轉換成10,16,36表示式.
strSQL = "Select MaxSerialNo From tblSYSSerialCreateMax " + " Where SerialType='" + SerialType + "'" + " And SerialString='" + SerialString + "'" + " And SerialLength=" + SerialLength + " And DecimalType=" + DecimalType + "";
// cmmTemp = New OleDb.OleDbCommand(strSQL, cnnTemp)
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
blnInsert = false;
lngMaxSerialNo = Conversions.ToLong(drTemp["MaxSerialNo"]);
}
else
{
blnInsert = true;
lngMaxSerialNo = 0L;
}
drTemp.Close();
// 最大的序號
lngSerialNo_Last = lngMaxSerialNo + SerialCount;
if (DecimalType == 1)
{
strSerialNo_Last_nn = lngSerialNo_Last.ToString();
}
else if (DecimalType == 2)
{
strSerialNo_Last_nn = Tran10_16(lngSerialNo_Last);
}
else if (DecimalType == 3)
{
strSerialNo_Last_nn = Tran10_36(lngSerialNo_Last);
}
// 86774: [6.0.5] 序號規則新增34進位序號
// ===================================== 86774 Start =====================================
else if (DecimalType == 4)
{
strSerialNo_Last_nn = Tran10_34(lngSerialNo_Last);
// ===================================== 86774 End =====================================
}
// 最大碼是否超出序號長度.
if (strSerialNo_Last_nn != null && strSerialNo_Last_nn.Length > SerialLength)
{
throw new iMESException.MESException("9P12-200028", "[%SerialString%]: " + SerialString + Constants.vbNewLine + "[%SerialLength%]: " + SerialLength + Constants.vbNewLine + "[%SerialNo%]: " + strSerialNo_Last_nn);
}
if (ReserveSerialNo == true)
{
// 回填最大碼(利用MaxSerialNo來確保資料的一致性及使用的序號為唯一)
if (blnInsert)
{
strSQL = "Insert into tblSYSSerialCreateMax " + " (SerialType,SerialString,SerialLength,DecimalType,MaxSerialNo) " + " Values('" + SerialType + "','" + SerialString + "'," + SerialLength + "," + DecimalType + "," + lngSerialNo_Last + ")";
colSQL.Add(strSQL);
colSQL_Rows.Add(1);
}
else
{
strSQL = "Update tblSYSSerialCreateMax Set MaxSerialNo=" + lngSerialNo_Last + " Where SerialType='" + SerialType + "'" + " And SerialString='" + SerialString + "'" + " And SerialLength=" + SerialLength + " And DecimalType=" + DecimalType + " And MaxSerialNo=" + lngMaxSerialNo;
colSQL.Add(strSQL);
colSQL_Rows.Add(1);
}
ExecuteSQLNoneQuery_ChkRowCount(Convert.ToString(strDataBaseType), strConnectionString, colSQL, colSQL_Rows);
}
for (int i = 1, loopTo = (int)SerialCount; i <= loopTo; i++)
{
if (PadLeft == 0)
{
if (DecimalType == 1)
{
arySerial.Add((lngMaxSerialNo + i).ToString());
}
else if (DecimalType == 2)
{
arySerial.Add(Tran10_16(lngMaxSerialNo + i).ToString());
}
else if (DecimalType == 3)
{
arySerial.Add(Tran10_36(lngMaxSerialNo + i).ToString());
}
// 86774: [6.0.5] 序號規則新增34進位序號
// ===================================== 86774 Start =====================================
else if (DecimalType == 4)
{
arySerial.Add(Tran10_34(lngMaxSerialNo + i).ToString());
// ===================================== 86774 End =====================================
}
}
else if (DecimalType == 1)
{
arySerial.Add((lngMaxSerialNo + i).ToString().PadLeft(SerialLength, '0'));
}
else if (DecimalType == 2)
{
arySerial.Add(Tran10_16(lngMaxSerialNo + i).ToString().PadLeft(SerialLength, '0'));
}
else if (DecimalType == 3)
{
arySerial.Add(Tran10_36(lngMaxSerialNo + i).ToString().PadLeft(SerialLength, '0'));
}
// 86774: [6.0.5] 序號規則新增34進位序號
// ===================================== 86774 Start =====================================
else if (DecimalType == 4)
{
arySerial.Add(Tran10_34(lngMaxSerialNo + i).ToString().PadLeft(SerialLength, '0'));
// ===================================== 86774 End =====================================
}
}
// 回傳最大碼
if (arySerial.Count > 0)
{
funExeSerialCreate_SerialRet = arySerial[0].ToString();
}
else
{
funExeSerialCreate_SerialRet = null;
}
}
catch (Exception e1)
{
funExeSerialCreate_SerialRet = null;
throw;
}
finally
{
CloseConnection(cnnTemp);
}
return funExeSerialCreate_SerialRet;
}
/// <summary>
/// 拼接异常信息Message + StackTrace用于日志/输出
/// </summary>
public static string GetExceptionFullMessage(Exception ex)
{
if (ex == null)
return "无异常信息";
return $"异常信息:{ex.Message} 堆栈信息:{ex.StackTrace}";
}
#endregion
#region "工单砍单、取消卡控接口"
public static bool funCheckMONoCanEditCancel_M(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, ref decimal InputQty, ref decimal OutputQty, ref string CurrentStatus, string MONo, decimal decQuantity, int intStatus)
{
bool funCheckMONoCanEditCancel_M = default(bool);
//bool r = false;
string strSQL = default(string);
IDbConnection cnnTemp = null;
DbDataReader drTemp = null;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString);
DataSet dsData = new DataSet();
string strReturn = "";
var ReleaseQty = default(decimal);
kcWIP.clsLot objLot = new kcWIP.clsLot();
DataRow drOE = null;
try
{
//标准基础检查
using (var objOE = new clsOEBasis())
{
drOE = objOE.GetMOBasis(MONo.ToUpper());
if (drOE["MONo"] is DBNull == true)
{
//clsERP.combineException(aryException, mesmsg: "[%MONo%]" + drOE["MONo"] + " [%MONoNotExist%]");
//break;
//throw new Exception("工单号不存在");
clsERP.combineMessage(ref aryMessage, mmsg: "[%工单号不存在!%]");
return false;
}
// 如果MES這邊是不使用IssueState = -1, 也要可以改,以EPR那邊為主,
if (!(drOE["MOState"] is DBNull))
{
if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(drOE["MOState"], 99, false)))
{
//clsERP.combineException(aryException, mesmsg: "[%MONo%]" + drOE["MONo"] + " [%MONoClosed%]");
//break;
//throw new Exception("工单状态已经结案!");
clsERP.combineMessage(ref aryMessage, mmsg: "[%工单状态已经结案!%]");
return false;
}
}
// ----- 3. 檢查MO剩餘數量 -----
if (!(drOE["MOQty"] is DBNull))
{
ReleaseQty = Convert.ToDecimal(Operators.SubtractObject(drOE["MOQty"], drOE["UnReleaseLotQty"]));
if (decQuantity > ReleaseQty && intStatus == 0)
{
//clsERP.combineException(aryException, mesmsg: "[%MONo%]" +
// drOE["MONo"] + " [%MOQtyLessThenReleaseLotQty%]");
//break;
//throw new Exception("砍单数量小于现在工单未下线数量!");
clsERP.combineMessage(ref aryMessage, mmsg: "[%砍单数量大于现在工单未下线数量/工单数量!%]");
return false;
}
}
}
//如当前设置A站点前可以砍单/取消可以手动变更为B站点前可以砍单/取消;在作业站属性中配置标识:Delflag只针对线上的生产批
//找到目前线上的生产批
strSQL = $"SELECT A.BASELOTNO,B.STATUS,B.LotStamp FROM TBLWIPLOTBASIS A INNER JOIN TBLWIPLOTSTATE B ON A.BASELOTNO = B.LOTNO WHERE A.MONO='{MONo}' AND B.STATUS IN (0,1,2,3,4,5) AND A.LotState = '1'";
ExecuteSQLQuery_Adapter(strSQL, dsData, "TBLWIPLOTBASIS", cnnTemp);
if (dsData.Tables["TBLWIPLOTBASIS"].Rows.Count > 0)
{
//有线上生产批
//检查线上生产批是否过了有 【在作业站属性中配置标识:Delflag】
//拼接成IN语句
string strLotNo = "";
foreach (DataRow dr in dsData.Tables["TBLWIPLOTBASIS"].Rows)
{
strLotNo += "'" + dr["BASELOTNO"] + "',";
}
strLotNo = strLotNo.Substring(0, strLotNo.Length - 1);
strSQL = $@"SELECT 1
FROM DUAL
WHERE EXISTS (
SELECT 1
FROM TBLOPPROPERTY A
INNER JOIN TBLOPBASIS B
ON A.OPNO = B.OPNO AND B.ISSUESTATE = 2
INNER JOIN TBLWIPLOTLOG C
ON C.OPNO = B.OPNO AND C.STATUS = 1
WHERE A.PROPERTYNO = 'Delflag'
AND A.ISSUESTATE = 2
AND C.LOTNO IN ({strLotNo})
)";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
//存在,说明过了特殊站点,不能变更
clsERP.combineMessage(ref aryMessage, mmsg: "[%线上生产批已经过了带有Delflag站点不能变更!%]");
return false;
}
else
{
//不存在,说明没有过特殊站点,可以变更
//可以变更先将线上的生产批全部wait,顾问说一搬流程就是 一个批,这里直接调用标准wait
foreach (DataRow dr in dsData.Tables["TBLWIPLOTBASIS"].Rows)
{
//如果是 STATUS 字段是 3或者4则则不wait
if (Convert.ToInt32(dr["STATUS"]) == 3 || Convert.ToInt32(dr["STATUS"]) == 4)
{
continue;
}
else
{
int intLotStamp = dr["LotStamp"].ToString().Trim() == "" ? 0 : Convert.ToInt32(dr["LotStamp"]);
//wait
objLot.SetLotStateToWait(LotStamp: intLotStamp, dr["BASELOTNO"].ToString(),
WaitType: 2, UserNo: "ERP", WaitSource: 0, WaitDescription: "砍单接口立即暂停所有批次");
}
}
}
drTemp.Close();
}
//若是成功,返回 工单投入、产出数量 、工单状态工单状态
if (drOE != null)
{
//工单投入(InputQty) = 工单数量(MOQTY) - 未下线数量(UNRELEASELOTQTY)
if (!(drOE["MOQty"] is DBNull) && !(drOE["UnReleaseLotQty"] is DBNull))
{
//使用三元运算符转换工单数量和未下线数量,防止出现空值报错
decimal MOQty = Convert.ToDecimal(drOE["MOQty"] is DBNull ? 0 : drOE["MOQty"]);
decimal UnReleaseLotQty = Convert.ToDecimal(drOE["UnReleaseLotQty"] is DBNull ? 0 : drOE["UnReleaseLotQty"]);
InputQty = MOQty - UnReleaseLotQty;
}
//产出数量 OnputQty MOFINISHQTY
decimal MOFINISHQTY = Convert.ToDecimal(drOE["MOFINISHQTY"] is DBNull ? 0 : drOE["MOFINISHQTY"]);
OutputQty = MOFINISHQTY;
//工单状态 根据 MOSTATE判断赋值给CurrentStatus
// 工单状态
//0:未确认
//1:确认中
//2:已确认
//3:生产中
//4:已在客托仓或退货仓
//99:结案
int MOSTATE = Convert.ToInt32(drOE["MOSTATE"] is DBNull ? 0 : drOE["MOSTATE"]);
switch (MOSTATE)
{
case 0:
CurrentStatus = "未确认";
break;
case 1:
CurrentStatus = "确认中";
break;
case 2:
CurrentStatus = "已确认";
break;
case 3:
CurrentStatus = "生产中";
break;
case 4:
CurrentStatus = "已在客托仓或退货仓";
break;
case 99:
CurrentStatus = "结案";
break;
default:
CurrentStatus = "未知状态";
break;
}
}
funCheckMONoCanEditCancel_M = true;
exitfun:
;
}
catch (Exception ex)
{
// 一行调用,拿到完整异常字符串
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
if (objLot != null)
{
objLot.Dispose();
}
drTemp?.Close();
dsData?.Dispose();
CloseConnection(cnnTemp);
}
return funCheckMONoCanEditCancel_M;
}
#endregion
#region"Mapping反转"
public static bool funGetPrdMapping(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string Productid, string Eqp_id, ref int REVERSALMETHOD)
{
bool funGetPrdMappingref = false;
string strSQL = default(string);
IDbConnection cnnTemp = null;
DbDataReader drTemp = null;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString);
DataSet dsData = new DataSet();
try
{
strSQL = "select d.* from TBLWIPPRDSTATE_LQ a inner join TBLWIPLOTSTATE b on a.LotNo=b.LotNo inner join TBLWIPLOTBASIS c on b.LotNo=c.BaseLotNo inner join TBLPRDMAPPING_LQ d on d.OPNO=b.OPNO and d.ProductNo=c.ProductNo where a.productid ='" + Productid + "'and a.state = '1'";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
REVERSALMETHOD = Convert.ToInt16(drTemp["REVERSALMETHOD"].ToString());
funGetPrdMappingref = true;
}
else
{
throw new Exception("产品作业站未配置反转方式!");
}
drTemp.Close();
}
catch (Exception ex)
{
// 一行调用,拿到完整异常字符串
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
dsData?.Dispose();
CloseConnection(cnnTemp);
}
return funGetPrdMappingref;
}
public static bool funGetMaterialhold(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string source, string materialno, string materiallotno, string holdstate, string creator, string date, string reasonno)
{
bool funGetPrdMappingref = false;
string strSQL = default(string);
IDbConnection cnnTemp = null;
DbDataReader drTemp = null;
AppSettings objSetting = new AppSettings();
Collection CollectionSQL = new Collection();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString);
DataSet dsData = new DataSet();
string MaterialFrom;
try
{
if (materiallotno == "*")
{
materiallotno = "ALL";
}
if (holdstate == "0")
{
if (source == "0")
{
//工单
MaterialFrom = "工单";
strSQL = "select * from TBLOEMOMATERIALSTATE WHERE MaterialNo='" + materialno + "' AND QTY>0";
if (!string.IsNullOrWhiteSpace(materiallotno) && !materiallotno.Equals("ALL", StringComparison.OrdinalIgnoreCase) && !materiallotno.Equals("*", StringComparison.OrdinalIgnoreCase))
{
strSQL += " AND MaterialLotNo ='" + materiallotno + "'";
}
}
else
{
MaterialFrom = "虚拟库";
strSQL = "select * from TBLINVWIPINVENTORY_RAW WHERE MaterialNo='" + materialno + "' AND QTY>0";
if (!string.IsNullOrWhiteSpace(materiallotno) && !materiallotno.Equals("ALL", StringComparison.OrdinalIgnoreCase) && !materiallotno.Equals("*", StringComparison.OrdinalIgnoreCase))
{
strSQL += " AND MaterialLotNo ='" + materiallotno + "'";
}
}
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
strSQL = "INSERT INTO TBLCUSHOLDMATERIALSTATE ( MATERIALFROM , MATERIALNO , MATERIALLOTNO , REASONNO , CREATOR ) VALUES ('" + MaterialFrom + "', '" + materialno + "', '" + materiallotno + "', '" + reasonno + "', '" + creator + "')";
CollectionSQL.Add(strSQL);
strSQL = "INSERT INTO TBLCUSHOLDMATERIALLOG ( MATERIALFROM , MATERIALNO , MATERIALLOTNO , HOLDSTATE , REASONNO , CREATOR) VALUES ('" + MaterialFrom + "', '" + materialno + "', '" + materiallotno + "',1, '" + reasonno + "', '" + creator + "')";
CollectionSQL.Add(strSQL);
}
else
{
throw new Exception("物料不存在或数量不足!");
}
drTemp.Close();
}
else
{
DataTable dtdata = new DataTable();
if (source == "0")
{
//工单
MaterialFrom = "工单";
}
else
{
MaterialFrom = "虚拟库";
}
strSQL = "select * from TBLCUSHOLDMATERIALSTATE where 1=1 ";
if (materiallotno != "*")
{
strSQL += " AND MaterialNo='" + materialno + "'";
}
if (MaterialFrom != "*")
{
strSQL += " AND MaterialFrom='" + MaterialFrom + "'";
}
if ( reasonno != "ERPhold")
{
strSQL += " AND REASONNO='" + reasonno + "'";
}
if (materiallotno != "*")
{
strSQL += " AND MaterialLotNo='" + materiallotno + "'";
}
else
{
strSQL += " AND MaterialLotNo='ALL'";
}
ExecuteSQLQuery_Adapter(strSQL, dtdata, cnnTemp);
if (dtdata.Rows.Count == 0)
{
throw new Exception("物料未被Hold!");
}
foreach (DataRow dr in dtdata.Rows)
{
strSQL = "delete from TBLCUSHOLDMATERIALSTATE where MaterialNo='" + dr["MATERIALNO"] + "' AND MaterialFrom='" + dr["MaterialFrom"] + "' AND REASONNO='" + dr["REASONNO"] + "' AND MaterialLotNo='" + dr["MaterialLotNo"] + "' AND Creator='" + dr["Creator"] + "'";
CollectionSQL.Add(strSQL);
strSQL = "INSERT INTO TBLCUSHOLDMATERIALLOG ( MATERIALFROM , MATERIALNO , MATERIALLOTNO , HOLDSTATE , REASONNO , CREATOR) VALUES ('" + dr["MaterialFrom"] + "', '" + dr["MATERIALNO"] + "', '" + dr["MaterialLotNo"] + "',0, '" + dr["REASONNO"] + "', '" + creator + "')";
CollectionSQL.Add(strSQL);
}
}
ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
funGetPrdMappingref=true;
}
catch (Exception ex)
{
// 一行调用,拿到完整异常字符串
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
dsData?.Dispose();
CloseConnection(cnnTemp);
}
return funGetPrdMappingref;
}
#endregion
#region"钢片绑定"
public static bool funSteelBind(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException,
string equipmentno, string steelno, string carrierno, ref string lotno)
{
bool result = false;
IDbConnection cnnTemp = null;
DataSet dsTemp = new DataSet();
AppSettings objSetting = new AppSettings();
try
{
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
// 1. 根据设备编号查询 TBLWIPTEMP_Equipment 获取 LotNo
cnnTemp = CreateConnection(strConnectionString);
string strSQL;
lotno = carrierno;
// 2. 检查钢片是否已被绑定(被其他批次占用)
dsTemp.Tables.Clear();
strSQL = string.Format("SELECT STEELNO, LOTNO, STEELSTATE FROM TBLCUSSTEELSTATE WHERE STEELNO = '{0}'", steelno);
ExecuteSQLQuery_Adapter(strSQL, dsTemp, "tblSteel", cnnTemp);
if (dsTemp.Tables["tblSteel"].Rows.Count > 0)
{
string existLotNo = dsTemp.Tables["tblSteel"].Rows[0]["LOTNO"].ToString();
if (!string.IsNullOrEmpty(existLotNo) && existLotNo != lotno)
{
throw new Exception("钢片已被绑定:" + steelno);
}
}
// 3. 检查该批次是否已绑定其他钢片,有则先解绑
dsTemp.Tables.Clear();
strSQL = string.Format("SELECT STEELNO FROM TBLCUSSTEELSTATE WHERE LOTNO = '{0}' AND STEELSTATE = '1' AND STEELNO != '{1}'", lotno, steelno);
ExecuteSQLQuery_Adapter(strSQL, dsTemp, "tblOldSteel", cnnTemp);
var CollectionSQL = new Collection();
foreach (DataRow dr in dsTemp.Tables["tblOldSteel"].Rows)
{
string oldSteelNo = dr["STEELNO"].ToString();
CollectionSQL.Add(string.Format("UPDATE TBLCUSSTEELSTATE SET LOTNO = '', STEELSTATE = '0' WHERE STEELNO = '{0}'", oldSteelNo));
CollectionSQL.Add(string.Format("INSERT INTO TBLCUSSTEELLOG(STEELNO, LOTNO, STEELSTATE, CREATOR, CREATDATE) VALUES('{0}', '{1}', '0', 'DS', SYSDATE)", oldSteelNo, lotno));
}
// 4. 绑定新钢片
CollectionSQL.Add(string.Format("UPDATE TBLCUSSTEELSTATE SET LOTNO = '{0}', STEELSTATE = '1' WHERE STEELNO = '{1}'", lotno, steelno));
CollectionSQL.Add(string.Format("INSERT INTO TBLCUSSTEELLOG(STEELNO, LOTNO, STEELSTATE, CREATOR, CREATDATE) VALUES('{0}', '{1}', '1', 'DS', SYSDATE)", steelno, lotno));
ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
result = true;
}
catch (Exception ex)
{
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
CloseConnection(cnnTemp);
dsTemp?.Dispose();
}
return result;
}
#endregion
#region" 产品BOM信息接口"
// OPNO,NODENO,STDQTY,DECREASERATE,SUBMTL
public static bool GetProdBOMInfo(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string PRODUCTNO = defString,
string PRODUCTVERSION = defString, BomRequest bomRequest = null)
{
// tcEAI_C.clsERP.AddUser(ref strMessage, ref strException, PRODUCTNO, PRODUCTNAME, PRODUCTVERSION, CREATOR, CREATEDATE, dtDPPara);
bool result = false;
// int i, j;
string strSQLAddField, strSQLAddValue;
Collection MTLCollection = new Collection();
Collection CollectionSQL = new Collection();
string strSQL = "";
IDbConnection cnnTemp = null;
DbDataReader drTemp, drTemp1;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
bool blnAdd = false; ;
try
{
try
{
// //Create connection
cnnTemp = CreateConnection(strConnectionString);
try
{
//add by 14166 for 产品已核准 则不允许进行参数收集
strSQL = " SELECT * FROM TBLPRDPRODUCTBASIS WHERE PRODUCTNO='" + PRODUCTNO + "' And PRODUCTVERSION='" + PRODUCTVERSION + "' ";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
//if (Convert.ToInt32(drTemp["ISSUESTATE"]) == 2)
//{
// clsERP.combineException(ref aryException, null, null, "[%产品编号:" + PRODUCTNO + " ,产品版本:" + PRODUCTVERSION + " 产品已核准,不允许产品Bom信息收集%]");
// // goto exitfun;
//}
}
else
{
//手动增加一个产品主档
strSQL = "INSERT INTO TBLPRDPRODUCTBASIS (PRODUCTNO,PRODUCTVERSION,PRODUCTNAME,PRODUCTTYPE,ISSUESTATE,\r\n CREATOR,CREATEDATE,DESCRIPTION,CURVERSION, UNITNO, UNITTYPE, SPECNO,CARTONQTY,PALLETQTY,BOXQTY,LOTSTDQTY, CUSTOMERNO , DEVICENO , ECNCONTROL , BATCHECNLOCK , DATASTAMP , UNITID , PANLEID ) VALUES ('"+ PRODUCTNO +"', '"+ PRODUCTVERSION +"', '"+ PRODUCTNO +"', 'null', '0', 'ERP',sysdate, 'ERP新增', '1', '', '', 'N/A', '0', '0', '0', '0','N/A', 'N/A', 'N', '0', '0', '','')";
CollectionSQL.Add(strSQL);
// clsERP.combineException(ref aryException, null, null, "[%产品编号:" + PRODUCTNO + " ,产品版本:" + PRODUCTVERSION + " 产品不存在,不允许产品Bom信息收集%]");
//goto exitfun;
}
drTemp.Close();
// ----- Exception => Fail -----
foreach (Bomlist dr in bomRequest.Bomlist)
{
int NodeType = 0, PUTINPLACETYPE = 0;
string UnitNo = defString, NODEVERSION = defString;
strSQL = "delete from TBLPRDBOM where ProductNo='" + PRODUCTNO + "' and PRODUCTVERSION='" + PRODUCTVERSION + "' and NodeNo='" + dr.MaterialNo.ToString() + "' and OPNO='" + dr.OpNo.ToString() + "'";
CollectionSQL.Add(strSQL);
strSQL = "delete from TBLPRDBOMMATERIALGROUP where ProductNo='" + PRODUCTNO + "' and PRODUCTVERSION='" + PRODUCTVERSION + "' and NodeNo='" + dr.MaterialNo.ToString() + "' and OPNO='" + dr.OpNo.ToString() + "'";
CollectionSQL.Add(strSQL);
strSQL = " SELECT * FROM TBLPRDPRODUCTBASIS WHERE PRODUCTNO='" + dr.MaterialNo.ToString() + "'";
drTemp = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp.Read())
{
//说明是半成品物料
NodeType = 1;
PUTINPLACETYPE = 4;
UnitNo = drTemp["UnitNo"].ToString();
NODEVERSION = "*";
}
else
{
//再检查是不是物料
strSQL = " SELECT * FROM TBLMTLMATERIALBASIS WHERE MATERIALNO='" + dr.MaterialNo.ToString() + "'";
drTemp1 = ExecuteSQLQuery_Reader(strSQL, cnnTemp);
if (drTemp1.Read())
{
NodeType = 0;
PUTINPLACETYPE = 2;
UnitNo = drTemp1["UnitNo"].ToString();
NODEVERSION = "N/A";
}
else
{
throw new Exception("[%NODENO:" + dr.MaterialNo.ToString() + " 既不是半成品也不是物料,信息错误!%]");
//goto exitfun;
}
drTemp1.Close();
}
drTemp.Close();
strSQL = "INSERT INTO TBLPRDBOM (PRODUCTNO, PRODUCTVERSION, NODENO, NODETYPE, STDQTY, UNITNO, DECREASERATE, OPNO, SPECIFIED, CREATOR, CREATEDATE, NODEVERSION, PUTINPLACETYPE,AB,PositionCode) " +
"VALUES('" + PRODUCTNO + "', '" + PRODUCTVERSION + "', '" + dr.MaterialNo.ToString() + "', '" + NodeType + "', '" + dr.StdQty.ToString() + "', '" + UnitNo + "', '" + dr.DecreaseRate.ToString() + "', '" + dr.OpNo.ToString() + "', '0', 'ERP', sysdate, '" + NODEVERSION + "', '" + PUTINPLACETYPE + "', '" + dr.AB.ToString() + "', '" + dr.PositionCode.ToString() + "')";
CollectionSQL.Add(strSQL);
if (!string.IsNullOrEmpty(dr.SubstituteMaterialNo.ToString()) && NodeType == 0)
{
string[] SUBMTLS = dr.SubstituteMaterialNo.ToString().Split(',');
for (int i = 0; i < SUBMTLS.Length; i++)
{
strSQL = "INSERT INTO TBLPRDBOMMATERIALGROUP (PRODUCTNO, PRODUCTVERSION, NODENO, OPNO, MATERIALNO) VALUES('" + PRODUCTNO + "', '" + PRODUCTVERSION + "', '" + dr.MaterialNo + "','" + dr.OpNo.ToString() + "','" + SUBMTLS[i].ToString() + "') ";
CollectionSQL.Add(strSQL);
}
}
}
// 呼叫執行SQL指令
ExecuteSQLNoneQuery_UPD(strDataBaseType, strConnectionString, CollectionSQL);
result = true;
}
catch (Exception ex)
{
// trans.Rollback()
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
}
catch (Exception ex)
{
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
}
catch (Exception ex)
{
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
CloseConnection(cnnTemp);
}
return result;
}
#endregion
#region
public static bool CheckReelQty(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException, string reelId, string storageCode, ref string mcode,
ref string qty, ref string vendordate, ref string vendorcode, ref string manufacturer, ref string vendorlotno, ref string snscale, ref bool everExisted)
{
bool CheckReelQty = default(bool);
string strSQL = "";
IDbConnection cnnTemp = null;
DbDataReader drTemp, drTemp1;
AppSettings objSetting = new AppSettings();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
try
{
// //Create connection
cnnTemp = CreateConnection(strConnectionString);
DataTable dtMaterial = new DataTable();
//供应商生产日期取自制造日期栏依WMS送入格式回传YYYYMMDD字串
//供应商编码、生产厂家、供应商批次、09条码四栏同表取数栏位由WMS进料写入
strSQL = $"select MATERIALNO,QTY,To_Char(MANUFACTUREDATE,'YYYYMMDD') as VENDORDATE,VENDORCODE,MANUFACTURER,VENDERLOTNO,SNSCALE from TBLINVWIPINVENTORY_RAW where MATERIALLOTNO = '{reelId}'";
//仓位有传则以仓别+料卷定位,未传则只以料卷号定位
if (storageCode != "")
{
strSQL += $" and INVENTORYNO = '{storageCode}'";
}
ExecuteSQLQuery_Adapter(strSQL, dtMaterial, cnnTemp);
if (dtMaterial.Rows.Count > 0)
{
mcode = dtMaterial.Rows[0]["MATERIALNO"].ToString();
qty = dtMaterial.Rows[0]["QTY"].ToString();
vendordate = dtMaterial.Rows[0]["VENDORDATE"].ToString();
//栏位未写入时为NULLToString後即空字串与既有回传空值行为一致
vendorcode = dtMaterial.Rows[0]["VENDORCODE"].ToString();
manufacturer = dtMaterial.Rows[0]["MANUFACTURER"].ToString();
vendorlotno = dtMaterial.Rows[0]["VENDERLOTNO"].ToString();
snscale = dtMaterial.Rows[0]["SNSCALE"].ToString();
everExisted = true;
CheckReelQty = true;
goto exitfun;
}
//线边仓查无现存量时,再查料卷日志判断该料卷是否曾经存在,
//用以区分「已扣光」与「卷号根本不存在」两种情形
DataTable dtLog = new DataTable();
strSQL = $"select count(1) as CNT from TBLINVWIPINVENTORY_RAWLOG where MATERIALLOTNO = '{reelId}'";
ExecuteSQLQuery_Adapter(strSQL, dtLog, cnnTemp);
if (dtLog.Rows.Count > 0 && Convert.ToDecimal(dtLog.Rows[0]["CNT"]) > 0)
{
everExisted = true;
}
exitfun:
;
}
catch (Exception ex)
{
string errorMsg = GetExceptionFullMessage(ex);
throw new Exception(errorMsg);
}
finally
{
CloseConnection(cnnTemp);
}
return CheckReelQty;
}
#endregion
#region MES退料
/// <summary>
/// WMS退料依REELINFO逐笔扣减线边仓料卷数量数量不够则清空、不报错
/// </summary>
/// <param name="mvdCode">退料单号</param>
/// <param name="moCode">工单号(仅落客製退料日志备查)</param>
/// <param name="fromStorage">供应仓对应线边仓的INVENTORYNO</param>
/// <param name="toStorage">收货仓,仅记录不入账</param>
/// <param name="dtReelInfo">料卷明细REELIDMCODEQTY</param>
public static bool ReelReturn(ref List<ArrayList> aryMessage, ref List<ArrayList> aryException,
string mvdCode, string moCode, string fromStorage, string toStorage,
string userCode, string mDate, string mTime, DataTable dtReelInfo)
{
bool ReelReturn = default(bool);
string strSQL = default(string);
IDbConnection cnnTemp = null;
AppSettings objSetting = new AppSettings();
var CollectionSQL = new Collection();
string strDataBaseType = objSetting.GetDataBaseType();
string strConnectionString = objSetting.GetConnectionString(strDataBaseType);
cnnTemp = CreateConnection(strConnectionString);
//同一料卷可能在REELINFO内出现多笔须逐笔累加扣减。
//因所有SQL累积到最后才一次提交若每笔都回资料库取现存量
//第二笔会取到未扣减前的数量而少扣,故在内存累计剩余量。
var dicLeftQty = new Dictionary<string, decimal>();
//以料卷为单位做扣减与快照时,保持 REELINFO 的出现顺序
var lstKeyOrder = new List<string>();
var dicMCode = new Dictionary<string, string>();
var dicReelId = new Dictionary<string, string>();
try
{
if (dtReelInfo.Rows.Count == 0)
{
throw new Exception("无明细数据!");
}
//操作日期与时间为数字栏,未传则存空值
string strMDate = mDate.Trim() == "" ? "null" : mDate.Trim();
string strMTime = mTime.Trim() == "" ? "null" : mTime.Trim();
for (int i = 0; i <= dtReelInfo.Rows.Count - 1; i++)
{
string strReelId = dtReelInfo.Rows[i]["REELID"].ToString();
string strMCode = dtReelInfo.Rows[i]["MCODE"].ToString();
string strKey = fromStorage + "|" + strMCode + "|" + strReelId;
//请求扣减量
decimal REQQTY = 0;
if (dtReelInfo.Rows[i]["QTY"].ToString() != "")
{
REQQTY = Convert.ToDecimal(dtReelInfo.Rows[i]["QTY"]);
}
if (REQQTY <= 0)
{
throw new Exception($"{strReelId}扣减数量不能为0或者负数");
}
//现存量:以仓别+物料+料卷三段键定位
decimal CURQTY = 0;
if (dicLeftQty.ContainsKey(strKey))
{
CURQTY = dicLeftQty[strKey];
}
else
{
DataTable dtRaw = new DataTable();
strSQL = $"select QTY from TBLINVWIPINVENTORY_RAW where INVENTORYNO = '{fromStorage}' and MATERIALNO = '{strMCode}' and MATERIALLOTNO = '{strReelId}'";
ExecuteSQLQuery_Adapter(strSQL, dtRaw, cnnTemp);
if (dtRaw.Rows.Count == 0)
{
throw new Exception($"{strReelId}在仓位{fromStorage}找不到对应的料卷!");
}
if (dtRaw.Rows[0]["QTY"].ToString() != "")
{
CURQTY = Convert.ToDecimal(dtRaw.Rows[0]["QTY"]);
}
}
//数量不够则清空、不用报错:实扣量最多只扣到现存量,
//不套用标准「保留负数」的写法,短扣差额由客製退料日志的请求量与实扣量留证
decimal REALQTY = REQQTY;
if (REQQTY > CURQTY)
{
REALQTY = CURQTY;
}
decimal LEFTQTY = CURQTY - REALQTY;
dicLeftQty[strKey] = LEFTQTY;
if (!lstKeyOrder.Contains(strKey))
{
lstKeyOrder.Add(strKey);
dicMCode[strKey] = strMCode;
dicReelId[strKey] = strReelId;
}
//① 写客製退料日志:逐笔记录请求量与实扣量,供短扣对帐;收货仓仅记录不入账
strSQL = @"INSERT INTO TBLINVREELRETURNLOG_LQ(MVDCODE, MOCODE, REELID, MCODE, FROMSTORAGE, TOSTORAGE, REQQTY, REALQTY, USERCODE, MDATE, MTIME, EVENTTIME) ";
strSQL += $" VALUES('{mvdCode}','{moCode}','{strReelId}','{strMCode}','{fromStorage}','{toStorage}',{REQQTY},{REALQTY},'{userCode}',{strMDate},{strMTime},To_Date('" + Strings.Format(DateTime.Now, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'))";
CollectionSQL.Add(strSQL);
}
//料卷日志与扣减以「料卷」为单位各做一次,不随 REELINFO 逐笔做:
//TBLINVWIPINVENTORY_RAWLOG 的主键是 (INVENTORYNO, MATERIALNO, MATERIALLOTNO, EVENTTIME)
//EVENTTIME 只到秒,同一料卷若在同批内写入多列快照必然撞主键 ORA-00001
//(规格 2.2 请求样例的 REELINFO 即同一 REELID 连续两笔)。
//且标准的 RAWLOG 语义本就是「变更后快照」=最终状态一列,故此处只留最终一列。
foreach (string strKey in lstKeyOrder)
{
string strMCode = dicMCode[strKey];
string strReelId = dicReelId[strKey];
decimal LEFTQTY = dicLeftQty[strKey];
//② 扣减线边仓现存量(累加扣减后的最终数量)
strSQL = $"UPDATE TBLINVWIPINVENTORY_RAW SET QTY = {LEFTQTY} WHERE INVENTORYNO = '{fromStorage}' AND MATERIALNO = '{strMCode}' AND MATERIALLOTNO = '{strReelId}'";
CollectionSQL.Add(strSQL);
//③ 写料卷日志(扣减后整列快照),必须排在删除资料列之前,否则删除后即无从取数
strSQL = @"INSERT INTO TBLINVWIPINVENTORY_RAWLOG(INVENTORYNO, MATERIALNO, MATERIALLOTNO, UNITNO, QTY, MATERIALTYPE, INPUTDATE,MANUFACTUREDATE,RECEIPTNO,REELID,EXDATE,EVENTTIME,DATECODE) ";
strSQL += " SELECT INVENTORYNO, MATERIALNO, MATERIALLOTNO, UNITNO, QTY, MATERIALTYPE, INPUTDATE,MANUFACTUREDATE,RECEIPTNO,REELID,EXDATE,To_Date('" + Strings.Format(DateTime.Now, "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'),DATECODE ";
strSQL += $" FROM TBLINVWIPINVENTORY_RAW WHERE INVENTORYNO = '{fromStorage}' AND MATERIALNO = '{strMCode}' AND MATERIALLOTNO = '{strReelId}'";
CollectionSQL.Add(strSQL);
//④ 扣光则删除资料列
if (LEFTQTY <= 0)
{
strSQL = $"DELETE FROM TBLINVWIPINVENTORY_RAW WHERE INVENTORYNO = '{fromStorage}' AND MATERIALNO = '{strMCode}' AND MATERIALLOTNO = '{strReelId}' AND QTY = 0";
CollectionSQL.Add(strSQL);
}
}
if (CollectionSQL.Count > 0)
{
ExecuteSQLNoneQuery_UPD(objSetting.GetDataBaseType(), objSetting.GetConnectionString(), CollectionSQL);
}
ReelReturn = true;
exitfun:
;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
CloseConnection(cnnTemp);
}
return ReelReturn;
}
#endregion
}
}