From a93b0e99036c24b9bd58c79bf5e7364b1ba28bae Mon Sep 17 00:00:00 2001
From: 杨前锦 <1010338399@qq.com>
Date: 星期二, 01 七月 2025 16:02:33 +0800
Subject: [PATCH] 福建佳通-流程优化

---
 HH.WCS.Mobox3/HH.WCS.Mobox3.YNJT_PT/wms/WMSHelper.cs | 1156 ++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 682 insertions(+), 474 deletions(-)

diff --git a/HH.WCS.Mobox3/HH.WCS.Mobox3.YNJT_PT/wms/WMSHelper.cs b/HH.WCS.Mobox3/HH.WCS.Mobox3.YNJT_PT/wms/WMSHelper.cs
index f4dc478..69a9200 100644
--- a/HH.WCS.Mobox3/HH.WCS.Mobox3.YNJT_PT/wms/WMSHelper.cs
+++ b/HH.WCS.Mobox3/HH.WCS.Mobox3.YNJT_PT/wms/WMSHelper.cs
@@ -1,9 +1,12 @@
-锘縰sing HH.WCS.Mobox3.YNJT_PT.api;
+锘縰sing HH.WCS.Mobox3.YNJT_BZP_PT.models;
+using HH.WCS.Mobox3.YNJT_PT.api;
+using HH.WCS.Mobox3.YNJT_PT.dispatch;
 using HH.WCS.Mobox3.YNJT_PT.models;
 using HH.WCS.Mobox3.YNJT_PT.models.other;
 using HH.WCS.Mobox3.YNJT_PT.util;
 using Newtonsoft.Json;
 using NLog.Fluent;
+using SqlSugar;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -23,10 +26,10 @@
             var date = DateTime.Now.ToString("yyMMdd");
             return $"OP{date}{id.ToString().PadLeft(4, '0')}";
         }
-        internal static string GenerateSortingNo() {
-            var id = SYSHelper.GetSerialNumber("鍒嗘嫞鍗�, "SO");
+        internal static string GenerateTaskGroupNo() {
+            var id = SYSHelper.GetSerialNumber("浠诲姟缁�, "GP");
             var date = DateTime.Now.ToString("yyMMdd");
-            return $"SO{date}{id.ToString().PadLeft(4, '0')}";
+            return $"GP{date}{id.ToString().PadLeft(4, '0')}";
         }
         internal static List<WMSTask> GetOperationListByState(string state) {
             var db = new SqlHelper<object>().GetInstance();
@@ -77,130 +80,9 @@
             return result;
         }
 
-        internal static bool CreateSortingOrder(List<string> list) {
-            var res = false;
-            //閬嶅巻鑾峰彇鍙戣揣鍗曪紝鐒跺悗鍒ゆ柇搴撳瓨锛屽鏋滃叏閮芥病搴撳瓨锛屽垯涓嶇敓鎴愬垎鎷e崟锛屽鏋滄湁鐢熸垚鍒嗘嫞鍗�-            //鏇存柊娉㈡鍗曪紝鍗充娇鍙湁涓�釜鍙戣揣鍗曚篃鏇存柊娉㈡鍗�-            var db = new SqlHelper<object>().GetInstance();
-            var sortingOrderNo = "";
-            SortingOrder sortingOrder = null;
-            try {
-                db.BeginTran();
-                list.ForEach(a => {
-                    var so = db.Queryable<ShippingOrder>().Includes(s => s.Details).Where(s => s.S_NO == a).First();
-                    //鍒ゆ柇搴撳瓨锛屽彧鏈夊凡缁忓叆搴撶殑鎵嶅彲浠ヨ绠楋紝鐮佺洏鐨勪笉绠楋紝鍏ュ簱鍚庡嚭搴撻�涓殑涔熻璁$畻锛岀爜鐩樺悗榛樿鍙緟鍏ュ簱锛屽叆搴撳悗鍙甯�-                    //鐢熸垚鍑哄簱浠诲姟锛屽彧鏈夋墭鐩樹綅缃湪绔嬪簱鎵嶉渶瑕佸垱寤哄嚭搴撲换鍔★紙鍏堝啓姝荤珛搴擄級
-                    //鍙湁鍏ㄩ儴鍒嗘嫞瀹屾垚鎵嶅厑璁稿洖搴擄紙涓�釜鎵樼洏鍙兘瀵瑰簲澶氫釜鍒嗘嫞鏄庣粏锛�+        
 
-                    //鏌ユ壘浠撳簱閲忚〃鍜屽簱鍖洪噺琛紝鍑哄簱鍗曢渶瑕佸畾浣嶄粨搴撳拰搴撳尯浜嗭紝鍑哄簱瀹氫綅鐗╃悊搴撳尯灏辫锛屽叆搴撳彲鑳界墿鏂欏簱鍖鸿繕瑕佸尯鍒嗛�杈戝簱鍖�-
-                    //鏆傛椂鍙煡浠撳簱閲忚〃锛堥噺琛ㄥ浣曢噸缃紝鏌ユ壘鎵�湁鏌ユ壘C_ENABLE=N鐨勶紝鍒ゆ柇濡傛灉鍦ㄤ粨搴撲腑锛屾敼鎴怸锛岀劧鍚庣粺璁★級
-
-                    //鐢熸垚鍒嗘嫞鍗曟椂鍊欏鍔犱粨搴撻噺琛ㄥ垎閰嶉噺锛岀敓鎴愬垎鎷e崟鏄庣粏鏃跺�锛屽鍔犲簱鍖洪噺琛ㄥ垎閰嶉噺
-                    if (so != null && so.Details.Count > 0) {
-                        var fail = true;
-                        for (int i = 0; i < so.Details.Count; i++) {
-                            var whi = db.Queryable<WHInventory>().Where(w => w.S_ITEM_CODE == so.Details[i].S_ITEM_CODE).First();
-                            if (whi != null && whi.F_QTY - whi.F_ALLOC_QTY > 0) {
-                                //鏈夎揣灏卞嚭
-                                float qty = whi.F_QTY - whi.F_ALLOC_QTY > so.Details[i].F_QTY ? so.Details[i].F_QTY : whi.F_QTY - whi.F_ALLOC_QTY;
-                                fail = false;
-                                //鏈夊彲鐢ㄥ簱瀛橈紝鐢熸垚鍒嗘嫞鍗�-                                if (sortingOrderNo == "") {
-                                    sortingOrderNo = GenerateSortingNo();
-                                    sortingOrder = new SortingOrder
-                                    {
-                                        S_NO = sortingOrderNo,
-                                        S_SHIPPING_NO = so.S_NO,
-                                        Composes = new List<SortingCompose>()
-                                    };
-                                    //鍒涘缓鍒嗘嫞鍗�-                                    db.Insertable(sortingOrder).ExecuteCommand();
-                                }
-                                else {
-                                    //鑾峰彇鏈�柊鍒嗘嫞鍗�-                                    sortingOrder = db.Queryable<SortingOrder>().Includes(s => s.Composes).Where(s => s.S_NO == sortingOrderNo).First();
-                                    //鏇存柊鍒嗘嫞鍗曚腑鐨勫彂璐у崟鍗曞彿
-                                    sortingOrder.S_SHIPPING_NO = sortingOrder.S_SHIPPING_NO + ";" + so.S_NO;
-                                    sortingOrder.T_MODIFY = DateTime.Now;
-                                    db.Updateable(sortingOrder).UpdateColumns(it => new { it.S_SHIPPING_NO, it.T_MODIFY }).ExecuteCommand();
-                                }
-                                //鏌ヨ鍒嗘嫞鍗曞瓙琛紙姝e父鎯呭喌杩橀渶瑕佸鍔犳壒娆″垽鏂級
-                                var soc = db.Queryable<SortingCompose>().Where(s => s.S_ITEM_CODE == so.Details[i].S_ITEM_CODE && s.S_SORTING_NO == sortingOrder.S_NO).First();
-                                if (soc == null) {
-                                    soc = new SortingCompose
-                                    {
-                                        S_ITEM_CODE = so.Details[i].S_ITEM_CODE,
-                                        S_SORTING_NO = sortingOrder.S_NO,
-                                        F_QTY = qty,
-                                        N_ROW_NO = sortingOrder.Composes.Count() + 1,
-                                        S_BATCH_NO = so.Details[i].S_BATCH_NO
-                                    };
-
-                                    //鍒涘缓鍒嗘嫞鍗曞瓙琛�-                                    db.Insertable(soc).ExecuteCommand();
-                                }
-                                else {
-                                    soc.F_QTY += qty;
-                                    soc.T_MODIFY = DateTime.Now;
-                                    //鏇存柊鍒嗘嫞鍗曞瓙琛�-                                    db.Updateable(soc).UpdateColumns(it => new { it.F_QTY, it.T_MODIFY }).ExecuteCommand();
-                                }
-                                //鏇存柊浠撳簱閲忚〃鍒嗛厤閲�-                                whi.F_ALLOC_QTY += qty;
-                                whi.T_MODIFY = DateTime.Now;
-                                db.Updateable(whi).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
-                                //璺熸柊鍙戣揣鍗曞瓙琛ㄩ厤璐ф暟閲�-                                so.Details[i].F_ACC_D_QTY += qty;
-                                so.Details[i].T_MODIFY = DateTime.Now;
-                                db.Updateable(so.Details[i]).UpdateColumns(it => new { it.F_ACC_D_QTY, it.T_MODIFY }).ExecuteCommand();
-                            }
-
-                        }
-                        //鏇存柊鍙戣揣鍗曠姸鎬�-                        so.N_B_STATE = fail ? 5 : 1;
-                        if (fail) {
-                            so.S_NOTE = "娌℃湁搴撳瓨";
-                        }
-                        so.S_WAVE_CODE = sortingOrderNo;
-                        so.T_MODIFY = DateTime.Now;
-                        db.Updateable(so).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY, it.S_WAVE_CODE, it.S_NOTE }).ExecuteCommand();
-
-                    }
-
-
-                    //鏌ユ壘搴撳尯鍐呮墭鐩樼敓鎴愭墭鐩樻槑缁嗭紙鍖呮嫭鍒嗘嫞涓級鎬庝箞鍒ゆ柇搴撳唴锛熸煡鎵捐揣浣嶇粦瀹氾紵杩樻槸鎵樼洏涓婂姞鏍囪瘑姣旇緝濂斤紝濡傛灉鏄暣鎵樺嚭鐨勶紝鍒嗘嫞纭鍚庡幓鎺夊垎鎷f爣璇嗐�
-                    //1銆佸彧鏈夌爜鐩樺叆搴撳悗鐨勬墠闇�鍔犳爣璇嗭紝鍒嗘嫞鍥炵殑涓嶇敤锛屽垎鎷e洖鐨勬爣璇嗚繕鍦紝娌℃湁鍙樸�鍐欐鐮佺洏鍏ョ殑瀹屾垚鍚庡姞鏍囪瘑锛屾暣鎵樺垎鎷g殑鍘绘帀鏍囪瘑锛岄槻姝㈠悗闈㈤噸鏂扮爜鐩樿剰鏁版嵁
-                    //2銆佹垨鑰呭叧鑱旀煡璇㈠簱鍐呯殑锛屽彧缁欏垎鎷e嚭鐨勫姞鏍囪瘑锛屾瘡娆″垎鎷e洖鍐嶆妸鏍囪瘑娓呴櫎浜嗭紙濡傛灉涓嶆竻闄ゅ甫鏍囪瘑鐨勪細寰堝锛岃繕涓嶅鍏ㄩ儴鍔犳爣璇嗭級锛屾暣鎵樼殑娓呴櫎銆�-                    //缁煎悎閫夋嫨杩樻槸鏂规1锛岃繖鏍峰垱寤哄垎鎷f槑缁嗭紝鍙渶瑕佹墭鐩樼墿鏂欎袱琛ㄦ煡璇㈠氨鑳藉畾浣嶆墭鐩橈紙濡傛灉淇℃伅涓嶅噯锛屽彲浠ラ噸缃級锛屾柟妗�闇�璐т綅銆佹墭鐩樸�鐗╂枡涓夎〃鑱旀煡
-
-                    //鏆傛椂涓嶈搴撳尯锛屾爣璇嗙敤瀹瑰櫒琛�C_ENABLE 鏉ュ垽鏂紝琛ㄧず鑳戒笉鑳藉嚭搴�-
-                    //鎵ц鍒嗘嫞鍒涘缓浠诲姟锛岄亶鍘嗗垎鎷f槑缁嗕腑鐨勬墭鐩橈紝濡傛灉鍦ㄤ粨搴撳氨鍑哄簱锛屽鏋滀笉鍦ㄥ氨涓嶇敤鍑哄簱
-
-
-                });
-                //鍏ㄩ儴鍒嗘嫞鍗曠敓鎴愪箣鍚庡皢鍒嗘嫞鍗曠姸鎬佽缃负寮�閰嶈揣,娉㈡鍙蜂负鍙戣揣鍗�-                sortingOrder = db.Queryable<SortingOrder>().Where(s => s.S_NO == sortingOrderNo).First();
-                sortingOrder.N_B_STATE = 1;
-                sortingOrder.T_MODIFY = DateTime.Now;
-                db.Updateable(sortingOrder).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
-                db.CommitTran();
-                res = true;
-            }
-            catch (Exception ex) {
-                Console.WriteLine(ex.Message);
-                db.RollbackTran();
-            }
-            return res;
-
-        }
-
-        internal static List<SortingDetail> GetSortingDetailByCntr(string cntr) {
-            var db = new SqlHelper<object>().GetInstance();
-            var result = db.Queryable<SortingDetail>().Where(a => a.S_CNTR_CODE == cntr && a.N_B_STATE != 2).ToList();
-            return result;
-        }
+        
 
         internal static bool CreateWmsTask(WMSTask wmsTask) {
             try {
@@ -250,74 +132,7 @@
             var db = new SqlHelper<object>().GetInstance();
             return db.Queryable<WMSTask>().Where(a => a.S_CODE == code).First();
         }
-        /*
-        internal static void CreateSortingOrderDetail(string so_no) {
-            //鍒嗘嫞鍗曢厤璐�-            var db = new SqlHelper<object>().GetInstance();
-            var so = db.Queryable<SortingOrder>().Includes(a => a.Composes).Where(a => a.S_NO == so_no && (a.N_B_STATE == 1 || a.N_B_STATE == 20)).First();// 
-            if (so != null && so.Composes.Count > 0) {
-                db.BeginTran();
-                try {
-                    int rowNo = 1;
-                    so.Composes.ForEach(a => {
-                        //鎸夊垎鎷e崟瀛愯〃鍘婚厤璐э紝鏌ユ壘鍙敤鎵樼洏(鍏堟煡鎵�湁绗﹀悎鐨勶紝鍚庨潰鍐嶄紭鍖�
-                        var cirList = db.Queryable<CntrItemRel>().Includes(c => c.Cntr).Where(c => c.Cntr.C_ENABLE == "Y" && c.S_ITEM_CODE == a.S_ITEM_CODE && (c.F_QTY - c.F_ALLOC_QTY) > 0).OrderBy(c => c.T_CREATE).ToList();
-                        for (int i = 0; i < cirList.Count; i++) {
-                            var cir = cirList[i];
-                            var sd = new SortingDetail
-                            {
-                                N_ROW_NO = rowNo,
-                                S_BATCH_NO = a.S_BATCH_NO,
-                                S_ITEM_CODE = a.S_ITEM_CODE,
-                                S_CNTR_CODE = cir.S_CNTR_CODE,
-                                S_SORTING_NO = a.S_SORTING_NO
-                            };
-                            bool needBreak = false;
-                            if (cir.F_QTY - cir.F_ALLOC_QTY >= (a.F_QTY - a.F_ACC_S_QTY)) {
-                                //瀹瑰櫒鍙敤鏁伴噺澶т簬鍒嗘嫞鍗曞瓙琛ㄨ姹傜殑鏁伴噺锛岀敓鎴愬垎鎷f槑缁嗭紝鐒跺悗璺冲嚭寰幆
-                                sd.F_QTY = a.F_QTY - a.F_ACC_S_QTY;
-                                needBreak = true;
-                            }
-                            else {
-                                //鐢熸垚鍒嗘嫞鏄庣粏锛岀户缁垱寤�-                                sd.F_QTY = cir.F_QTY - cir.F_ALLOC_QTY;
-                            }
-                            db.Insertable(sd).ExecuteCommand();
-                            rowNo++;
-                            //鏇存柊瀹瑰櫒璐у搧琛ㄥ垎閰嶉噺
-                            cir.F_ALLOC_QTY += sd.F_QTY;
-                            cir.T_MODIFY = DateTime.Now;
-                            db.Updateable(cir).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
-                            //鏇存柊鍒嗘嫞鍗曞瓙琛ㄧ殑閲�-                            a.F_ACC_S_QTY += sd.F_QTY;
-                            a.T_MODIFY = DateTime.Now;
-                            db.Updateable(cir).UpdateColumns(it => new { it.F_ALLOC_QTY, it.T_MODIFY }).ExecuteCommand();
-                            if (needBreak) {
-                                break;
-                            }
-                        }
-                    });
-                    //鍏ㄩ儴鍒嗘嫞鍗曞瓙琛ㄧ敓鎴愬垎鎷f槑缁嗭紝淇敼鍒嗘嫞鍗曠姸鎬佷负閰嶈揣瀹屾垚(鍙嶆浠撳簱鐨勮揣鑳介厤鐨勯兘閰嶅畬浜嗭紝闄ら潪鏁版嵁鏈夊紓甯�
-                    so.N_B_STATE = 2;
-                    so.T_MODIFY = DateTime.Now;
-                    db.Updateable(so).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand();
-                    db.CommitTran();
-                }
-                catch (Exception ex) {
-                    Console.WriteLine(ex.Message);
-                    db.RollbackTran();
-                }
-            }
-        }
-        */
-        /// <summary>
-        /// 鑾峰彇寮�閰嶈揣鐨勫垎鎷e崟锛屼竴娆℃�鐢熸垚鍒嗘嫞鏄庣粏锛岄伩鍏嶇敓鎴愪竴鍗婂啀鐢熸垚锛屾墍浠ュ垱寤哄垎鎷f槑缁嗙殑鏃跺�鍔犱笂浜嬪姟
-        /// </summary>
-        /// <returns></returns>
-        internal static List<SortingOrder> GetWaitingSortingOrderList() {
-            var db = new SqlHelper<object>().GetInstance();
-            return db.Queryable<SortingOrder>().Includes(a => a.Composes).Where(a => a.N_B_STATE == 1 || a.N_B_STATE == 20).ToList();
-        }
+    
         /// <summary>
         /// 鑾峰彇閰嶈揣瀹屾垚鐨勫垎鎷e崟锛屾瘡涓垎鎷e崟鍗曠嫭鍒涘缓鍒嗘嫞浣滀笟
         /// </summary>
@@ -509,290 +324,683 @@
             return result;
         }
 
-        public static Location GetLocation4InEmptyRow()
+
+        // ----------------------------------------------- 鍗板凹浣抽� - 纭寲--------------------------------------------
+
+        /// <summary>
+        /// 娣诲姞鎴愬瀷鏈轰笅绾胯褰�+        /// </summary>
+        /// <param name="record"></param>
+        /// <returns></returns>
+        public static bool addOffLineRecord(OffLineRecord record) 
         {
-            Location result = null;
-            try
-            {
-                var db = new SqlHelper<object>().GetInstance();
-
-                #region 鏌ユ壘鎵�湁鏁伴噺鏄┖鐨勬帓
-                //Console.WriteLine("鏌ユ壘鎵�湁鏁伴噺鏄┖鐨勬帓");
-                //2.0 绠�寲鏌ヨ鍙煡姣忎竴鎺掔涓�垪
-                var list = db.Queryable<Location>().OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList();
-                //2.1 閫変竴涓┖鎺�-                for (int i = 0; i < list.Count; i++)
-                {
-                    var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == list[i].S_AREA_CODE && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE != "鏃�).First();
-                    if (list[i].N_LOCK_STATE == 0 && other == null)
-                    {
-                        //浜屾鏍¢獙褰撳墠鎺掓墍鏈夎揣浣嶉兘鏄┖鐨勶紝闃叉绯荤粺鏁版嵁閿欎贡
-                        var rowSumInfo = db.Queryable<Location>().Where(l => l.S_AREA_CODE == list[i].S_AREA_CODE && l.N_ROW == list[i].N_ROW && l.N_CURRENT_NUM != 0).Count();
-                        if (rowSumInfo == 0)
-                        {
-                            result = list[i];
-                            break;
-                        }
-                    }
-                }
-                #endregion
-
-                if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && (result.C_ENABLE == "绂佺敤" || result.C_ENABLE == "N")))
-                {
-                    //绂佺敤浜嗛�鎷╁悗闈竴涓揣浣�-                    Console.WriteLine("绂佺敤浜嗛�鎷╁悗闈竴涓揣浣�);
-                    result = db.Queryable<Location>().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == result.S_AREA_CODE && a.N_ROW == result.N_ROW && (string.IsNullOrEmpty(a.C_ENABLE) || (a.C_ENABLE != "绂佺敤" && a.C_ENABLE != "N")) && a.N_COL > result.N_COL).First();
-                }
-            }
-            catch (Exception ex)
-            {
-
-                LogHelper.Error("GetLocation4InEmptyRow:" + ex.Message, ex);
-            }
-            return result;
-        }
-
-        internal static Location GetInstockEnd(string item)
-        {
-            var db = new SqlHelper<object>().GetInstance();
-            Location end = null;
-            // 鏌ヨ鐩稿悓鐗╂枡鐨勬帓鏄惁鏈夊彲鏀捐揣鐨勫簱浣�-            var listMaxCol = db.Queryable<Location>()
-                 .LeftJoin<LocCntrRel>((l, lc) => l.S_CODE == lc.S_LOC_CODE)
-                 .LeftJoin<CntrItemRel>((l, lc, ci) => lc.S_CNTR_CODE == ci.S_CNTR_CODE)
-                 .Where((l, lc, ci) => l.N_CURRENT_NUM > 0 && ci.S_ITEM_CODE == item && l.S_AREA_CODE != Settings.BufferArea)
-                 .OrderByDescending((l, lc, ci) => l.N_COL).Take(1).PartitionBy((l, lc, ci) => l.N_ROW).ToList();
-
-            foreach (var loc in listMaxCol)
-            {
-                //鎺掓湁閿佷篃鎺掗櫎
-                var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == loc.S_AREA_CODE && a.N_ROW == loc.N_ROW && a.S_LOCK_STATE != "鏃� && a.N_LOCK_STATE != 0).First();
-                if (other != null)
-                {
-                   continue;
-                }
-
-                end = db.Queryable<Location>().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == loc.S_AREA_CODE && a.N_ROW == loc.N_ROW && a.N_CURRENT_NUM < a.N_CAPACITY && (string.IsNullOrEmpty(a.C_ENABLE) || (a.C_ENABLE != "绂佺敤" && a.C_ENABLE != "N")) && a.N_COL >= loc.N_COL).First();
-                if (end != null) { 
-                    return end;
-                }
-            }
-            // 濡傛灉娌℃湁锛屽垯闅忔満鏀剧┖鐨勬帓
-            if (end == null) {
-                end = GetLocation4InEmptyRow();
-            }
-            return end;
-        }
-
-        public static Location GetShiftStockStart(string area ,int row)
-        {
-            Location result = null;
-            try
-            {
-                // 1銆佹煡璇㈠綋鍓嶅簱鍖�鎺�鐗╂枡 鏈夋墭鐩樼殑璐т綅
-                var db = new SqlHelper<object>().GetInstance();
-                result = db.Queryable<Location>() 
-                    .Where(l => l.N_CURRENT_NUM > 0 && l.S_AREA_CODE == area && l.N_ROW == row && l.N_LOCK_STATE == 0 && (l.C_ENABLE != "绂佺敤" && l.C_ENABLE != "N"))
-                    .Includes(l => l.LocCntrRel, l => l.CntrItemRel)
-                    .OrderByDescending(l => l.N_COL)
-                    .First();
-            }
-            catch (Exception ex)
-            {
-                LogHelper.Error("GetShiftStockStart:" + ex.Message, ex);
-            }
-            return result;
-        }
-
-        public static Location GetShiftStockStart(string area)
-        {
-            Location result = null;
-            try
-            {
-                // 1銆佹煡璇㈠綋鍓嶅簱鍖�鎺�鐗╂枡 鏈夋墭鐩樼殑璐т綅
-                var db = new SqlHelper<object>().GetInstance();
-                var listMaxCol = db.Queryable<Location>()
-                    .Where(l => l.N_CURRENT_NUM > 0 && l.S_AREA_CODE == area)
-                    .Includes(l => l.LocCntrRel, l => l.CntrItemRel)
-                    .OrderByDescending(l => l.N_COL)
-                    .Take(1)
-                    .PartitionBy(l => l.N_ROW)
-                    .ToList();
-
-                foreach (var loc in listMaxCol)
-                {
-                    //鎺掓湁閿佷篃鎺掗櫎
-                    var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == loc.S_AREA_CODE && a.N_ROW == loc.N_ROW && a.S_LOCK_STATE != "鏃� && a.N_LOCK_STATE != 0).First();
-                    if (other != null)
-                    {
-                        continue;
-                    }
-                    return loc;
-                }
-            }
-            catch (Exception ex)
-            {
-                LogHelper.Error("GetShiftStockStart:" + ex.Message, ex);
-            }
-            return result;
-        }
-
-        public static bool isRowLock(Location location) {
-            var db = new SqlHelper<object>().GetInstance();
-            return  db.Queryable<Location>().Where(a => a.S_AREA_CODE == location.S_AREA_CODE && a.N_ROW == location.N_ROW && a.S_LOCK_STATE != "鏃� && a.N_LOCK_STATE != 0).Count() > 0;
-        }
-
-        public static Location GetShiftStockEnd(string area, int row)
-        {
-            Location result = null;
-
-            try
-            {
-                //1.0 鑾峰彇姣忎竴鎺掓渶澶х殑鍒�-                //1.1 鍒ゆ柇褰撳墠鏁伴噺鏄笉鏄弧鐨勶紝濡傛灉鏄弧鐨勫苟涓旀槸鏈�ぇ鍒楋紝闇�鎺掗櫎
-                var listMaxCol = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
-                //1.1 鏌ュ埌鎵�湁鏈夋墭鐩樼殑鎺�
-                Console.WriteLine("鏌ュ埌鎵�湁鏈夋墭鐩樼殑鎺�");
-                var db = new SqlHelper<object>().GetInstance();
-                var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area && a.N_ROW == row).Includes(a => a.LocCntrRel, a => a.CntrItemRel).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
-                if (list.Count > 0)
-                {
-                    //1.2 鏌ユ壘鍏跺畠灏哄鏈夋墭鐩樻垨鑰呴攣瀹氱殑鎺�-                    for (int i = list.Count - 1; i >= 0; i--)
-                    {
-                        //鎺掗櫎宸茬粡閿佸畾鐨勮揣浣�鍜�鏀炬弧浜嗕笖鏄渶澶у垪鐨勮揣浣�-                        if (list[i].N_LOCK_STATE != 0 || (list[i].N_CURRENT_NUM == list[i].N_CAPACITY && listMaxCol.Count(a => a.S_CODE == list[i].S_CODE) > 0))
-                        {
-                            Console.WriteLine($"鎺掗櫎宸茬粡閿佸畾鐨勮揣浣�鍜�鏀炬弧浜嗕笖鏄渶澶у垪鐨勮揣浣�鎺抺list[i].N_ROW}");
-                            list.Remove(list[i]);
-                        }
-                        else
-                        {
-                            //鎺掓湁閿佷篃鎺掗櫎
-                            var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE != "鏃� && a.N_LOCK_STATE != 0).First();
-                            if (other != null)
-                            {
-                                Console.WriteLine($"鎺掗櫎鏈夐攣鐨勬帓{list[i].N_ROW}");
-                                list.Remove(list[i]);
-                            }
-                        }
-                    }
-                    Console.WriteLine($"鏈夋墭鐩樻帓鏁颁负{list.Count}");
-                    if (list.Count > 0)
-                    {
-
-                        //1.3 閬嶅巻鍒ゆ柇鐗╂枡绫诲瀷鏄惁鐩稿悓
-                        Console.WriteLine("閬嶅巻鍒ゆ柇鐗╂枡绫诲瀷鏄惁鐩稿悓");
-                        for (int i = 0; i < list.Count; i++)
-                        {
-                            //todo 杩橀渶瑕佸垽鏂攣
-                            if (list[i].LocCntrRel != null && list[i].LocCntrRel.CntrItemRel != null)
-                            {
-                                if (list[i].N_CURRENT_NUM < list[i].N_CAPACITY)
-                                {
-                                    result = list[i];
-                                }
-                                else
-                                {
-                                    Console.WriteLine("閫夋嫨鍚庨潰绌轰綅");
-                                    result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL && a.C_ENABLE == "Y").OrderBy(a => a.N_COL).First();
-                                }
-
-                                if (result != null)
-                                {
-                                    break;
-                                }
-                            }
-
-                        }
-                    }
-                }
-
-                if (result == null) 
-                {
-                    #region 鏌ユ壘鎵�湁鏁伴噺鏄┖鐨勬帓
-                    //Console.WriteLine("鏌ユ壘鎵�湁鏁伴噺鏄┖鐨勬帓");
-                    //2.0 绠�寲鏌ヨ鍙煡姣忎竴鎺掔涓�垪
-                    list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList();
-                    //2.1 閫変竴涓┖鎺�-                    for (int i = 0; i < list.Count; i++)
-                    {
-                        var other = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.S_LOCK_STATE != "鏃�).First();
-                        if (list[i].N_LOCK_STATE == 0 && other == null)
-                        {
-                            //浜屾鏍¢獙褰撳墠鎺掓墍鏈夎揣浣嶉兘鏄┖鐨勶紝闃叉绯荤粺鏁版嵁閿欎贡
-                            var rowSumInfo = db.Queryable<Location>().Where(l => l.S_AREA_CODE == area && l.N_ROW == list[i].N_ROW && l.N_CURRENT_NUM != 0).Count();
-                            if (rowSumInfo == 0)
-                            {
-                                result = list[i];
-                                break;
-                            }
-                        }
-                    }
-                    #endregion
-                }
-
-                if (result != null && (!string.IsNullOrEmpty(result.C_ENABLE) && (result.C_ENABLE == "绂佺敤" || result.C_ENABLE == "N")))
-                {
-                    //绂佺敤浜嗛�鎷╁悗闈竴涓揣浣�-                    //Console.WriteLine("绂佺敤浜嗛�鎷╁悗闈竴涓揣浣�);
-                    result = db.Queryable<Location>().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE == area && a.N_ROW == result.N_ROW && (string.IsNullOrEmpty(a.C_ENABLE) || (a.C_ENABLE != "绂佺敤" && a.C_ENABLE != "N")) && a.N_COL > result.N_COL).First();
-                }
-            }
-            catch (Exception ex)
-            {
-                LogHelper.Error("GetLocation4InFinish:" + ex.Message, ex);
-            }
-            return result;
-        }
-
-
-        public static List<Location> GetLocationList(string area , int row) { 
-            List<Location> result = new List<Location> ();
-            try {
-                var db = new SqlHelper<object>().GetInstance();
-                result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == row).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList();
-            }
-            catch (Exception ex) {
-                    LogHelper.Error("GetLocationList:" + ex.Message, ex);
-            }
-            return result;
-        }
-
-        public static List<TN_YiKuDetail> getShiftOrderDetail(string orderNo = null) {
-            var db = new SqlHelper<object>().GetInstance();
-            List<TN_YiKuDetail> details = new List<TN_YiKuDetail>();
-            var orderList = db.Queryable<TN_YiKuOrder>().Where(a => a.S_B_STATE == "鎵ц").ToList();
-            foreach (var order in orderList)
-            {
-                var detail = db.Queryable<TN_YiKuDetail>().Where(a => order.S_NO == a.S_NO).First();
-                if (detail != null) 
-                {
-                    details.Add(detail);
-                }
-            }
-            return details;
-        }
-
-        public static bool updateShiftOrderDetail(TN_YiKuDetail detail) {
             bool result = false;
             var db = new SqlHelper<object>().GetInstance();
-            LogHelper.Info("绉诲簱瀹屾垚鏁伴噺鍙樻洿鍙傛暟锛� + JsonConvert.SerializeObject(detail), "TSSG");
-            result = db.Updateable<TN_YiKuDetail>()
-                .SetColumns(a => new TN_YiKuDetail() { N_COMPLETE_NUM = a.N_COMPLETE_NUM + 1 })
-                .Where(a => a.S_NO == detail.S_NO 
-                    && a.S_START_AREA == detail.S_START_AREA 
-                    && a.S_START_ROW == detail.S_START_ROW 
-                    && a.S_END_AREA == detail.S_END_AREA 
-                    && a.S_END_ROW == detail.S_END_ROW
-                    )
-                .ExecuteCommand() > 0;
-
-            var completeResult = db.Queryable<TN_YiKuDetail>().Where(a => a.S_NO == detail.S_NO && a.N_QTY > a.N_COMPLETE_NUM).Count() == 0;
-            if(completeResult) {
-                result = db.Updateable<TN_YiKuOrder>().SetColumns(a => new TN_YiKuOrder() { S_B_STATE = "瀹屾垚" }).Where(a => a.S_NO == detail.S_NO).ExecuteCommand() > 0;
+            var offLineRecord = db.Queryable<OffLineRecord>().Where(a => a.S_RFID == record.S_RFID).First();
+            if (offLineRecord != null)
+            {
+                offLineRecord.S_DEVICE_NO = record.S_DEVICE_NO;
+                offLineRecord.N_IS_URGENT = record.N_IS_URGENT;
+                offLineRecord.T_OFF_TIME = record.T_OFF_TIME;
+                offLineRecord.N_IS_FULL = record.N_IS_FULL;
+                result = db.Updateable(offLineRecord).ExecuteCommand() > 0;
+            }
+            else 
+            {
+                result = db.Insertable(record).ExecuteCommand() > 0;
             }
             return result;
         }
+
+        /// <summary>
+        /// 鏌ヨ鎴愬瀷鏈轰笅绾胯褰�+        /// </summary>
+        /// <param name="rfid"></param>
+        /// <returns></returns>
+        public static OffLineRecord getOffLineRecord(string rfid) 
+        {
+            OffLineRecord offLineRecord = null;
+            var db = new SqlHelper<object>().GetInstance();
+            if (rfid != null)
+            {
+                offLineRecord = db.Queryable<OffLineRecord>().Where(a => a.S_RFID == rfid).First();
+            }
+            return offLineRecord;
+        }
+
+        /// <summary>
+        /// 鏌ヨ鐗╂枡鏉$爜淇℃伅
+        /// </summary>
+        /// <param name="barcode"></param>
+        /// <returns></returns>
+        public static GreenTireInformation GetGreenTireInformation(string barcode) 
+        {
+            GreenTireInformation greenTireInformation = null;
+            var db = new SqlHelper<object>().GetInstance();
+            if (barcode != null)
+            {
+                greenTireInformation = db.Queryable<GreenTireInformation>().Where(a => a.BARCODE == barcode).First();
+            }
+            return greenTireInformation;
+        }
+
+        /*/// <summary>
+        /// 鏌ヨ鍏ュ簱缁堢偣璐т綅
+        /// 鍏ュ簱绛栫暐锛�+        /// 宸烽亾鍐呭悓瑙勬牸鏁伴噺 灏忎簬 10锛堟殏瀹氾級锛屾寜鐗╂枡鍧囪 璁$畻锛屽鏋滄墍鏈夌殑宸烽亾鍐呭悓瑙勬牸鏁伴噺閮藉ぇ浜�0锛屽垯鎸夌収宸烽亾鍧囪 璁$畻
+        /// </summary>
+        /// <param name="locNum">1.鍗曡揣浣�2.鍙岃揣浣�/param>
+        /// <returns></returns>
+        public static EndLocGroup getInStockEndLoc(int locNum , string itemCode) 
+        {
+            var db = new SqlHelper<object>().GetInstance();
+            EndLocGroup endLocGroup = new EndLocGroup();
+            List<Location> locations = new List<Location>();
+
+            List<int> roadwayList = new List<int>();
+
+            // 1.鎸夊贩閬撹繘琛屽垎缁勶紝鏌ヨ姣忎釜宸烽亾鍐呭悓瑙勬牸鐗╂枡鐨勬暟閲忥紝骞朵粠灏忓埌澶ф帓搴�+            var roadwayItemNumOrderGroup = db.Queryable<Location>()
+                .LeftJoin<LocCntrRel>((a,b) => a.S_CODE == b.S_LOC_CODE)
+                .LeftJoin<CntrItemRel>((a,b,c) => b.S_CNTR_CODE == c.S_CNTR_CODE)
+                .Where((a, b, c) => a.S_AREA_CODE == Settings.stockArea && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y" && c.S_ITEM_CODE == itemCode)
+                .GroupBy((a, b, c) => a.N_ROADWAY)
+                .Select((a, b, c) => new { roadway = a.N_ROADWAY, num = SqlFunc.AggregateCount(a.S_CODE) })
+                .OrderBy(a => a.num)
+                .ToList();
+
+            roadwayList = roadwayItemNumOrderGroup.Where(a => a.num < 10).OrderBy(a => a.num).Select(a => a.roadway).ToList();
+
+            // 2.鎸夊贩閬撹繘琛屽垎缁勶紝鏌ヨ姣忎釜宸烽亾绌鸿揣浣嶆暟閲忥紝骞朵粠澶у埌灏忔帓搴�+            if (roadwayList.Count == 0) 
+            {
+                var roadwayEmptyNumOrderGroup = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y")
+                    .GroupBy(a => a.N_ROADWAY)
+                    .Select(a => new { roadway = a.N_ROADWAY, num = SqlFunc.AggregateCount(a.S_CODE) })
+                    .OrderByDescending(a => a.num)
+                    .ToList();
+                roadwayList = roadwayEmptyNumOrderGroup.Select(a => a.roadway).ToList();
+            }
+
+            if (roadwayList.Count > 0) 
+            {
+                // 鏌ヨ鍗曡揣浣�+                foreach (var roadway in roadwayList)
+                {
+                    if (locNum == 1)
+                    {
+                        // 鏌ヨ绌鸿揣浣�+                        var emptyLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == roadway && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => new { a.N_LAYER, a.N_COL }).First();
+                        if (emptyLoc != null)
+                        {
+                            locations.Add(emptyLoc);
+                            endLocGroup.endLocList = locations;
+                            return endLocGroup;
+                        }
+                    }
+
+                    if (locNum == 2)
+                    {
+                        var emptyLocList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == roadway && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").OrderBy(a => new { a.N_LAYER, a.N_COL }).ToList();
+                        if (emptyLocList.Count > 0)
+                        {
+                            // 浼樺厛鏌ヨ鐩搁偦鍙屾嫋绌鸿揣浣�+                            if (locations.Count == 0)
+                            {
+                                foreach (var loc in emptyLocList)
+                                {
+                                    // 鏌ヨ鐩搁偦宸︿晶鏄惁鏈夌┖璐т綅
+                                    var leftLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == roadway && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL - 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First();
+                                    if (leftLoc != null)
+                                    {
+                                        locations.Add(loc);
+                                        locations.Add(leftLoc);
+                                        break;
+                                    }
+
+                                    // 鏌ヨ鐩搁偦鍙充晶鏄惁鏈夌┖璐т綅
+                                    var rightLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == Settings.stockArea && a.N_ROADWAY == roadway && a.N_ROW == loc.N_ROW && a.N_COL == loc.N_COL + 1 && a.N_LAYER == loc.N_LAYER && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.C_ENABLE == "Y").First();
+                                    if (rightLoc != null)
+                                    {
+                                        locations.Add(loc);
+                                        locations.Add(rightLoc);
+                                        break;
+                                    }
+                                }
+                            }
+
+                            if (locations.Count < locNum) 
+                            {
+                                // 鏌ヨ涓嶇浉閭荤殑鍗曟嫋璐т綅
+                                foreach (var loc in emptyLocList)
+                                {
+                                    locations.Add(loc);
+                                    if (locations.Count == locNum)
+                                    {
+                                        break;
+                                    }
+                                }
+                            }
+
+                            if (locations.Count == locNum)
+                            {
+                                endLocGroup.endLocList = locations;
+                                // 鏍¢獙璐т綅鏄惁鏄悓宸烽亾锛屾槸鍒欑敓鎴愪换鍔$粍鍙�+                                var groupNum = locations.GroupBy(a => a.N_ROADWAY).Count();
+                                if (groupNum == 1) 
+                                {
+                                    endLocGroup.groupNo = WMSHelper.GenerateTaskGroupNo();
+                                }
+                                return endLocGroup;
+                            }
+                        }
+                    }
+                }
+            }
+            return endLocGroup;
+        }*/
+
+        /// <summary>
+        /// 鏌ヨ鍏ュ簱缁堢偣璐т綅
+        /// 鍏ュ簱绛栫暐锛�+        /// 宸烽亾鍐呭悓瑙勬牸鏁伴噺 灏忎簬 10锛堟殏瀹氾級锛屾寜鐗╂枡鍧囪 璁$畻锛屽鏋滄墍鏈夌殑宸烽亾鍐呭悓瑙勬牸鏁伴噺閮藉ぇ浜�0锛屽垯鎸夌収宸烽亾鍧囪 璁$畻
+        /// </summary>
+        /// <param name="locNum"></param>
+        /// <param name="itemCode"></param>
+        /// <param name="roadway"></param>
+        /// <param name="excludeRoadway"></param>
+        /// <returns></returns>
+        public static EndLocGroup getInStockEndLoc(int locNum, string itemCode , int roadway = 0 ,int excludeRoadway = 0)
+        {
+            var db = new SqlHelper<object>().GetInstance();
+            EndLocGroup endLocGroup = new EndLocGroup { endLocList = new List<Location>() };
+
+            // 1. 鑾峰彇鍊欓�宸烽亾鍒楄〃锛堢墿鏂欏潎琛℃垨宸烽亾鍧囪 锛�+            List<int> candidateRoadways = new List<int>();
+            if (roadway == 0)
+            {
+                candidateRoadways = GetCandidateRoadways(db, itemCode);
+                if (candidateRoadways.Count == 0) return endLocGroup;
+
+                if (excludeRoadway != 0)
+                {
+                    candidateRoadways.Remove(excludeRoadway);
+                }
+            }
+            else 
+            {
+                candidateRoadways.Add(roadway);
+            }
+           
+
+            // 2. 澶勭悊鍗曡揣浣嶅叆搴�+            if (locNum == 1)
+            {
+                return FindSingleLocation(db, candidateRoadways);
+            }
+
+            // 3. 澶勭悊鍙岃揣浣嶅叆搴�+            return FindDoubleLocations(db, candidateRoadways);
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍊欓�宸烽亾鍒楄〃锛堟寜绛栫暐鎺掑簭锛�+        /// </summary>
+        private static List<int> GetCandidateRoadways(SqlSugarClient db, string itemCode)
+        {
+            var list = new List<int>();
+            // 绛栫暐1锛氬贩閬撳唴鍚岃鏍肩墿鏂�< 10 鐨勫贩閬擄紙鎸夋暟閲忓崌搴忥級
+            var materialRoadwayGroup = db.Queryable<Location>()
+                        // 琛ㄥ埆鍚嶏細a = Location, b = LocCntrRel, c = CntrItemRel
+                        .LeftJoin<LocCntrRel>((a, b) => a.S_CODE == b.S_LOC_CODE)
+                        .LeftJoin<CntrItemRel>((a, b, c) => b.S_CNTR_CODE == c.S_CNTR_CODE)
+
+                        // 鍩虹绛涢�鏉′欢锛堟墍鏈変綅缃級
+                        .Where((a, b, c) =>
+                            a.S_AREA_CODE == Settings.stockArea &&  // 鎸囧畾鍖哄煙
+                            a.N_LOCK_STATE == 0 &&                 // 鏈攣瀹�+                            a.C_ENABLE == "Y")                     // 鍚敤鐘舵�
+
+                        // 鎸夊贩閬撳垎缁勶紙浣跨敤鍘熷琛ㄥ瓧娈碉級
+                        .GroupBy((a, b, c) => a.N_ROADWAY)
+
+                        // 閫夋嫨鍒嗙粍缁撴灉锛堝寘鍚仛鍚堣绠楋級
+                        .Select((a, b, c) => new
+                        {
+                            Roadway = a.N_ROADWAY,  // 宸烽亾缂栧彿
+
+                            // 缁熻婊¤冻鐗瑰畾鏉′欢鐨勬暟閲忥細
+                            // 1. 褰撳墠鏁伴噺=1 (a.N_CURRENT_NUM == 1)
+                            // 2. 鐗╂枡鍖归厤 (c.S_ITEM_CODE == itemCode)
+                            // 3. 瀹瑰櫒鍏宠仈瀛樺湪 (b.S_CNTR_CODE != null)
+                            validCount = SqlFunc.AggregateSum(SqlFunc.IIF(
+                                a.N_CURRENT_NUM == 1 &&
+                                c.S_ITEM_CODE == itemCode &&
+                                b.S_CNTR_CODE != null,
+                                1, 0))
+                        })
+                       .ToList();
+
+            
+
+            if (materialRoadwayGroup.Count > 0)
+            {
+                list = materialRoadwayGroup.Where(a => a.validCount < 10).OrderBy(a => a.validCount).Select(a => a.Roadway).ToList();
+            }
+
+            if (list.Count == 0)
+            {
+                // 绛栫暐2锛氭墍鏈夊贩閬撴寜绌鸿揣浣嶆暟闄嶅簭鎺掑簭
+                materialRoadwayGroup = db.Queryable<Location>()
+                    .Where(a =>
+                        a.S_AREA_CODE == Settings.stockArea &&
+                        a.N_CURRENT_NUM == 0 &&
+                        a.N_LOCK_STATE == 0 &&
+                        a.C_ENABLE == "Y")
+                    .GroupBy(a => a.N_ROADWAY)
+                    .Select(a => new { Roadway = a.N_ROADWAY, validCount = SqlFunc.AggregateCount(a.S_CODE) })
+                    .ToList();
+
+                list = materialRoadwayGroup.OrderByDescending(a => a.validCount).Select(a => a.Roadway).ToList();
+            }
+            return list;
+        }
+
+        /// <summary>
+        /// 鏌ユ壘鍗曡揣浣�+        /// </summary>
+        private static EndLocGroup FindSingleLocation(SqlSugarClient db, List<int> candidateRoadways)
+        {
+            foreach (var roadway in candidateRoadways)
+            {
+                var location = db.Queryable<Location>()
+                    .Where(a =>
+                        a.S_AREA_CODE == Settings.stockArea &&
+                        a.N_ROADWAY == roadway &&
+                        a.N_CURRENT_NUM == 0 &&
+                        a.N_LOCK_STATE == 0 &&
+                        a.C_ENABLE == "Y")
+                    .OrderBy(a => a.N_LAYER)
+                    .OrderBy(a => a.N_COL)
+                    .First();
+
+                if (location != null)
+                {
+                    return new EndLocGroup
+                    {
+                        endLocList = new List<Location> { location }
+                    };
+                }
+            }
+            return new EndLocGroup();
+        }
+
+        /// <summary>
+        /// 鏌ユ壘鍙岃揣浣嶏紙浼樺寲鐩搁偦璐т綅鏌ユ壘锛�+        /// </summary>
+        private static EndLocGroup FindDoubleLocations(SqlSugarClient db, List<int> candidateRoadways)
+        {
+            // 鍏堝皾璇曟壘鐩搁偦璐т綅
+            foreach (var roadway in candidateRoadways)
+            {
+                // 涓�鎬ц幏鍙栧贩閬撴墍鏈夌┖璐т綅锛堝噺灏慏B鏌ヨ锛�+                var emptyLocs = db.Queryable<Location>()
+                    .Where(a =>
+                        a.S_AREA_CODE == Settings.stockArea &&
+                        a.N_ROADWAY == roadway &&
+                        a.N_CURRENT_NUM == 0 &&
+                        a.N_LOCK_STATE == 0 &&
+                        a.C_ENABLE == "Y")
+                    .OrderBy(a => a.N_LAYER)
+                    .OrderBy(a => a.N_COL)
+                    .ToList();
+
+                if (emptyLocs.Count < 2) continue;
+
+                // 鍦ㄥ唴瀛樹腑鏌ユ壘鐩搁偦璐т綅锛堥珮鎬ц兘锛�+                var adjacentPair = FindAdjacentLocations(emptyLocs);
+                if (adjacentPair != null)
+                {
+                    return CreateDoubleLocGroup(adjacentPair);
+                }
+            }
+
+            // 娌℃湁鐩搁偦璐т綅鏃讹紝鍙栦换鎰忎袱涓揣浣�+            foreach (var roadway in candidateRoadways)
+            {
+                var emptyLocs = db.Queryable<Location>()
+                    .Where(a =>
+                        a.S_AREA_CODE == Settings.stockArea &&
+                        a.N_ROADWAY == roadway &&
+                        a.N_CURRENT_NUM == 0 &&
+                        a.N_LOCK_STATE == 0 &&
+                        a.C_ENABLE == "Y")
+                    .OrderBy(a => a.N_LAYER)
+                    .OrderBy(a => a.N_COL)
+                    .Take(2)
+                    .ToList();
+
+                if (emptyLocs.Count == 2)
+                {
+                    return CreateDoubleLocGroup(emptyLocs);
+                }
+            }
+
+            return new EndLocGroup();
+        }
+
+        /// <summary>
+        /// 鍦ㄥ唴瀛樹腑鏌ユ壘鐩搁偦璐т綅锛堥珮鏁堢畻娉曪級
+        /// </summary>
+        private static List<Location> FindAdjacentLocations(List<Location> locations)
+        {
+            // 鎸夊眰->鍒楁帓搴忥紝渚夸簬鏌ユ壘鐩搁偦
+            var sorted = locations
+                .OrderBy(l => l.N_LAYER)
+                .ThenBy(l => l.N_ROW)
+                .ThenBy(l => l.N_COL)
+                .ToList();
+
+            for (int i = 0; i < sorted.Count - 1; i++)
+            {
+                var current = sorted[i];
+                var next = sorted[i + 1];
+
+                // 鍒ゆ柇鏄惁鍚屼竴灞備笖鐩搁偦鍒�+                if (current.N_LAYER == next.N_LAYER &&
+                    current.N_COL + 1 == next.N_COL)
+                {
+                    return new List<Location> { current, next };
+                }
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// 鍒涘缓鍙岃揣浣嶈繑鍥炵粨鏋�+        /// </summary>
+        private static EndLocGroup CreateDoubleLocGroup(List<Location> locations)
+        {
+            return new EndLocGroup
+            {
+                endLocList = locations,
+                groupNo = locations.GroupBy(a => a.N_ROADWAY).Count() == 1
+                    ? WMSHelper.GenerateTaskGroupNo()
+                    : null
+            };
+        }
+
+        public class EndLocGroup
+        {
+            public string groupNo { get; set; }
+            public List<Location> endLocList { get; set; }
+        }
+
+        /// <summary>
+        /// 鏌ヨ鍑哄簱寮�璐т綅
+        /// 1.璁$畻锛�.宸烽亾涓嶆姤璀︺�2.鐗╂枡鐘舵�OK銆�.灏忎簬澶辨晥鏃堕棿 澶т簬绛変簬鐢熸晥鏃堕棿 4.鍔犳�鏂欏厛鍑恒�5.鍏堝叆鍏堝嚭锛堢敓浜ф椂闂达級锛夊嚭搴撶墿鏂�+        /// 2.鍚岀瓑鏉′欢涓嬶紝浼樺厛鍙栧墠涓�墭璐х殑鐩搁偦璐т綅(鏆傛椂涓嶅仛鑰冭檻锛岄渶纭畾鍏堝叆鍏堝嚭锛堢敓浜ф椂闂达級鏄寜澶╃畻锛岃繕鏄簿纭埌鏃跺垎绉�
+        /// </summary>
+        /// <param name="itemCode"></param>
+        /// <param name="prevLoc"></param>
+        public static Location getOutStockStartLoc(string itemCode, Location prevLoc = null) 
+        {
+            var db = new SqlHelper<object>().GetInstance();
+            Location startLoc = null;
+
+            // 1.鏌ヨ锛堢墿鏂欑姸鎬丱K 锛屼笖灏忎簬澶辨晥鏃堕棿锛屽ぇ浜庣瓑浜庣敓鏁堟椂闂达級鍑哄簱鐗╂枡锛屽苟鎸夊姞鎬ユ枡鍏堝嚭锛屽厛鍏ュ厛鍑猴紙鐢熶骇鏃堕棿锛夌殑鍘熷垯杩涜鎺掑簭
+            var query = db.Queryable<Location>()
+               .LeftJoin<LocCntrRel>((a, b) => a.S_CODE == b.S_LOC_CODE)
+               .LeftJoin<CntrItemRel>((a, b, c) => b.S_CNTR_CODE == c.S_CNTR_CODE)
+               .Where((a, b, c) => a.S_AREA_CODE == Settings.stockArea
+                               && a.N_CURRENT_NUM == 1
+                               && a.N_LOCK_STATE == 0
+                               && a.C_ENABLE == "Y"
+                               && b.S_CNTR_CODE != null
+                               );
+
+            if (itemCode != null)
+            {
+                query = query.Where((a, b, c) => c.S_ITEM_CODE == itemCode
+                               && c.S_ITEM_STATE == "OK"
+                               && SqlFunc.ToDate(c.S_EFFECTIVE_TIME) <= SqlFunc.GetDate()  // 鐢熸晥鏃堕棿鏃╀簬褰撳墠鏃堕棿
+                               && SqlFunc.ToDate(c.S_EXPIRATION_TIME) >= SqlFunc.GetDate() // 澶辨晥鏃堕棿鏅氫簬褰撳墠鏃堕棿
+                               && c.S_EFFECTIVE_TIME != null
+                               && c.S_EXPIRATION_TIME != null)
+                            .OrderByDescending((a, b, c) => c.N_URGENT_FLAG)
+                            .OrderBy((a, b, c) => c.S_TXNDATE);
+            }
+            else 
+            {
+                query = query.Where((a, b, c) => c.S_ITEM_CODE == itemCode);
+            }
+            query = query.OrderByDescending((a, b, c) => a.N_ROADWAY == prevLoc.N_ROADWAY);
+            var outLocList = query.ToList();
+
+            if (outLocList.Count > 0)
+            {
+                foreach (var loc in outLocList)
+                {
+                    // 鏌ヨ宸烽亾鏄惁姝e父锛屽紓甯歌烦杩�+                    var deviceConfig = Settings.deviceConfigList.Where(a => a.roadway == loc.N_ROADWAY).First();
+                    if (deviceConfig != null) 
+                    {
+                        var stackerStates = WCSDispatch.getDeviceStatus(new List<string>() { deviceConfig.deviceNo } );
+                        if ( stackerStates.Count == 0 || stackerStates[0].workStatus != 1 || stackerStates[0].manualStatus == 1 )
+                        {
+                            continue;
+                        }
+                    }
+                    startLoc = loc;
+                    break;
+                }
+            }
+            return startLoc;
+
+        }
+
+        public class StartLocGroup
+        {
+            public string groupNo {  get; set; }
+            public List<Location> startLocList { get; set; }
+        }
+
+        /// <summary>
+        /// 鏌ヨ寮傚父鍖虹┖璐т綅
+        /// </summary>
+        /// <param name="areaCode"></param>
+        public static Location getAbnormalAreaEmptyLoc(string areaCode) 
+        {
+            Location location = new Location();
+            var db = new SqlHelper<object>().GetInstance();
+            location = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaCode && a.N_CURRENT_NUM == 0 && a.C_ENABLE == "Y" && a.N_LOCK_STATE == 0).First();
+            return location;
+        }
+
+        /// <summary>
+        /// 鏌ヨ宸烽亾浠诲姟鏈�皯鐨勬帴椹充綅
+        /// </summary>
+        /// <returns></returns>
+        public static Location getMinTaskMiddleLoc(int type , int roadway = 0 , int excludeRoadway = 0) 
+        {
+            Location location = new Location();
+            var db = new SqlHelper<object>().GetInstance();
+
+            var query = db.Queryable<Location>()
+                    .LeftJoin<WCSTask>((a, b) => a.S_CODE == b.S_END_LOC && b.N_B_STATE < 3)
+                    .Where((a, b) => a.S_AREA_CODE == Settings.stockArea);
+
+            if (roadway != 0) 
+            {
+                query = query.Where((a, b) => a.N_ROADWAY == roadway);
+            }
+            if (excludeRoadway != 0) 
+            {
+                query = query.Where((a, b) => a.N_ROADWAY != excludeRoadway);
+            }
+
+            var roadwayGroup = query.GroupBy((a, b) => a.N_ROADWAY)
+                    .Select((a, b) => new { roadway = a.N_ROADWAY, num = SqlFunc.AggregateDistinctCount(b.S_CODE != null) })
+                    .OrderBy(a => a.num)
+                    .ToList();
+
+            foreach (var item in roadwayGroup)
+            {
+                var connectLoc = Settings.connectLocList.Where(a => a.roadway == item.roadway).FirstOrDefault();
+                if (connectLoc != null) 
+                {
+                    location = LocationHelper.GetLoc(connectLoc.locCode);
+                    break;
+                }
+            }
+            return location;
+        }
+
+        /// <summary>
+        /// 鏌ヨ涓婄嚎璐т綅
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static Location getOnlneLoc(int type)
+        {
+            Location location = null;
+            var connectLoc = Settings.onLineLocList.Where(a => a.type == type).FirstOrDefault();
+            if (connectLoc != null)
+            {
+                location = LocationHelper.GetLoc(connectLoc.locCode);
+            }
+            return location;
+        }
+
+        /// <summary>
+        /// 鏌ヨ鍙枡寮傚父鎺掑嚭浣�+        /// </summary>
+        /// <param name="row"></param>
+        /// <returns></returns>
+        public static Location getCallOutLoc(int row)
+        {
+            Location location = null;
+            var connectLoc = Settings.callOutLocList.Where(a => a.row == row).FirstOrDefault();
+            if (connectLoc != null)
+            {
+                location = LocationHelper.GetLoc(connectLoc.locCode);
+            }
+            return location;
+        }
+
+        /// <summary>
+        /// 鏌ヨ鐗╂枡瀛樻斁鏃堕棿閰嶇疆淇℃伅
+        /// </summary>
+        /// <param name="bc_entried"></param>
+        /// <returns></returns>
+        public static Overage getOverage(string bc_entried)
+        {
+
+            var db = new SqlHelper<object>().GetInstance();
+
+            // 鐩存帴鎵ц SQL锛堝弬鏁板寲鏌ヨ锛�+            var sql = "SELECT get_ovg_bar(@barcode, @mcngrp) AS overage_value";
+            var sql1 = "SELECT get_minhour_bar(@barcode, @mcngrp) AS overage_value";
+
+            // 浣跨敤鍖垮悕瀵硅薄浼犻�鍙傛暟
+            var ovg_bar = db.Ado.SqlQuery<int>(sql, new { barcode = bc_entried, mcngrp = "0" });
+            var minhour_bar = db.Ado.SqlQuery<float>(sql1, new { barcode = bc_entried, mcngrp = "0" });
+            if (ovg_bar.Count > 0 && minhour_bar.Count > 0)
+            {
+                Overage overage = new Overage()
+                {
+                    MINHOUR = minhour_bar[0],
+                    OVERAGE = ovg_bar[0]
+                };
+                return overage;
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// 缁戝畾鏉$爜鐗╂枡淇℃伅
+        /// </summary>
+        /// <param name="cntrCode"></param>
+        /// <param name="greenTireInformation"></param>
+        /// <returns></returns>
+        public static bool bindBarcodeItemInfo( string cntrCode,GreenTireInformation greenTireInformation) 
+        {
+            bool result = false;
+            var db = new SqlHelper<object>().GetInstance();
+            var cntrItemRel = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrCode).First();
+            if (cntrItemRel == null)
+            {
+                var overage = getOverage(greenTireInformation.BARCODE);
+                DateTime txndate = DateTime.Parse(greenTireInformation.TXNDATE);
+                DateTime minTime = txndate.AddHours(overage.MINHOUR);
+                DateTime maxTime = txndate.AddDays(overage.OVERAGE);
+                cntrItemRel = new CntrItemRel()
+                {
+                    S_CG_ID = greenTireInformation.BARCODE,
+                    S_ITEM_CODE = greenTireInformation.ITEMCODE,
+                    S_CNTR_CODE = cntrCode,
+                    S_CELL_NO = greenTireInformation.TIRECODE,
+                    F_QTY = greenTireInformation.QTY,
+                    S_MCN = greenTireInformation.MCN,
+                    S_OPR = greenTireInformation.OPR,
+                    S_OPR02 = greenTireInformation.OPR02,
+                    S_OPR03 = greenTireInformation.OPR03,
+                    S_OPR04 = greenTireInformation.OPR04,
+                    S_WINDUP = greenTireInformation.WINDUP,
+                    S_TXNDATE = greenTireInformation.TXNDATE,
+                    S_DATE_SHIFT = greenTireInformation.DATE_SHIFT,
+                    S_EFFECTIVE_TIME = minTime.ToString("yyyy-MM-dd HH:mm:ss"),
+                    S_EXPIRATION_TIME = maxTime.ToString("yyyy-MM-dd HH:mm:ss"),
+                };
+                result = db.Insertable(cntrItemRel).ExecuteCommand() > 0;
+            }
+            else 
+            {
+                var overage = getOverage(greenTireInformation.BARCODE);
+                DateTime txndate = DateTime.Parse(greenTireInformation.TXNDATE);
+                DateTime minTime = txndate.AddHours(overage.MINHOUR);
+                DateTime maxTime = txndate.AddDays(overage.OVERAGE);
+                cntrItemRel.S_CG_ID = greenTireInformation.BARCODE;
+                cntrItemRel.S_ITEM_CODE = greenTireInformation.ITEMCODE;
+                cntrItemRel.S_CNTR_CODE = cntrCode;
+                cntrItemRel.S_CELL_NO = greenTireInformation.TIRECODE;
+                cntrItemRel.F_QTY = greenTireInformation.QTY;
+                cntrItemRel.S_MCN = greenTireInformation.MCN;
+                cntrItemRel.S_OPR = greenTireInformation.OPR;
+                cntrItemRel.S_OPR02 = greenTireInformation.OPR02;
+                cntrItemRel.S_OPR03 = greenTireInformation.OPR03;
+                cntrItemRel.S_OPR04 = greenTireInformation.OPR04;
+                cntrItemRel.S_WINDUP = greenTireInformation.WINDUP;
+                cntrItemRel.S_TXNDATE = greenTireInformation.TXNDATE;
+                cntrItemRel.S_DATE_SHIFT = greenTireInformation.DATE_SHIFT;
+                cntrItemRel.S_EFFECTIVE_TIME = minTime.ToString("yyyy-MM-dd HH:mm:ss");
+                cntrItemRel.S_EXPIRATION_TIME = maxTime.ToString("yyyy-MM-dd HH:mm:ss");
+                result = db.Updateable(cntrItemRel).ExecuteCommand() > 0;
+            }
+            return result;
+        }
+
+        /// <summary>
+        /// 鏌ヨ纭寲宸ュ崟
+        /// </summary>
+        /// <param name="dateShift"></param>
+        /// <param name="mcn"></param>
+        /// <param name="shift"></param>
+        /// <returns></returns>
+        public static ProductionShedule getProductionShedule(string dateShift ,string mcn ,string shift) 
+        {
+            var db = new SqlHelper<object>().GetInstance();
+            return db.Queryable<ProductionShedule>().Where(a => a.DATESHIFT == dateShift && a.MCN == mcn && a.SHIFT == shift).First();
+        }
+
+        /// <summary>
+        /// 鏌ヨ鑳氳儙瀹屾垚纭寲鐨勬暟閲�+        /// </summary>
+        /// <returns></returns>
+        public static int getEmbryoFinishNum(string dateShift, string mcn, string shift) 
+        {
+            var db = new SqlHelper<object>().GetInstance();
+            return db.Queryable<EmbryoFinishRecord>().Where(a => a.DATE_SHIFT == dateShift && a.CUR_MCN == mcn && a.CUR_SHIFT == shift).Count();
+        }
     }    
 }

--
Gitblit v1.9.1