schangxiang@126.com
2024-12-03 761aaf597639c55c6f36b03f3a89ba2d49a1d3f4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
using Admin.NET.Application;
using iWareCommon.Common.Globle;
using iWareCommon.Utils;
using iWareModel;
using iWareModel.EnumType.XiGangPublicCommon;
using iWareSql.DataAccess;
using iWareSql.DBModel;
using iWareSql.WmsDBModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XiGang.Core.Model;
 
 
namespace iWareCC.Common.Helper
{
    /// <summary>
    /// 增补创建的扩展帮助类 【EditBy shaocx,2022-02-05】
    /// </summary>
    public class MyExtendHelper
    {
 
        /// <summary>
        /// 处理 表 mes_order_gather
        /// </summary>
        /// <param name="wmsDB"></param>
        /// <param name="package"></param>
        /// <param name="qitaoValue"></param>
        /// <param name="_UnlinePerson"></param>
        /// <param name="errMsg"></param>
        /// <returns></returns>
        public static bool HandlerOrderGather(WmsDBModel wmsDB, mes_package_gather package, string qitaoValue, string _UnlinePerson, out string errMsg)
        {
            errMsg = "";
            //处理表  mes_order_gather
            if (package == null) {
                return true;
            }
            var isAddOrder = false;
            var packageList = wmsDB.mes_package_gather.Where(x => x.Info5 == package.Info5).ToList();
            if (packageList == null || packageList?.Count == 0)
            {
                errMsg = $"没有找到生产单号{package.Info5}的汇总数据";
                return false;
            }
            var order = wmsDB.mes_order_gather.Where(x => x.Info5 == package.Info5).FirstOrDefault();
            if (order != null)
            {
 
            }
            else
            {
                order = new mes_order_gather()
                {
                    Id = Yitter.IdGenerator.YitIdHelper.NextId(),
                    Info5 = package.Info5,
                    OrderId = package.OrderId,
                    PlanNo = package.PlanNo,
                };
                isAddOrder = true;
            }
            order.PackageNum = packageList.Count();
            order.UnLinePackageNum = packageList.Where(x => x.UpiStatus == (int)UpiStatusEnum.已下线).Count();
            order.NoUnLinePackageNum = order.PackageNum - order.UnLinePackageNum;
 
            order.AllPackageArea = packageList.Sum(x => Convert.ToDecimal(x.Info13));
            order.ScanPackageArea = packageList.Where(x => x.UpiStatus == (int)UpiStatusEnum.已下线).Sum(x => Convert.ToDecimal(x.Info13));
            order.NoScanPackageArea = order.AllPackageArea - order.ScanPackageArea;
            order.IsKitting = qitaoValue == "齐套" ? true : false;
 
            var order_unLine = false;
            //查询下一个包是不是属于该订单
            var newLineQueue = wmsDB.mes_package_linequeue.OrderBy(x => x.Id).FirstOrDefault();
            if (newLineQueue != null && newLineQueue.Info5 != order.Info5)
            {
                //表示是 切换 新订单了,该订单要更新为 已下线。
                order_unLine = true;
            }
            else
            {
                //判断该订单是否已下线
                if (order.PackageNum == order.UnLinePackageNum)
                {
                    order_unLine = true;
                }
            }
            //判断该订单是否已下线
            if (order_unLine)
            {
                order.IsUnline = true;
                order.UnlineTime = DateTime.Now;
                order.UnlinePerson = _UnlinePerson;
            }
            else
            {
                order.IsUnline = false;
            }
 
            if (isAddOrder)
            {
                wmsDB.mes_order_gather.Add(order);
            }
 
            return true;
        }
 
 
        /// <summary>
        /// 配置缺料原因
        /// </summary>
        /// <param name="oldRemark"></param>
        /// <param name="queliaoReason"></param>
        /// <returns></returns>
        public static string GetQueliaoReason(string oldRemark, string queliaoReason)
        {
            char splitStr = '|';
            var updateRemark = "缺料原因:" + queliaoReason;
            if (string.IsNullOrEmpty(oldRemark))
            {
                oldRemark = updateRemark + splitStr;
            }
            else
            {
                //解析字符串
                var arr = oldRemark.Split(splitStr);
                oldRemark = updateRemark + splitStr + arr.Last();
            }
            return oldRemark;
        }
 
        /// <summary>
        /// 清除缺料原因
        /// </summary>
        /// <param name="oldRemark"></param>
        /// <param name="queliaoReason"></param>
        /// <returns></returns>
        public static string CleareQueliaoReason(string oldRemark)
        {
            char splitStr = '|';
            if (string.IsNullOrEmpty(oldRemark))
            {
                return string.Empty;
            }
            else
            {
                //解析字符串
                var arr = oldRemark.Split(splitStr);
                oldRemark = arr.Last();
            }
            return oldRemark;
        }
 
        /// <summary>
        /// 设置强制完成信号
        /// </summary>
        /// <param name="srmStationCode"></param>
        /// <returns></returns>
        public static void SetSrm_IN_SMQZYZTG(EDevice device, bool value)
        {
            if (device == EDevice.一号堆垛机)
            {
                FormCC.Srm1_IN_SMQZYZTG = value;
            }
            else if (device == EDevice.二号堆垛机)
            {
                FormCC.Srm2_IN_SMQZYZTG = value;
            }
            else if (device == EDevice.三号堆垛机)
            {
                FormCC.Srm3_IN_SMQZYZTG = value;
            }
            else if (device == EDevice.四号堆垛机)
            {
                FormCC.Srm4_IN_SMQZYZTG = value;
            }
        }
 
        /// <summary>
        /// 根据堆垛机的入库口获取 输送线的站点号
        /// </summary>
        /// <param name="srmStationCode"></param>
        /// <returns></returns>
        public static string GetRgvStationCodeBySrm(EDevice device)
        {
            string stationCode = "";
            if (device == EDevice.一号堆垛机)
            {
                stationCode = "1002";
            }
            else if (device == EDevice.二号堆垛机)
            {
                stationCode = "1004";
            }
            else if (device == EDevice.三号堆垛机)
            {
                stationCode = "1006";
            }
            else if (device == EDevice.四号堆垛机)
            {
                stationCode = "1007";
            }
            return stationCode;
        }
 
        /// <summary>
        /// 四个入库口 扫描验证结果推送
        /// </summary>
        /// <param name="isReset"></param>
        /// <param name="handType"></param>
        /// <param name="stationCode"></param>
        /// <param name="plcTaskId"></param>
        /// <param name="value"></param>
        /// <param name="sysSalverCode"></param>
        /// <param name="scanCode"></param>
        public static bool WriteScanValidateACK(bool isReset, string handType, string stationCode, int plcTaskId, bool value, string sysSalverCode, string scanCode)
        {
            using (RgvService.RgvServiceClient clent = new RgvService.RgvServiceClient())
            {
                var res = clent.WriteScanValidateACK(isReset, (int)EDevice.RGV, stationCode, value, Convert.ToInt32(plcTaskId));
                if (res.result)
                {
                    Log4NetHelper.WriteInfoLog(iWareCommon.Utils.LogType.DataProcess_RobotBuffer_FinishTaskForOutbound, "HandlerLineInSacnResult 下发扫描验证下发成功,写入值value:" + value + ",stationCode:" + stationCode + ",PlcTaskId:" + plcTaskId + ",系统托盘号:" + sysSalverCode + ",扫描托盘号:" + scanCode + ",处理类型:" + handType);
                    return true;
                }
                else
                {
                    Log4NetHelper.WriteErrorLog(iWareCommon.Utils.LogType.DataProcess_RobotBuffer_FinishTaskForOutbound, "HandlerLineInSacnResult 下发扫描验证下发失败,写入值value:" + value + ",stationCode:" + stationCode + ",PlcTaskId:" + plcTaskId + ",系统托盘号:" + sysSalverCode + ",扫描托盘号:" + scanCode + ",处理类型:" + handType);
                    return false;
                }
            }
        }
 
        /// <summary>
        /// 托盘回收时,是否允许创建去1014的任务
        /// </summary>
        /// <param name="errMsg"></param>
        /// <returns>true:允许创建,false:不允许创建</returns>
        public static bool IsAllowSendTaskTo1014ByTPHS(ref string errMsg)
        {
 
            //增加验证,1009上两个光电有货,或 1010上其中一个光电有货,或 1011上一个光电有货,就先暂停不要下发去1014的任务,目的是为了优先让托盘回收的去1014位置,而不是立体库,挺高接怕 [EditBy shaocx,2022-05-01]
            EDevice rgvLocation = EDevice.空托缓存1009;
            var stationCode = Convert.ToInt32(rgvLocation).ToString();
            //bool isGD_HasCatogryForRgvStattion = MyExtendHelper.IsGD_HasCatogryForRgvStattionForPH_1(stationCode);
            bool isGD_HasCatogryForRgvStattion = MyExtendHelper.IsGD_HasCatogryForRgvStattion(stationCode);
            if (isGD_HasCatogryForRgvStattion)
            {
                errMsg = "1009显示PH_01光电有货,就暂时不创建从立体库去1014的任务,等着1009的托盘到了1011再定夺托盘区哪里";
                return false;
            }
            rgvLocation = EDevice.空托缓存1010;
            isGD_HasCatogryForRgvStattion = MyExtendHelper.IsGD_HasCatogryForRgvStattion(stationCode);
            if (isGD_HasCatogryForRgvStattion)
            {
                errMsg = "1010显示一个光电有货,就暂时不创建从立体库去1014的任务,等着1010的托盘到了1011再定夺托盘区哪里";
                return false;
            }
            rgvLocation = EDevice.空托缓存1011;
            isGD_HasCatogryForRgvStattion = MyExtendHelper.IsGD_HasCatogryForRgvStattion(stationCode);
            if (isGD_HasCatogryForRgvStattion)
            {
                errMsg = "1011显示一个光电有货,就暂时不创建从立体库去1014的任务";
                return false;
            }
            return true;
        }
 
        /// <summary>
        /// 根据1009站点的光电获取返回立体库的托盘数
        /// </summary>
        /// <returns></returns>
        public static int GetSalverStackCountForBackToStore()
        {
            var high3 = FormCC.rgvView.R_1009_High3;
            var high2 = FormCC.rgvView.R_1009_High2;
            var high1 = FormCC.rgvView.R_1009_High1;
 
            int count = 0;
            if (high1 && high2 && high3)
            {
                count = 3;
            }
            else if (high1 && high2 && !high3)
            {
                count = 2;
            }
            else if (high1 && !high2 && !high3)
            {
                count = 1;
            }
            return count;
        }
        /// <summary>
        /// 判断  出库的任务未完成的,超过了两个库区的设定
        /// </summary>
        /// <param name="context"></param>
        /// <param name="errMsg"></param>
        /// <returns>true:未超过限定 false:超过了限定</returns>
        public static bool IsNoFinishedOutTaskGroupbyArea(DbModel context, ref string errMsg)
        {
            var queryTaskType = (int)DeviceTaskTypeEnum.出库;
 
            var noFishisedList = context.Task_Part.Where(x => x.TaskType == queryTaskType &&
                (x.TaskState == (int)DeviceTaskStatusEnum.未开始 || x.TaskState == (int)DeviceTaskStatusEnum.已下发)
                && x.DeviceType == (int)EDeviceType.堆垛机
                ).ToList();
 
            if (noFishisedList == null || noFishisedList.Count == 0)
            {
                return true;
            }
            int num = noFishisedList.Select(x => x.DeviceId).Distinct().Count();
            if (num >= 2)
            {
                errMsg = "未结束的出库任务所占的库区,已经超过设定的值" + 2 + ",目前是:" + num;
                return false;
            }
            return true;
        }
 
        /*
        /// <summary>
        /// 是否条件允许做入库任务,只有当 当 没有出库计划,或者是 1012长时间被托盘占用的情况下 才允许分解组盘入库任务
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static bool IsAllowCreateTaskForInStore(DbModel context, ref string errMsg)
        {
            //查询状态=下发中的出库计划
            //注意:原则是优先执行出库任务
 
            var queryState2 = (int)MainTaskStatusEnum.待出库;
 
            //按照先 出库优先,再入库的原则来
            var mainList = context.Task_Main.Where(x => x.TaskState == queryState2).OrderBy(x => x.TaskSequence).ThenBy(x => x.CreateTime).ToList();//按照顺序号升序排列
            if (mainList != null && mainList.Count > 0)
            {//每次只处理一个
                if (FormCC.RGV_1012_HasCategory_COUNT > SysGloble.MAX_RGV_1012_HasCategory_COUNT)
                {//1012长时间被托盘占用的情况下 才允许分解组盘入库任务
                    return true;
                }
            }
            else
            {//只有当 没有出库计划,或者是 1012长时间被托盘占用的情况下 才允许分解组盘入库任务
                return true;
            }
            errMsg = "只有当 没有出库计划,或者是 1012长时间被托盘占用的情况下 才允许入库任务";
            return false;
        }
 
        //*/
 
        ///// <summary>
        ///// 是否有两个货物占用两个出库口,并且1012上显示有货
        ///// </summary>
        ///// <returns></returns>
        //public static bool IsHasTwoCatogryOnOutStationAndOn1012()
        //{
        //    //判断出库计划是否有两个出库口被货物占用了
        //    var _list = GetHasCatogryStationCodeAreaList();
        //    if (_list != null && _list.Count >= 2)
        //    {//说明有两个货物占用两个出库口
        //        var isHasCatogry_1012 = IsGD_HasCatogryForRgvStattion(((int)EDevice.出库口1012).ToString());
        //        if (isHasCatogry_1012)
        //        {
        //            return true;
        //        }
        //    }
        //    return false;
        //}
 
        /// <summary>
        /// 获取四个出库口 光电有货物占用的列表
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static List<string> GetHasCatogryStationCodeAreaList()
        {
            if (MyExtendHelper.IsAllowSimulatorHandle(null))
            {//如果是模拟,返回默认 [EditBy shaocx,2022-05-31]
                return new List<string>();
            }
            List<string> hasCatogryStationCodeAreaList = new List<string>();
            //优先从四个出库口目前未占用的地方出库
            var stationCode = ((int)EDevice.堆垛机1出库口1001).ToString();
            var isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isHasCatogry)
            {
                hasCatogryStationCodeAreaList.Add("1");
            }
            stationCode = ((int)EDevice.堆垛机2出库口1003).ToString();
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isHasCatogry)
            {
                hasCatogryStationCodeAreaList.Add("2");
            }
            stationCode = ((int)EDevice.堆垛机3出库口1005).ToString();
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isHasCatogry)
            {
                hasCatogryStationCodeAreaList.Add("3");
            }
            stationCode = ((int)EDevice.堆垛机4出库口1008).ToString();
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isHasCatogry)
            {
                hasCatogryStationCodeAreaList.Add("4");
            }
            return hasCatogryStationCodeAreaList;
        }
 
        /// <summary>
        /// 获取四个出库口 有出库任务未结束或有货物占用 的占用的列表
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static List<string> GetHasCatogryAndNoFinishedOutStoreTaskStationCodeAreaList(DbModel context, ref Dictionary<string, int> dict_hasNoFinishedOutStoreTaskStationCodeAreaList)
        {
            dict_hasNoFinishedOutStoreTaskStationCodeAreaList = new Dictionary<string, int>();
            List<string> hasNoFinishedOutStoreTaskStationCodeAreaList = new List<string>();
            if (MyExtendHelper.IsAllowSimulatorHandle(null))
            {//如果是模拟,返回默认 [EditBy shaocx,2022-05-31]
                return new List<string>();
            }
 
            //优先从四个出库口目前未占用的地方出库
            var stationCode = ((int)EDevice.堆垛机1出库口1001).ToString();
            var place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            bool isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);//判断堆垛机是否有出库任务未结束
            var isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry)
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("1");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("1", FormCC.RGV_1001_HasCategory_COUNT);
            }
            stationCode = ((int)EDevice.堆垛机2出库口1003).ToString();
            place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry)
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("2");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("2", FormCC.RGV_1003_HasCategory_COUNT);
            }
            stationCode = ((int)EDevice.堆垛机3出库口1005).ToString();
            place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry)
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("3");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("3", FormCC.RGV_1005_HasCategory_COUNT);
            }
            stationCode = ((int)EDevice.堆垛机4出库口1008).ToString();
            place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry)
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("4");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("4", FormCC.RGV_1008_HasCategory_COUNT);
            }
            return hasNoFinishedOutStoreTaskStationCodeAreaList;
        }
 
        public static List<string> GetHasCatogryAndNoFinishedOutStoreTaskStationCodeAreaListForOutSalver(DbModel context, ref Dictionary<string, int> dict_hasNoFinishedOutStoreTaskStationCodeAreaList)
        {
            dict_hasNoFinishedOutStoreTaskStationCodeAreaList = new Dictionary<string, int>();
            List<string> hasNoFinishedOutStoreTaskStationCodeAreaList = new List<string>();
            if (MyExtendHelper.IsAllowSimulatorHandle(null))
            {//如果是模拟,返回默认 [EditBy shaocx,2022-05-31]
                return new List<string>();
            }
 
            //优先从四个出库口目前未占用的地方出库
            var stationCode = ((int)EDevice.堆垛机1出库口1001).ToString();
            var place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            bool isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);//判断堆垛机是否有出库任务未结束
            var isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry || !IsKongXianForSrm(EDevice.一号堆垛机))
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("1");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("1", FormCC.RGV_1001_HasCategory_COUNT);
            }
            stationCode = ((int)EDevice.堆垛机2出库口1003).ToString();
            place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry || !IsKongXianForSrm(EDevice.二号堆垛机))
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("2");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("2", FormCC.RGV_1003_HasCategory_COUNT);
            }
            stationCode = ((int)EDevice.堆垛机3出库口1005).ToString();
            place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry || !IsKongXianForSrm(EDevice.三号堆垛机))
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("3");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("3", FormCC.RGV_1005_HasCategory_COUNT);
            }
            stationCode = ((int)EDevice.堆垛机4出库口1008).ToString();
            place = context.Base_Station.Where(x => x.RgvStationCode == stationCode).First();
            isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, place.Id);
            isHasCatogry = IsGD_HasCatogryForRgvStattion(stationCode);
            if (isExistOtherTaskDoing || isHasCatogry || !IsKongXianForSrm(EDevice.四号堆垛机))
            {
                hasNoFinishedOutStoreTaskStationCodeAreaList.Add("4");
                dict_hasNoFinishedOutStoreTaskStationCodeAreaList.Add("4", FormCC.RGV_1008_HasCategory_COUNT);
            }
            return hasNoFinishedOutStoreTaskStationCodeAreaList;
        }
 
        /// <summary>
        /// 判断堆垛机是否空闲
        /// </summary>
        /// <param name="devic"></param>
        private static bool IsKongXianForSrm(EDevice devic)
        {
            if (FormCC.srmViewDict[(int)devic].R_State == (int)ESrmState.空闲)
            {
                return true;
            }
            return false;
        }
 
 
        #region 寻找立体库中的空托,出库到1014位置
 
        /// <summary>
        /// 寻找立体库中的空托,出库到1014位置
        /// </summary>
        /// <param name="context"></param>
        /// <param name="outDetailTask"></param>
        /// <param name="errMsg"></param>
        public static V_Store FindStoreForEmptySalverTo1014(DbModel context, ref string errMsg)
        {
            var queryMaterialType = (int)MaterialTypeEnum.托盘;
            var findStoreList = context.V_Store.Where(x => x.MaterialType == queryMaterialType
                   && x.StationIsHasTaskDoing == false && x.StationIsLock == false
                   && x.StationIsDeleted == false).OrderBy(x => x.InStoreTime).ThenBy(x => x.Qty).ToList();//空托排序
            if (findStoreList == null || findStoreList.Count == 0)
            {
                errMsg = "未找到可用于到拆盘机入库的立体库空托盘库存";
                return null;
            }
            //注意:排除掉堆垛机不可用的 【EditBy shaocx,2022-04-16】
            findStoreList = StationHandler.FindPlacesFilterByBreakdown(findStoreList);//通过设备状态来过滤库位 [EditBy shaocx,2020-12-13]
            if (findStoreList == null || findStoreList.Count == 0)
            {
                errMsg = "未找到可用于到拆盘机入库的空托盘库存";
                return null;
            }
 
            #region 优先从四个出库口目前未占用的地方出库
            Dictionary<string, int> dict_hasNoFinishedOutStoreTaskStationCodeAreaList = new Dictionary<string, int>();
            List<string> hasCatogryStationCodeAreaList = GetHasCatogryAndNoFinishedOutStoreTaskStationCodeAreaListForOutSalver(context, ref dict_hasNoFinishedOutStoreTaskStationCodeAreaList);
 
            var resultStore = findStoreList.FirstOrDefault();
            if (hasCatogryStationCodeAreaList.Count == 0)
            {
                return resultStore;
            }
            else
            {
                var new_findStoreList = findStoreList.Where(x => !hasCatogryStationCodeAreaList.Contains(x.Area)).OrderBy(x => x.InStoreTime).ThenBy(x => x.Qty).ToList();//空托排序
                if (new_findStoreList == null || new_findStoreList.Count == 0)
                {
                    //无奈,只好排队了,先找有货秒数=0的那个 
                    var myArea = "";
                    foreach (var item in dict_hasNoFinishedOutStoreTaskStationCodeAreaList)
                    {
                        if (item.Value == 0)
                        {
                            myArea = item.Key;
                            break;
                        }
                    }
                    if (!string.IsNullOrEmpty(myArea))
                    {
                        resultStore = findStoreList.Where(x => x.Area == myArea).OrderBy(x => x.InStoreTime).ThenBy(x => x.Qty).First();//空托排序
                    }
                    else
                    {
                        //无奈,只好排队了,排队也要排最长的那个
                        var dict = dict_hasNoFinishedOutStoreTaskStationCodeAreaList.OrderByDescending(x => x.Value).First();//取排队时间最长的那个
                        resultStore = findStoreList.Where(x => x.Area == dict.Key).OrderBy(x => x.InStoreTime).ThenBy(x => x.Qty).First();//空托排序
                    }
 
                    return resultStore;
                }
                else
                {//找到最优的
                    return new_findStoreList.FirstOrDefault();
                }
            }
            #endregion
        }
 
        #endregion
 
        /// <summary>
        /// 是否允许给1014发送目标点是1014的任务
        /// </summary>
        /// <param name="context"></param>
        /// <param name="stationCode"></param>
        /// <param name="store"></param>
        /// <returns>true:允许,false:不允许</returns>
        public static bool IsAllowSendTaskToPlace1014(DbModel context, string stationCode, ref V_AllStore store)
        {
            var isGD_HasCatogryForRgvStattion = MyExtendHelper.IsGD_HasCatogryForRgvStattion(stationCode);
            var isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(stationCode);
            var isSys_HasCatogryForRgvStattion = MyExtendHelper.IsSys_HasCatogryForRgvStattion(context, stationCode, ref store);//1014上是否有系统库存
 
            var isExistOtherTaskDoingForDeviceTaskTypeEnum_立库空托到拆盘机入口 = PartTaskHandler.IsExistOtherTaskDoingForDeviceTaskTypeEnum(DeviceTaskTypeEnum.立库空托到拆盘机入口);
            var isExistOtherTaskDoingForDeviceTaskTypeEnum_空托转运到拆盘机入口 = PartTaskHandler.IsExistOtherTaskDoingForDeviceTaskTypeEnum(DeviceTaskTypeEnum.空托转运到拆盘机入口);
 
 
            if (!isSys_HasCatogryForRgvStattion && //没有系统库存
                !isGD_HasCatogryForRgvStattion &&  //光电显示无货
                !isExistOtherTaskDoing //没有其他任务占用
                && isExistOtherTaskDoingForDeviceTaskTypeEnum_立库空托到拆盘机入口 == false
                && isExistOtherTaskDoingForDeviceTaskTypeEnum_空托转运到拆盘机入口 == false
                )
            {
                return true;
            }
            return false;
        }
 
        /// <summary>
        /// 站点光电是否有货(只需要判断其中一个光电,就认为,有货)
        /// </summary>
        /// <param name="stationCode"></param>
        /// <returns>true:光电有货,false:光电无货</returns>
        public static bool IsGD_HasCatogryForRgvStattion(string stationCode)
        {
            if (FormCC.rgvView == null) return false;
            var rgv = FormCC.rgvView.R_RgvForReadCommList.Where(x => x.StationCode == stationCode).FirstOrDefault();
            if (rgv.R_PH_2 == true || rgv.R_PH_1 == true)
            {//只需要判断其中一个光电,就认为,有货
                return true;
            }
            return false;
        }
 
        /// <summary>
        /// 站点光电是否有货(两个光电必须全是有货)
        /// </summary>
        /// <param name="stationCode"></param>
        /// <returns>true:光电有货,false:光电无货</returns>
        public static bool IsGD_HasCatogryForRgvStattionFor2(string stationCode)
        {
            if (FormCC.rgvView == null) return false;
            var rgv = FormCC.rgvView.R_RgvForReadCommList.Where(x => x.StationCode == stationCode).FirstOrDefault();
            if (rgv.R_PH_1 == true && rgv.R_PH_2 == true)
            {//有货,两个光电必须全是有货
                return true;
            }
            return false;
        }
 
        /// <summary>
        /// 站点PH_1光电是否有货 (PH_1是指他的停止光电)
        /// </summary>
        /// <param name="stationCode"></param>
        /// <returns>true:光电有货,false:光电无货</returns>
        public static bool IsGD_HasCatogryForRgvStattionForPH_1(string stationCode)
        {
            if (FormCC.rgvView == null) return false;
            var rgv = FormCC.rgvView.R_RgvForReadCommList.Where(x => x.StationCode == stationCode).FirstOrDefault();
            if (rgv.R_PH_1 == true)
            {//PH_1有货
                return true;
            }
            return false;
        }
 
        /// <summary>
        /// 站点PH_2光电是否有货 (PH_2是指他的有货光电)
        /// </summary>
        /// <param name="stationCode"></param>
        /// <returns>true:光电有货,false:光电无货</returns>
        public static bool IsGD_HasCatogryForRgvStattionForPH_2(string stationCode)
        {
            var rgv = FormCC.rgvView.R_RgvForReadCommList.Where(x => x.StationCode == stationCode).FirstOrDefault();
            if (rgv.R_PH_2 == true)
            {//PH_2有货
                return true;
            }
            return false;
        }
 
        /// <summary>
        /// 站点系统是否有货
        /// </summary>
        /// <param name="stationCode"></param>
        /// <returns>true:系统有货,false:系统无货</returns>
        public static bool IsSys_HasCatogryForRgvStattion(DbModel context, string stationCode, ref V_AllStore store)
        {
            store = StoreHandler.GetV_AllStoreByRgvStationCode(context, stationCode);
            if (store != null)
            {//有货
                return true;
            }
            return false;
        }
 
        public static FunRetEntity DoHandler(DbModel context, V_AllStore store, EDevice rgvStationCode)
        {
            return null;
        }
 
        /// <summary>
        /// 判断任务是否允许模拟完成(虚拟模拟或者是强制完成模式)
        /// </summary>
        /// <param name="_task"></param>
        /// <returns></returns>
        public static bool IsAllowSimulatorHandle(Task_Part _task)
        {
            if (WCSConfigHelper.GetConfig_IsSimulationPLC())
            {
                return true;
            }
            if (_task != null && _task.IsAllowSimulateExecute == true)
            {
                return true;
            }
            return false;
        }
    }
}