Ejemplo n.º 1
0
        /// <summary>
        /// 执行批次进站作业。
        /// </summary>
        /// <param name="dsParams">
        /// 数据集对象。包含名称为<see cref="TRANS_TABLES.TABLE_PARAM"/>的数据表。
        /// 数据表中必须包含两个列"name"和"value"。列name存放哈希表的键名,列value存放哈希表键对应的键值。</param>
        /// <returns>
        /// 包含执行结果的数据集。
        /// 0:成功。-1或1:失败。 2:需要进行数据采集。
        /// </returns>
        public DataSet TrackInLot(DataSet dsParams)
        {
            DateTime      startTime         = DateTime.Now;
            DataSet       dsReturn          = new DataSet();
            string        sql               = "";
            DbConnection  dbconn            = null;
            DbTransaction dbtran            = null;
            string        lotKey            = "",
                          lineKey           = "",
                          workOrderKey      = "",
                          stepKey           = "",
                          quantityIn        = "",
                          user              = "",
                          editTime          = "",
                          lotNumber         = "",
                          strEquKey         = "",
                          strEquStateKey    = "",
                          strOperationKey   = "",
                          strIsBatch        = "",
                          maxQuantity       = "",
                          inProductQuantity = "",
                          isAutoTrackOut    = string.Empty,
                          oprLine           = string.Empty,
                          shiftName         = string.Empty,
                          lineName          = string.Empty,
                          editTimeZone      = string.Empty,
                          shiftKey          = string.Empty,
                          operateCompName   = string.Empty;

            try
            {
                dbconn = db.CreateConnection();
                dbconn.Open();
                //Create Transaction
                dbtran = dbconn.BeginTransaction();

                //如果数据集中包含TRANS_TABLES.TABLE_PARAM的数据表
                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();
                    lotNumber       = htParams[POR_LOT_FIELDS.FIELD_LOT_NUMBER].ToString();
                    lineKey         = htParams[WIP_TRANSACTION_FIELDS.FIELD_LINE_KEY].ToString();
                    workOrderKey    = htParams[WIP_TRANSACTION_FIELDS.FIELD_WORK_ORDER_KEY].ToString();
                    stepKey         = htParams[WIP_TRANSACTION_FIELDS.FIELD_STEP_KEY].ToString();
                    quantityIn      = htParams[WIP_TRANSACTION_FIELDS.FIELD_QUANTITY_IN].ToString();
                    user            = htParams[WIP_TRANSACTION_FIELDS.FIELD_EDITOR].ToString();
                    editTime        = htParams[WIP_TRANSACTION_FIELDS.FIELD_EDIT_TIME].ToString();
                    editTimeZone    = htParams[WIP_TRANSACTION_FIELDS.FIELD_EDIT_TIMEZONE_KEY].ToString();
                    oprLine         = htParams[WIP_TRANSACTION_FIELDS.FIELD_OPR_LINE].ToString();
                    shiftName       = htParams[WIP_TRANSACTION_FIELDS.FIELD_SHIFT_NAME].ToString();
                    lineName        = htParams[POR_LOT_FIELDS.FIELD_LINE_NAME].ToString();
                    shiftKey        = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_SHIFT_KEY]);
                    operateCompName = Convert.ToString(htParams[WIP_TRANSACTION_FIELDS.FIELD_OPR_COMPUTER]);
                }

                #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, 1, "数据已过期");
                    return(dsReturn);
                }
                #endregion

                DateTime dtCurrent = UtilHelper.GetSysdate(db);

                #region 检查设备
                //如果数据集合中包含EMS_EQUIPMENTS_FIELDS.DATABASE_TABLE_NAME数据表对象。
                if (dsParams.Tables.Contains(EMS_EQUIPMENTS_FIELDS.DATABASE_TABLE_NAME))
                {
                    DataTable equDataTable = dsParams.Tables[EMS_EQUIPMENTS_FIELDS.DATABASE_TABLE_NAME];
                    Hashtable equHashData  = SolarViewer.Hemera.Share.Common.CommonUtils.ConvertToHashtable(equDataTable);
                    strEquKey       = equHashData[EMS_EQUIPMENTS_FIELDS.FIELD_EQUIPMENT_KEY].ToString();
                    strOperationKey = equHashData[POR_ROUTE_OPERATION_VER_FIELDS.FIELD_ROUTE_OPERATION_VER_KEY].ToString();
                    //如果设备主键有值。
                    if (strEquKey != "" && strEquKey.Length > 0)
                    {
                        sql = @"SELECT a.ISBATCH,a.EQUIPMENT_STATE_KEY,a.MAXQUANTITY ,b.EQUIPMENT_STATE_TYPE,b.EQUIPMENT_STATE_NAME
                                FROM EMS_EQUIPMENTS a
                                LEFT JOIN EMS_EQUIPMENT_STATES b ON a.EQUIPMENT_STATE_KEY=b.EQUIPMENT_STATE_KEY
                                WHERE EQUIPMENT_KEY='" + strEquKey.PreventSQLInjection() + "'";
                        DataSet dsEqu = db.ExecuteDataSet(CommandType.Text, sql);//查询设备
                        //如果有数据。
                        if (dsEqu.Tables[0].Rows.Count > 0)
                        {
                            strIsBatch     = Convert.ToString(dsEqu.Tables[0].Rows[0][EMS_EQUIPMENTS_FIELDS.FIELD_ISBATCH]);                             //设备是否是批处理设备。
                            strEquStateKey = Convert.ToString(dsEqu.Tables[0].Rows[0][EMS_EQUIPMENTS_FIELDS.FIELD_EQUIPMENT_STATE_KEY]);                 //设备状态。
                            maxQuantity    = Convert.ToString(dsEqu.Tables[0].Rows[0][EMS_EQUIPMENTS_FIELDS.FIELD_MAXQUANTITY]);                         //最大数量。
                            string strEquStateName = Convert.ToString(dsEqu.Tables[0].Rows[0][EMS_EQUIPMENT_STATES_FIELDS.FIELD_EQUIPMENT_STATE_NAME]);  //设备状态名称。
                            string strEquStateType = Convert.ToString(dsEqu.Tables[0].Rows[0][EMS_EQUIPMENT_STATES_FIELDS.FIELD_EQUIPMENT_STATE_TYPE]);  //设备状态类型。
                            #region 检查设备状态
                            //如果设备状态不是“待产”
                            if (strEquStateType != "LOST")
                            {
                                //如果设备状态是“在产”
                                if (strEquStateType == "RUN")
                                {
                                    //如果是批处理设备。
                                    if (strIsBatch == "1")
                                    {
                                        //获取设备在产数量。
                                        sql = @"SELECT ISNULL(SUM(T.QUANTITY),0) AS INQUANTITY 
                                                FROM EMS_LOT_EQUIPMENT T
                                                WHERE T.EQUIPMENT_KEY = '" + strEquKey + "' AND T.END_TIMESTAMP IS NULL";
                                        DataSet dsLotEqu = db.ExecuteDataSet(CommandType.Text, sql);
                                        if (dsLotEqu.Tables[0].Rows.Count > 0 && !string.IsNullOrEmpty(maxQuantity))//获取设备在产数量成功
                                        {
                                            inProductQuantity = dsLotEqu.Tables[0].Rows[0]["inQuantity"].ToString();
                                            //在产数量>设备的最大数量,结束方法执行。
                                            if (Convert.ToInt32(inProductQuantity) + Convert.ToInt32(quantityIn) > Convert.ToInt32(maxQuantity))
                                            {
                                                SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, "${res:SolarViewer.Hemera.Modules.Wip.WipEngine.Msg.BigThenMaxQuantity}");
                                                return(dsReturn);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //如果不是批处理设备,结束方法执行。
                                        SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, "${res:SolarViewer.Hemera.Modules.Wip.WipEngine.Msg.BatchIsFalse}");
                                        return(dsReturn);
                                    }
                                }
                                else
                                {
                                    //如果设备状态不是在产,结束方法执行。
                                    SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, "${res:SolarViewer.Hemera.Modules.Wip.WipEngine.Msg.EquipmentCanNotUser}");
                                    return(dsReturn);
                                }
                            }
                            #endregion
                        }
                        else//获取设备数据失败。
                        {
                            SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, "${res:SolarViewer.Hemera.Modules.Wip.WipEngine.Msg.GetEquipmentError}");
                            return(dsReturn);
                        }
                    }
                }
                #endregion

                //批次进站,更新批次数据,插入批次进站操作记录。
                WipManagement.TrackInLot(db, dbtran, dsParams);
                //设备主键不为空。
                if (strEquKey != "")
                {
                    //批次和设备进行关联。
                    WipManagement.TrackInForEquipment(lotKey, Convert.ToInt32(quantityIn), strOperationKey, stepKey, strEquKey, user, dbtran);
                }

                #region 检查自动合批
                //工步主键不为空。
                if (stepKey != "")
                {
                    string  isLastStep     = "";
                    string  isAutoMerge    = "";
                    int     maxBoxQuantity = -1;
                    DataSet dsStepUda      = GetStepUda(stepKey);
                    //如果获取到工步自定义属性数据。
                    if (dsStepUda.Tables[0].Rows.Count > 0)
                    {
                        //遍历工序的自定义属性。
                        for (int i = 0; i < dsStepUda.Tables[0].Rows.Count; i++)
                        {
                            string szAttriName  = dsStepUda.Tables[0].Rows[i][POR_ROUTE_STEP_ATTR_FIELDS.FIELD_ATTRIBUTE_NAME].ToString();
                            string szAttriValue = dsStepUda.Tables[0].Rows[i][POR_ROUTE_STEP_ATTR_FIELDS.FIELD_ATTRIBUTE_VALUE].ToString();
                            //是否是最后一个工步。
                            if (szAttriName == "IsLastStep")
                            {
                                isLastStep = szAttriValue;
                            }
                            //是否自动合批。
                            if (szAttriName == "AutoMerge")
                            {
                                isAutoMerge = szAttriValue;
                            }
                            //箱子最大数量。
                            if (szAttriName == "MaxBoxQuantity" && !int.TryParse(szAttriValue, out maxBoxQuantity))
                            {
                                maxBoxQuantity = -1;
                            }
                            //是否自动出站。
                            if (szAttriName == "AutoTrackOut")
                            {
                                isAutoTrackOut = szAttriValue;
                            }
                        }
                        if (isAutoMerge.ToLower() == "true")//进行自动合批
                        {
                            AutoMerge(db, dbtran, lotKey, workOrderKey, stepKey, lineKey,
                                      quantityIn, maxBoxQuantity, 4, user, false, oprLine, shiftName);
                        }
                    }
                }

                #endregion

                #region 检查自动出站
                //自动出站
                if (isAutoTrackOut.ToLower() == "true")
                {
                    DataSet dsInfo = GetLotsInfo(dbtran, lotKey);
                    //获取批次信息成功。
                    if (dsInfo.Tables.Count > 0 && dsInfo.Tables[0].Rows.Count > 0)
                    {
                        string nextRunTime = string.Empty;
                        string sDuration   = Convert.ToString(dsInfo.Tables[0].Rows[0][POR_ROUTE_STEP_FIELDS.FIELD_DURATION]);
                        double duration    = 0;
                        if (!double.TryParse(sDuration, out duration))
                        {
                            duration = 0;
                        }
                        nextRunTime = dtCurrent.AddMinutes(duration).ToString("yyyy-MM-dd HH:mm:ss");
                        Hashtable hashWipJob = new Hashtable();
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_EDIT_TIMEZONE, editTimeZone);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_EDITOR, user);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_EDIT_TIME, dtCurrent);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_ENTERPRISE_KEY, dsInfo.Tables[0].Rows[0][POR_LOT_FIELDS.FIELD_ROUTE_ENTERPRISE_VER_KEY].ToString());
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_JOB_CREATETIME, dtCurrent);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_EQUIPMENT_KEY, strEquKey);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_JOB_CLOSETYPE, string.Empty);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_JOB_NEXTRUNTIME, nextRunTime);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_JOB_RUNACCOUNT, "0");
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_JOB_STATUS, "0");
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_JOB_TYPE, ACTIVITY_FIELD_VALUES.FIELD_ACTIVITY_TRACKIN);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_LINE_NAME, lineName);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_LOT_KEY, lotKey);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_LOT_NUMBER, lotNumber);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_NOTIFY_USER, string.Empty);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_ROUTE_KEY, dsInfo.Tables[0].Rows[0][POR_LOT_FIELDS.FIELD_CUR_ROUTE_VER_KEY]);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_ROW_KEY, UtilHelper.GenerateNewKey(0));
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_STEP_KEY, dsInfo.Tables[0].Rows[0][POR_LOT_FIELDS.FIELD_CUR_STEP_VER_KEY]);
                        hashWipJob.Add(WIP_JOB_FIELDS.FIELDS_WORKORDER_NUMBER, dsInfo.Tables[0].Rows[0][POR_WORK_ORDER_FIELDS.FIELD_ORDER_NUMBER]);
                        //插入一笔自动过站任务。
                        WipJobAutoTrack.InsertWipJob(db, dbtran, hashWipJob);
                    }
                }
                #endregion

                //检查是否需要进行数据采集。
                string edcPointKey = string.Empty;
                if (CheckNeedEdc(dbtran, lotKey, strEquKey, out edcPointKey))
                {
                    IEDCEngine edcEngine = RemotingServer.ServerObjFactory.Get <IEDCEngine>();
                    edcEngine.SaveEdcMainInfo(dbtran, lotKey, edcPointKey, user, strEquKey, oprLine, shiftKey);
                    SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, 2, "批次" + lotNumber + "需要抽检");
                }
                else
                {
                    //更新批次状态为9(WaitingForTrackout)
                    UpdateLotState(dbtran, lotKey, 9);
                    SolarViewer.Hemera.Share.Common.ReturnMessageUtils.AddServerReturnMessage(dsReturn, 0, string.Empty);
                }
                //检查是否需要进行锁定。
                CheckAndUpdateFutureHold(dbtran, lotKey, stepKey, shiftName, shiftKey, user,
                                         operateCompName, editTimeZone, ACTIVITY_FIELD_VALUES.FIELD_ACTIVITY_TRACKIN);

                dbtran.Commit();
            }
            catch (Exception ex)
            {
                ReturnMessageUtils.AddServerReturnMessage(dsReturn, 1, "批次进站出错" + ex.Message);
                LogService.LogError("TrackInLot Error: " + ex.Message);
                dbtran.Rollback();
            }
            finally
            {
                dbconn.Close();
            }
            System.DateTime endTime = System.DateTime.Now;
            LogService.LogInfo("TrackIn Lot Time: " + (endTime - startTime).TotalMilliseconds.ToString());
            return(dsReturn);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 检查批次是否需要进行数据采集。
        /// </summary>
        /// <param name="dbTrans"></param>
        /// <param name="lotKey">唯一标识批次的主键或批次号。</param>
        /// <param name="equipmentKey">唯一表示设备的主键。</param>
        /// <param name="edcpntKey">数据抽检设置主键。输出参数。</param>
        /// <returns>true:批次需要抽检。false:批次不需要抽检。</returns>
        private bool CheckNeedEdc(DbTransaction dbTrans, string lotKey, string equipmentKey, out string edcpntKey)
        {
            edcpntKey = string.Empty;
            DataSet dsLot = GetLotsInfo(dbTrans, lotKey);
            string  msg   = ReturnMessageUtils.GetServerReturnMessage(dsLot);

            if (!string.IsNullOrEmpty(msg))
            {
                throw new Exception(msg);
            }
            //获取批次信息
            DataTable  dtLot         = dsLot.Tables[0];
            string     routeKey      = dtLot.Rows[0][POR_LOT_FIELDS.FIELD_CUR_ROUTE_VER_KEY].ToString();      //工艺流程主键。
            string     stepKey       = dtLot.Rows[0][POR_LOT_FIELDS.FIELD_CUR_STEP_VER_KEY].ToString();       //工步主键
            string     oprLine       = dtLot.Rows[0][POR_LOT_FIELDS.FIELD_OPR_LINE].ToString();               //操作线别
            string     partNumber    = dtLot.Rows[0][POR_WORK_ORDER_FIELDS.FIELD_PART_NUMBER].ToString();     //成品号
            string     operationName = dtLot.Rows[0][POR_ROUTE_STEP_FIELDS.FIELD_ROUTE_STEP_NAME].ToString(); //工序名称
            IEDCEngine edcEngine     = RemotingServer.ServerObjFactory.Get <IEDCEngine>();
            Hashtable  hashTable     = new Hashtable();

            hashTable.Add(POR_WORK_ORDER_FIELDS.FIELD_PART_NUMBER, partNumber);
            hashTable.Add(POR_ROUTE_OPERATION_VER_FIELDS.FIELD_ROUTE_OPERATION_NAME, operationName);
            hashTable.Add(EDC_POINT_FIELDS.FIELD_ACTION_NAME, ACTIVITY_FIELD_VALUES.FIELD_ACTIVITY_TRACKOUT);
            hashTable.Add(EDC_POINT_FIELDS.FIELD_ROUTE_VER_KEY, routeKey);
            if (equipmentKey != string.Empty)
            {
                hashTable.Add(EMS_EQUIPMENTS_FIELDS.FIELD_EQUIPMENT_KEY, equipmentKey);
            }
            DataTable dataTable = new DataTable();

            dataTable = SolarViewer.Hemera.Share.Common.CommonUtils.ParseToDataTable(hashTable);
            //获取数据抽检点。
            DataSet dsEdcPoint = edcEngine.CheckEdc(dataTable);

            msg = SolarViewer.Hemera.Share.Common.ReturnMessageUtils.GetServerReturnMessage(dsEdcPoint);
            if (msg == string.Empty) //成功获取到数据抽检点集合。
            {
                string samplingKey = string.Empty;
                //获取的数据抽检点集合存在数据。
                if (dsEdcPoint.Tables.Count > 0 && dsEdcPoint.Tables[0].Rows.Count > 0)
                {
                    string edcPointKey = dsEdcPoint.Tables[0].Rows[0][EDC_POINT_FIELDS.FIELD_ROW_KEY].ToString();
                    //抽检参数没有满足条件的,则不进行抽检。
                    if (!edcEngine.CheckEDCPointParams(edcPointKey))
                    {
                        return(false);
                    }
                    string edcKey = dsEdcPoint.Tables[0].Rows[0][EDC_POINT_FIELDS.FIELD_EDC_KEY].ToString();
                    if (dsEdcPoint.Tables[0].Rows[0][EDC_POINT_FIELDS.FIELD_SP_KEY] != null)
                    {
                        samplingKey = dsEdcPoint.Tables[0].Rows[0][EDC_POINT_FIELDS.FIELD_SP_KEY].ToString();
                    }
                    bool blNeedSamp = false;
                    //获取当前工步是否有依赖的抽样工步。
                    string dependSampStep = GetStepUdaValue(db, stepKey, "DependSampStep");
                    //依赖的抽样工步不为空
                    if (dependSampStep != string.Empty && dependSampStep.Length > 0)
                    {
                        //检查是否进行了抽检。true 进行抽检,false没有进行抽检。
                        //如果该批次在依赖的抽样工步进行了抽检,则该批次在当前工步必须抽检。
                        blNeedSamp = edcEngine.CheckDependSampStep(lotKey, dependSampStep);
                    }
                    //依赖的抽样工步没有进行抽检 并且 依赖抽检的工步为空。
                    if (blNeedSamp == false && dependSampStep == string.Empty)
                    {
                        //如果抽样规则主键为空,则需要进行抽检。
                        if (samplingKey == string.Empty)
                        {
                            blNeedSamp = true;
                        }
                        else
                        {//如果抽样规则主键不为空,则需要根据抽检规则进行判断是否进行抽检。
                            blNeedSamp = edcEngine.CheckSampling(
                                lotKey,
                                stepKey,
                                dtLot.Rows[0][POR_LOT_FIELDS.FIELD_CUR_PRODUCTION_LINE_KEY].ToString(),
                                samplingKey,
                                ACTIVITY_FIELD_VALUES.FIELD_ACTIVITY_OUTEDC,
                                equipmentKey);
                        }
                    }
                    //上面判断需要进行抽检。
                    if (blNeedSamp)
                    {
                        edcpntKey = edcPointKey;
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            //批次不需要抽检
            return(false);
        }