/// <summary> /// 进行批次报废操作。 /// </summary> /// <param name="dsParams"> /// 包含批次报废数据信息的数据集对象。 /// 必须包含名称为<see cref=" TRANS_TABLES.TABLE_PARAM"/>的数据表,用于存储批次主信息的数据。 /// 包含名称为<see cref=" WIP_SCRAP_FIELDS.DATABASE_TABLE_NAME"/>的数据表(可选),用于存储批次报废的数据。 /// </param> /// <returns>包含执行结果的数据集。</returns> public DataSet LotLossBonus(DataSet dsParams) { System.DateTime startTime = System.DateTime.Now; DataSet dsReturn = new DataSet(); DbConnection dbConn = null; DbTransaction dbTran = null; string lotKey = string.Empty, editor = string.Empty, editTimeZone = string.Empty, qty = string.Empty; try { dbConn = db.CreateConnection(); dbConn.Open(); //Create Transaction dbTran = dbConn.BeginTransaction(); #region CheckExpired 检查记录是否过期。防止重复修改。 if (dsParams.Tables.Contains(TRANS_TABLES.TABLE_PARAM)) { DataTable dtParams = dsParams.Tables[TRANS_TABLES.TABLE_PARAM]; Hashtable htParams = SolarViewer.Hemera.Share.Common.CommonUtils.ConvertToHashtable(dtParams); lotKey = htParams[POR_LOT_FIELDS.FIELD_LOT_KEY].ToString(); qty = htParams[WIP_TRANSACTION_FIELDS.FIELD_QUANTITY_OUT].ToString(); editor = htParams[WIP_TRANSACTION_FIELDS.FIELD_EDITOR].ToString(); editTimeZone = htParams[WIP_TRANSACTION_FIELDS.FIELD_EDIT_TIMEZONE_KEY].ToString(); string strEditTime = htParams[WIP_TRANSACTION_FIELDS.FIELD_EDIT_TIME].ToString(); KeyValuePair <string, string> kvp = new KeyValuePair <string, string>(POR_LOT_FIELDS.FIELD_LOT_KEY, lotKey); List <KeyValuePair <string, string> > listCondition = new List <KeyValuePair <string, string> >(); listCondition.Add(kvp); //如果记录过期,当前编辑时间<数据库中的记录编辑时间。结束方法执行。 if (UtilHelper.CheckRecordExpired(db, POR_LOT_FIELDS.DATABASE_TABLE_NAME, listCondition, strEditTime)) { SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, COMMON_FIELDS.FIELD_COMMON_EDITTIME_EXP); return(dsReturn); } } #endregion //进行报废数据收集。 WipManagement.SetLossBonus(db, dbTran, dsParams); //更新批次数量。 string sql = string.Format(@"UPDATE POR_LOT SET QUANTITY='{0}',EDITOR='{1}',EDIT_TIME=GETDATE(),EDIT_TIMEZONE='{2}' WHERE LOT_KEY='{3}'", qty.PreventSQLInjection(), editor.PreventSQLInjection(), editTimeZone.PreventSQLInjection(), lotKey.PreventSQLInjection()); db.ExecuteNonQuery(dbTran, CommandType.Text, sql); dbTran.Commit(); SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, ""); } catch (Exception ex) { SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, ex.Message); LogService.LogError("LotLossBonus Error: " + ex.Message); dbTran.Rollback(); } finally { dbConn.Close(); } System.DateTime endTime = System.DateTime.Now; LogService.LogInfo("LotLossBonus Time: " + (endTime - startTime).TotalMilliseconds.ToString()); return(dsReturn); }
/// <summary> /// 执行批次出站或仅采集批次报废数量。 /// </summary> /// <param name="dataset">包含批次出站信息的数据集对象。 /// 必须包含名称为<see cref=" TRANS_TABLES.TABLE_PARAM"/>的数据表,用于存储批次及批出站主信息的数据。 /// 包含名称为<see cref=" WIP_SCRAP_FIELDS.DATABASE_TABLE_NAME"/>的数据表(可选),用于存储批次报废的数据。 /// 包含名称为<see cref="WST_STORE_MAT_FIELDS.DATABASE_TABLE_NAME"/>的数据表(可选),用于存储批次返工或退库的数据。 /// 包含名称为<see cref="EMS_EQUIPMENTS_FIELDS.DATABASE_TABLE_NAME"/>的数据表(可选),用于存储设备数据。</param> /// <returns> /// 包含方法执行结果的数据集。 /// </returns> public DataSet TrackOutLot(DataSet dsParams) { System.DateTime startTime = System.DateTime.Now; DataSet dsReturn = new DataSet(); DbConnection dbConn = null; DbTransaction dbtran = null; DataTable dtParams = new DataTable(); Hashtable htParams = new Hashtable(); //string module = ""; int quantityOut = 0; int quantityToMerge = 0; string lotKeyForMerge = string.Empty; string lotKey = string.Empty; string workOrderKey = string.Empty, lineKey = "", editor = "", opUser = "", editTime = string.Empty; int workOrderStep = 0; //工单序号 string isAutoTrackIn = string.Empty, oprLine = string.Empty; //是否自动进站,操作线别 string shiftName = string.Empty; //班次名称 bool isFinished = false; //批次完成状态。 string toStepKey = string.Empty; //工步主键 string toRouteKey = string.Empty; //工艺流程主键 string toEnterpriseKey = string.Empty; //工艺流程组主键 string editTimeZone = string.Empty; //编辑时间时区 string operateCompName = string.Empty; //操作计算机名称 string shiftKey = string.Empty; //班次主键 string stepKey = string.Empty; //当前工步主键 try { dbConn = db.CreateConnection(); dbConn.Open(); //Create Transaction dbtran = dbConn.BeginTransaction(); if (dsParams.Tables.Contains(TRANS_TABLES.TABLE_PARAM)) { dtParams = dsParams.Tables[TRANS_TABLES.TABLE_PARAM]; htParams = SolarViewer.Hemera.Share.Common.CommonUtils.ConvertToHashtable(dtParams); lotKey = Convert.ToString(htParams[POR_LOT_FIELDS.FIELD_LOT_KEY]); lotKeyForMerge = lotKey; workOrderKey = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_WORK_ORDER_KEY]); lineKey = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_LINE_KEY]); oprLine = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_OPR_LINE]); editor = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_EDITOR]); opUser = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_OPERATOR]); shiftName = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_SHIFT_NAME]); editTime = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_EDIT_TIME]); toStepKey = Convert.ToString(htParams[WIP_FIELDS.FIELDS_TO_STEP_VER_KEY]); toRouteKey = Convert.ToString(htParams[WIP_FIELDS.FIELDS_TO_ROUTE_VER_KEY]); toEnterpriseKey = Convert.ToString(htParams[WIP_FIELDS.FIELDS_TO_ENTERPRISE_VER_KEY]); //module = Convert.ToString(htParams[POR_LOT_FIELDS.FIELD_MODULE]); editTimeZone = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_EDIT_TIMEZONE_KEY]); operateCompName = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_OPR_COMPUTER]); shiftKey = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_SHIFT_KEY]); stepKey = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_STEP_KEY]); //如果哈希表中包含最后一步的字段。表示该工步为最后一个工步,设置批次完成状态为true if (htParams.ContainsKey("LAST_STEP")) { isFinished = Boolean.Parse(htParams["LAST_STEP"].ToString()); } quantityOut = Convert.ToInt32(htParams[WIP_TRANSACTION_FIELDS.FIELD_QUANTITY_OUT]); quantityToMerge = quantityOut; } #region 检查记录是否过期。防止重复修改。 KeyValuePair <string, string> kvp = new KeyValuePair <string, string>(POR_LOT_FIELDS.FIELD_LOT_KEY, lotKey); List <KeyValuePair <string, string> > listCondition = new List <KeyValuePair <string, string> >(); listCondition.Add(kvp); //如果数据记录过期,则返回结束方法执行。 if (UtilHelper.CheckRecordExpired(db, POR_LOT_FIELDS.DATABASE_TABLE_NAME, listCondition, editTime)) { SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, COMMON_FIELDS.FIELD_COMMON_EDITTIME_EXP); return(dsReturn); } #endregion //如果数据集中包含批次报废数据表。 if (dsParams.Tables.Contains(WIP_SCRAP_FIELDS.DATABASE_TABLE_NAME)) { WipManagement.SetLossBonus(db, dbtran, dsParams); } //如果数据集中包含批次返工或退库的数据表。 if (dsParams.Tables.Contains(WST_STORE_MAT_FIELDS.DATABASE_TABLE_NAME)) { SetDefect(dbtran, dsParams); } //插入批次出站的记录信息。 WipManagement.TrackOutOrReworkLot(db, dbtran, dsParams, ACTIVITY_FIELD_VALUES.FIELD_ACTIVITY_TRACKOUT); //更新批次出站和设备关联的记录信息。 if (dsParams.Tables.Contains(EMS_EQUIPMENTS_FIELDS.DATABASE_TABLE_NAME)) { TrackOutOrReworkForEquipment(dbtran, dsParams); } #region 确定是否自动分批或自动合批 //如果不是完成状态且数量>0 if (isFinished == false && quantityOut > 0) { int maxBoxQuantity = -1; string autoMerge = ""; string autoSplit = ""; //获取下一工步的自定义属性。 DataSet dsStepUda = GetStepUda(toStepKey); if (dsStepUda.Tables[0].Rows.Count > 0) { //获取下一工步的自定义属性成功。 for (int i = 0; i < dsStepUda.Tables[0].Rows.Count; i++) { string szStepUdaName = dsStepUda.Tables[0].Rows[i][POR_ROUTE_STEP_ATTR_FIELDS.FIELD_ATTRIBUTE_NAME].ToString(); string szStepUdaValue = dsStepUda.Tables[0].Rows[i][POR_ROUTE_STEP_ATTR_FIELDS.FIELD_ATTRIBUTE_VALUE].ToString(); //箱的最大数量 if (szStepUdaName == "MaxBoxQuantity") { maxBoxQuantity = Convert.ToInt32(szStepUdaValue); } //自动合批 if (szStepUdaName == "AutoMerge") { autoMerge = szStepUdaValue; } //自动分批 if (szStepUdaName == "AutoSplit") { autoSplit = szStepUdaValue; } //自动出站 if (szStepUdaName == "AutoTrackIn") { isAutoTrackIn = szStepUdaValue; } } //确定自动分批 if (autoSplit.ToLower() == "true") { //箱最大数量 if (maxBoxQuantity == -1) { throw new Exception("${res:SolarViewer.Hemera.Addins.WIP.AutoSplit.Exception}"); } else if (quantityOut > maxBoxQuantity)//出站数量>箱最大数量。 { #region splitLot #region MainDataTable if (htParams.Contains(POR_LOT_FIELDS.FIELD_QUANTITY)) { htParams.Remove(POR_LOT_FIELDS.FIELD_QUANTITY); } htParams.Add(POR_LOT_FIELDS.FIELD_QUANTITY, maxBoxQuantity.ToString()); htParams[WIP_TRANSACTION_FIELDS.FIELD_QUANTITY_IN] = quantityOut; htParams[POR_LOT_FIELDS.FIELD_ROUTE_ENTERPRISE_VER_KEY] = toEnterpriseKey; htParams[POR_LOT_FIELDS.FIELD_CUR_ROUTE_VER_KEY] = toRouteKey; htParams[POR_LOT_FIELDS.FIELD_CUR_STEP_VER_KEY] = toStepKey; htParams.Add(POR_LOT_FIELDS.FIELD_STATE_FLAG, "0"); if (workOrderStep != 0) { htParams.Add(COMMON_FIELDS.FIELD_WORK_ORDER_STEP, workOrderStep); } DataTable splitTable = SolarViewer.Hemera.Share.Common.CommonUtils.ParseToDataTable(htParams); splitTable.TableName = TRANS_TABLES.TABLE_MAIN_DATA; DataSet splitDS = new DataSet(); splitDS.Tables.Add(splitTable); #endregion int remainderQty = quantityOut - maxBoxQuantity; #region ChildTable DataTable childTable = new DataTable(); //childTable.Columns.Add("LOT_NUMBER", Type.GetType("System.String")); childTable.Columns.Add("QUANTITY", Type.GetType("System.String")); childTable.Columns.Add("SPLIT_SEQ", Type.GetType("System.String")); childTable.Columns.Add("LOT_KEY", Type.GetType("System.String")); //string childLotNumber = ""; string lastChildLotKey = ""; int i = 0; //剩余数量-箱最大数量>0,继续分批 while ((remainderQty - maxBoxQuantity) >= 0) { #region GenerateChildLotNumber i++; #endregion //childTable.Rows.Add(childLotNumber, maxBoxQuantity.ToString(), i.ToString("00"), Utils.GenerateNewKey(0)); childTable.Rows.Add(maxBoxQuantity.ToString(), i.ToString("00"), UtilHelper.GenerateNewKey(0)); remainderQty = remainderQty - maxBoxQuantity; } //如果剩余数量>0,作为最后一批。 if (remainderQty > 0) { i++; lastChildLotKey = UtilHelper.GenerateNewKey(0); childTable.Rows.Add(remainderQty.ToString(), i.ToString("00"), lastChildLotKey); } childTable.TableName = BASE_PARAMETER_FIELDS.DATABASE_TABLE_NAME; splitDS.Tables.Add(childTable); #endregion //Excute Split //SplitLot(db, dbtran, splitDS); DataSet childLotReturn = new DataSet(); //执行分批操作。 SplitLotTransact(db, dbtran, splitDS, ref childLotReturn); quantityToMerge = remainderQty; lotKeyForMerge = lastChildLotKey; #endregion } } #region AutoMerge //如果自动合批。 if (autoMerge.ToLower() == "true") { //执行自动合批操作。 AutoMerge(db, dbtran, lotKeyForMerge, workOrderKey, toStepKey, lineKey, quantityToMerge.ToString(), maxBoxQuantity, 0, editor, false, oprLine, shiftName); } #endregion } } #endregion //检查是否需要进行锁定。 int nHoldCount = 0; if (isFinished == false) { nHoldCount = CheckAndUpdateFutureHold(dbtran, lotKey, stepKey, shiftName, shiftKey, editor, operateCompName, editTimeZone, ACTIVITY_FIELD_VALUES.FIELD_ACTIVITY_TRACKOUT); } dbtran.Commit(); SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, ""); #region AutoTrackIn 确定是否自动进站。 //如果自动进站 if (isFinished == false && isAutoTrackIn.ToLower() == "true" && nHoldCount == 0) { //执行自动进站作业。 AutoTrackIn(lotKey, string.Empty, shiftName); } #endregion } catch (Exception ex) { SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, ex.Message); LogService.LogError("TrackOutLot Error: " + ex.Message); dbtran.Rollback(); } finally { dbConn.Close(); } //记录操作时间 记录。 System.DateTime endTime = System.DateTime.Now; LogService.LogInfo("TrackOut Lot Time: " + (endTime - startTime).TotalMilliseconds.ToString()); return(dsReturn); }