|  |  | 
 |  |  |     public partial class LocationInfoService | 
 |  |  |     { | 
 |  |  |  | 
 |  |  |         double weightValue_BC = 0.25; | 
 |  |  |         double weightValue_BC = 0.5; | 
 |  |  |  | 
 |  |  |         private readonly static object _locker_BC = new object(); | 
 |  |  |         static List<LocationCache> locationCaches_BC = new List<LocationCache>(); | 
 |  |  | 
 |  |  |         /// æçç±»å | 
 |  |  |         /// </param> | 
 |  |  |         /// <returns></returns> | 
 |  |  |         public Dt_LocationInfo? AssignLocation_BC(string roadwayNo, PalletTypeEnum palletType, string beRelocationCode = "") | 
 |  |  |         public Dt_LocationInfo? AssignLocation_BC(string roadwayNo, int palletType, Dt_PalletTypeInfo palletTypeInfo, string beRelocationCode = "", int heightType = 0) | 
 |  |  |         { | 
 |  |  |             lock (_locker_BC) | 
 |  |  |             { | 
 |  |  | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 //å·²å®ä¹è´§ä½ç±»åçè´§ä½ | 
 |  |  |                 List<Dt_LocationInfo> definedTypeLocations = locationInfos.Where(x => x.LocationType == palletType.ObjToInt()).ToList(); | 
 |  |  |  | 
 |  |  |                 //æªå®ä¹ç±»åçç©ºè´§ä½ | 
 |  |  |                 List<Dt_LocationInfo> undefinedTypeEmptyLocations = locationInfos.Where(x => (x.EnableStatus == EnableStatusEnum.Normal.ObjToInt() || x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt()) && x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.LocationType == LocationTypeEnum.Undefined.ObjToInt() && !lockLocationCodes.Contains(x.LocationCode)).OrderByDescending(x => x.Depth).ThenBy(x => x.Layer).ThenBy(x => x.Row).ThenBy(x => x.Column).ToList(); | 
 |  |  |                 List<Dt_LocationInfo> undefinedTypeEmptyLocations = locationInfos.Where(x => (x.EnableStatus == EnableStatusEnum.Normal.ObjToInt() || x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt()) && x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.LocationType == LocationTypeEnum.Undefined.ObjToInt() && !lockLocationCodes.Contains(x.LocationCode)).OrderByDescending(x => x.Depth).ThenBy(x => x.Layer).ThenBy(x => x.Column).ThenBy(x => x.Row).ToList(); | 
 |  |  |  | 
 |  |  |                 List<Dt_LocationInfo> definedTypeEmptyLocations = locationInfos.Where(x => (x.EnableStatus == EnableStatusEnum.Normal.ObjToInt() || x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt()) && x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.LocationType == palletType.ObjToInt() && !lockLocationCodes.Contains(x.LocationCode)).OrderByDescending(x => x.Depth).ThenBy(x => x.Layer).ThenBy(x => x.Row).ThenBy(x => x.Column).ToList(); | 
 |  |  |                 List<Dt_LocationInfo> definedTypeEmptyLocations = locationInfos.Where(x => (x.EnableStatus == EnableStatusEnum.Normal.ObjToInt() || x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt()) && x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.LocationType == palletType.ObjToInt() && !lockLocationCodes.Contains(x.LocationCode)).OrderByDescending(x => x.Depth).ThenBy(x => x.Layer).ThenBy(x => x.Column).ThenBy(x => x.Row).ToList(); | 
 |  |  |  | 
 |  |  |                 if ((locationInfos.Count * weightValue_BC >= definedTypeLocations.Count && undefinedTypeEmptyLocations.Any()) || !definedTypeEmptyLocations.Any())//妿已å®ä¹ç±»åè´§ä½æªè¶
è¿æ¯ä¾ï¼ä¸ææªå®ä¹ç±»åçè´§ä½ | 
 |  |  |                 if(heightType == 1) | 
 |  |  |                 { | 
 |  |  |                     if (palletType == PalletTypeEnum.LargePallet || palletType == PalletTypeEnum.LargestPallet) | 
 |  |  |                     undefinedTypeEmptyLocations = undefinedTypeEmptyLocations.Where(x=>x.Layer <= 3).ToList(); | 
 |  |  |                     definedTypeEmptyLocations = definedTypeEmptyLocations.Where(x => x.Layer <= 3).ToList(); | 
 |  |  |                 } | 
 |  |  |                 else if(heightType == 2) | 
 |  |  |                 { | 
 |  |  |                     undefinedTypeEmptyLocations = undefinedTypeEmptyLocations.Where(x => x.Layer == 4).ToList(); | 
 |  |  |                     definedTypeEmptyLocations = definedTypeEmptyLocations.Where(x => x.Layer == 4).ToList(); | 
 |  |  |                 } | 
 |  |  |                 else if (heightType == 3) | 
 |  |  |                 { | 
 |  |  |                     undefinedTypeEmptyLocations = undefinedTypeEmptyLocations.Where(x => x.Layer == 5).ToList(); | 
 |  |  |                     definedTypeEmptyLocations = definedTypeEmptyLocations.Where(x => x.Layer == 5).ToList(); | 
 |  |  |                 } | 
 |  |  |                 else | 
 |  |  |                 { | 
 |  |  |                     undefinedTypeEmptyLocations = undefinedTypeEmptyLocations.Where(x => false).ToList(); | 
 |  |  |                     definedTypeEmptyLocations = definedTypeEmptyLocations.Where(x => false).ToList(); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 if (palletTypeInfo.LocaitonCount == 2) | 
 |  |  |                 { | 
 |  |  |                     if (roadwayNo != "SC01_BC") | 
 |  |  |                         definedTypeEmptyLocations = definedTypeEmptyLocations.Where(x => x.Column % 2 == 1).ToList(); | 
 |  |  |                     else | 
 |  |  |                         definedTypeEmptyLocations = definedTypeEmptyLocations.Where(x => x.Column % 2 == 0).ToList(); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 if (definedTypeEmptyLocations.Any()) | 
 |  |  |                 { | 
 |  |  |                     for (int i = 0; i < definedTypeEmptyLocations.Count; i++) | 
 |  |  |                     { | 
 |  |  |                         undefinedTypeEmptyLocations = undefinedTypeEmptyLocations.Where(x => x.Depth % 2 == 1).ToList(); | 
 |  |  |                     } | 
 |  |  |                     for (int i = 0; i < undefinedTypeEmptyLocations.Count; i++) | 
 |  |  |                     { | 
 |  |  |                         Dt_LocationInfo undefinedTypeEmptyLocation = undefinedTypeEmptyLocations[i]; | 
 |  |  |                         Dt_LocationInfo? locationInfo = GetUsableLocation_BC(locationInfos, undefinedTypeEmptyLocation, palletType); | 
 |  |  |                         Dt_LocationInfo definedTypeEmptyLocation = definedTypeEmptyLocations[i]; | 
 |  |  |                         Dt_LocationInfo? locationInfo = GetUsableLocation_BC(locationInfos, definedTypeEmptyLocation, palletType, palletTypeInfo); | 
 |  |  |                         //å¤æè´§ä½ä¸¤æ·±å以䏿¯å¦åå¨åºåºéå®è´§ä½ | 
 |  |  |                         if (locationInfo?.Depth == 1) | 
 |  |  |                         { | 
 |  |  |                             Dt_LocationInfo? IsBebusyLocation = locationInfos.Where(x => x.Row == (locationInfo?.Row == 2 ? locationInfo?.Row - 1 : locationInfo?.Row + 1) && x.Column==locationInfo?.Column && x.Layer== locationInfo?.Layer).FirstOrDefault(); | 
 |  |  |                             if (IsBebusyLocation!=null && (IsBebusyLocation.LocationStatus<LocationStatusEnum.InStock.ObjToInt())) | 
 |  |  |                             { | 
 |  |  |                                 continue; | 
 |  |  |                             } | 
 |  |  |                         } | 
 |  |  |                         if (locationInfo != null) | 
 |  |  |                         { | 
 |  |  |                             locationCaches_BC.Add(new LocationCache { LocationCode = locationInfo.LocationCode, DateTime = DateTime.Now }); | 
 |  |  | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |                 else | 
 |  |  |                 if ((/*locationInfos.Count * weightValue_BC >= definedTypeLocations.Count &&*/ undefinedTypeEmptyLocations.Any()))//妿已å®ä¹ç±»åè´§ä½æªè¶
è¿æ¯ä¾ï¼ä¸ææªå®ä¹ç±»åçè´§ä½ | 
 |  |  |                 { | 
 |  |  |                     for (int i = 0; i < definedTypeEmptyLocations.Count; i++) | 
 |  |  |                     if (palletTypeInfo.LocaitonCount == 2) | 
 |  |  |                     { | 
 |  |  |                         Dt_LocationInfo definedTypeEmptyLocation = definedTypeEmptyLocations[i]; | 
 |  |  |                         Dt_LocationInfo? locationInfo = GetUsableLocation_BC(locationInfos, definedTypeEmptyLocation, palletType); | 
 |  |  |                         if (locationInfo != null) | 
 |  |  |                         if (roadwayNo != "SC01_BC") | 
 |  |  |                             undefinedTypeEmptyLocations = undefinedTypeEmptyLocations.Where(x => x.Column % 2 == 1).ToList(); | 
 |  |  |                         else | 
 |  |  |                             undefinedTypeEmptyLocations = undefinedTypeEmptyLocations.Where(x => x.Column % 2 == 0).ToList(); | 
 |  |  |  | 
 |  |  |                         for (int i = 0; i < undefinedTypeEmptyLocations.Count; i++) | 
 |  |  |                         { | 
 |  |  |                             locationCaches_BC.Add(new LocationCache { LocationCode = locationInfo.LocationCode, DateTime = DateTime.Now }); | 
 |  |  |                             return locationInfo; | 
 |  |  |                             Dt_LocationInfo undefinedTypeEmptyLocation = undefinedTypeEmptyLocations[i]; | 
 |  |  |                             Dt_LocationInfo? locationInfo = GetUsableLocation_BC(locationInfos, undefinedTypeEmptyLocation, palletType, palletTypeInfo); | 
 |  |  |                             //å¤æè´§ä½ä¸¤æ·±å以䏿¯å¦åå¨åºåºéå®è´§ä½ | 
 |  |  |                             if (locationInfo?.Depth == 1) | 
 |  |  |                             { | 
 |  |  |                                 Dt_LocationInfo? IsBebusyLocation = locationInfos.Where(x => x.Row == (locationInfo?.Row == 2 ? locationInfo?.Row - 1 : locationInfo?.Row + 1) && x.Column == locationInfo?.Column && x.Layer == locationInfo?.Layer).FirstOrDefault(); | 
 |  |  |                                 if (IsBebusyLocation != null && (IsBebusyLocation.LocationStatus < LocationStatusEnum.InStock.ObjToInt())) | 
 |  |  |                                 { | 
 |  |  |                                     continue; | 
 |  |  |                                 } | 
 |  |  |                             } | 
 |  |  |                             if (locationInfo != null) | 
 |  |  |                             { | 
 |  |  |                                 //UpdateLocationStatus(locationInfo, palletType, LocationStatusEnum.Lock, locationInfo.WarehouseId); | 
 |  |  |                                 locationCaches_BC.Add(new LocationCache { LocationCode = locationInfo.LocationCode, DateTime = DateTime.Now }); | 
 |  |  |                                 return locationInfo; | 
 |  |  |                             } | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                      | 
 |  |  |                 } | 
 |  |  |                 return null; | 
 |  |  |             } | 
 |  |  | 
 |  |  |         /// <param name="emptyLocation"></param> | 
 |  |  |         /// <param name="palletType"></param> | 
 |  |  |         /// <returns></returns> | 
 |  |  |         private Dt_LocationInfo? GetUsableLocation_BC(List<Dt_LocationInfo> locationInfos, Dt_LocationInfo emptyLocation, PalletTypeEnum palletType) | 
 |  |  |         private Dt_LocationInfo? GetUsableLocation_BC(List<Dt_LocationInfo> locationInfos, Dt_LocationInfo emptyLocation, int palletType, Dt_PalletTypeInfo palletTypeInfo) | 
 |  |  |         { | 
 |  |  |             switch (palletType) | 
 |  |  |  | 
 |  |  |             if (palletTypeInfo.LocaitonCount == 2) | 
 |  |  |             { | 
 |  |  |                 case PalletTypeEnum.LargestPallet: | 
 |  |  |                 case PalletTypeEnum.LargePallet: | 
 |  |  |                     if (emptyLocation.Depth % 2 == 0) | 
 |  |  |                 Dt_LocationInfo? nearLocation = null; | 
 |  |  |                 if (emptyLocation.RoadwayNo != "SC01_BC" && emptyLocation.Column % 2 == 1) | 
 |  |  |                     nearLocation = locationInfos.FirstOrDefault(x => x.Row == emptyLocation.Row && x.Layer == emptyLocation.Layer && x.Depth == emptyLocation.Depth && x.Column == emptyLocation.Column - 1); | 
 |  |  |                 else if (emptyLocation.RoadwayNo == "SC01_BC" && emptyLocation.Column % 2 == 0) | 
 |  |  |                     nearLocation = locationInfos.FirstOrDefault(x => x.Row == emptyLocation.Row && x.Layer == emptyLocation.Layer && x.Depth == emptyLocation.Depth && x.Column == emptyLocation.Column + 1); | 
 |  |  |                 if (nearLocation != null && DepthLocationIsEmpty_BC(locationInfos, nearLocation) != null) | 
 |  |  |                 { | 
 |  |  |                     Dt_LocationInfo? locationInfo = DepthLocationIsEmpty_BC(locationInfos, emptyLocation); | 
 |  |  |                     if (locationInfo != null) | 
 |  |  |                     { | 
 |  |  |                         return null; | 
 |  |  |                         return locationInfo; | 
 |  |  |                     } | 
 |  |  |                     break; | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             Dt_LocationInfo? locationInfo = DepthLocationIsEmpty_BC(locationInfos, emptyLocation, palletType); | 
 |  |  |             if (locationInfo != null) | 
 |  |  |             else | 
 |  |  |             { | 
 |  |  |                 return locationInfo; | 
 |  |  |                 Dt_LocationInfo? locationInfo = DepthLocationIsEmpty_BC(locationInfos, emptyLocation); | 
 |  |  |                 if (locationInfo != null) | 
 |  |  |                 { | 
 |  |  |                     return locationInfo; | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             return null; | 
 |  |  |         } | 
 |  |  | 
 |  |  |         /// <param name="locationInfos"></param> | 
 |  |  |         /// <param name="emptyLocation"></param> | 
 |  |  |         /// <returns></returns> | 
 |  |  |         private Dt_LocationInfo? DepthLocationIsEmpty_BC(List<Dt_LocationInfo> locationInfos, Dt_LocationInfo emptyLocation, PalletTypeEnum palletType) | 
 |  |  |         private Dt_LocationInfo? DepthLocationIsEmpty_BC(List<Dt_LocationInfo> locationInfos, Dt_LocationInfo emptyLocation) | 
 |  |  |         { | 
 |  |  |             List<Dt_LocationInfo> locations = GetGroupLocations(locationInfos, emptyLocation); | 
 |  |  |  | 
 |  |  |             bool moreDepthFlag = false; | 
 |  |  |             bool littleDepthFlag = false; | 
 |  |  |  | 
 |  |  |             switch (palletType) | 
 |  |  |             if (emptyLocation.LocationType == 0) | 
 |  |  |             { | 
 |  |  |                 case PalletTypeEnum.LargestPallet: | 
 |  |  |                 case PalletTypeEnum.LargePallet: | 
 |  |  |                     List<Dt_LocationInfo> moreDepth = locations.Where(x => x.Depth > emptyLocation.Depth).ToList(); | 
 |  |  |                     moreDepthFlag = moreDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.InStock.ObjToInt() && x.LocationStatus != LocationStatusEnum.PalletLock.ObjToInt()) == null;//æ¥è¯¢å¤§äºå½åè´§ä½æ·±åº¦çéåéæ¯å¦æç¶æä¸ä¸ºæè´§çè´§ä½ï¼å¦ææ¯trueï¼åè¡¨ç¤ºæ·±è´§ä½ææªè¢«ä½¿ç¨çæ
åµ | 
 |  |  |                 List<Dt_LocationInfo> moreDepth = locations.Where(x => x.Depth > emptyLocation.Depth).ToList(); | 
 |  |  |                 moreDepthFlag = moreDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.InStock.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != 0) == null;//æ¥è¯¢å¤§äºå½åè´§ä½æ·±åº¦çéåéæ¯å¦æç¶æä¸ä¸ºæè´§çè´§ä½ï¼å¦ææ¯trueï¼åè¡¨ç¤ºæ·±è´§ä½ææªè¢«ä½¿ç¨çæ
åµ | 
 |  |  |  | 
 |  |  |                     List<Dt_LocationInfo> littleDepth = locations.Where(x => x.Depth <= emptyLocation.Depth).ToList(); | 
 |  |  |                     littleDepthFlag = littleDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.Free.ObjToInt() && x.EnableStatus != EnableStatusEnum.OnlyIn.ObjToInt() && x.EnableStatus != EnableStatusEnum.Normal.ObjToInt()) == null; //æ¥è¯¢å°äºå½åè´§ä½æ·±åº¦çéåéæ¯å¦æç¶æä¸ä¸ºç©ºï¼ä¸ç¦ç¨ç¶æä¸ä¸ºç¦ç¨ä»¥ååªå
¥çè´§ä½ï¼å¦ææ¯trueï¼å表示æµ
è´§ä½è¢«ä½¿ç¨æè
被ç¦ç¨çæ
åµ | 
 |  |  |                     break; | 
 |  |  |                 List<Dt_LocationInfo> littleDepth = locations.Where(x => x.Depth <= emptyLocation.Depth).ToList(); | 
 |  |  |                 littleDepthFlag = littleDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.Free.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != 0) == null; //æ¥è¯¢å°äºå½åè´§ä½æ·±åº¦çéåéæ¯å¦æç¶æä¸ä¸ºç©ºï¼ä¸ç¦ç¨ç¶æä¸ä¸ºç¦ç¨ä»¥ååªå
¥çè´§ä½ï¼å¦ææ¯trueï¼å表示æµ
è´§ä½è¢«ä½¿ç¨æè
被ç¦ç¨çæ
åµ | 
 |  |  |             } | 
 |  |  |             else | 
 |  |  |             { | 
 |  |  |                 List<Dt_LocationInfo> moreDepth = locations.Where(x => x.Depth > emptyLocation.Depth).ToList(); | 
 |  |  |                 moreDepthFlag = moreDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.InStock.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != emptyLocation.LocationType) == null;//æ¥è¯¢å¤§äºå½åè´§ä½æ·±åº¦çéåéæ¯å¦æç¶æä¸ä¸ºæè´§çè´§ä½ï¼å¦ææ¯trueï¼åè¡¨ç¤ºæ·±è´§ä½ææªè¢«ä½¿ç¨çæ
åµ | 
 |  |  |  | 
 |  |  |                 List<Dt_LocationInfo> littleDepth = locations.Where(x => x.Depth <= emptyLocation.Depth).ToList(); | 
 |  |  |                 littleDepthFlag = littleDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.Free.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != emptyLocation.LocationType) == null; //æ¥è¯¢å°äºå½åè´§ä½æ·±åº¦çéåéæ¯å¦æç¶æä¸ä¸ºç©ºï¼ä¸ç¦ç¨ç¶æä¸ä¸ºç¦ç¨ä»¥ååªå
¥çè´§ä½ï¼å¦ææ¯trueï¼å表示æµ
è´§ä½è¢«ä½¿ç¨æè
被ç¦ç¨çæ
åµ | 
 |  |  |             } | 
 |  |  |             if (moreDepthFlag && littleDepthFlag) | 
 |  |  |             { | 
 |  |  |                 return emptyLocation; |