qinchulong
2024-10-12 b17d60113095491a95557f6f785cb1c0e744e8cc
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
namespace WIDESEA_StorageOutBasicServices;
 
public class Dt_LocationService : ServiceBase<Dt_LocationInfo, IDt_LocationRepository>, IDt_LocationService
{
    private readonly IUnitOfWorkManage _unitOfWorkManage;
    private readonly IDt_OutOrderService _outOrderService;
    private readonly IDt_TaskService _taskService;
    private readonly IDt_BillGroupStockService _BillGroupStockService;
 
    public Dt_LocationService(IDt_LocationRepository BaseDal,
                                    IUnitOfWorkManage unitOfWorkManage,
                                    IDt_OutOrderService outOrderService,
                                    IDt_TaskService taskService,
                                    IDt_BillGroupStockService billGroupStockService) : base(BaseDal)
    {
        _unitOfWorkManage = unitOfWorkManage;
        _outOrderService = outOrderService;
        _taskService = taskService;
        _BillGroupStockService = billGroupStockService;
    }
 
    /// <summary>
    /// 检查并生成移库任务或返回出库任务
    /// </summary>
    /// <param name="locationID">库位ID</param>
    /// <returns>任务对象</returns>
    public virtual async Task<Dt_Task> TransferCheck(string locationID)
    {
        try
        {
            // 获取指定库位的任务
            var outboundTask = await _taskService.GetByLocation(locationID);
            if (outboundTask == null)
                return null;
 
            // 检查是否需要进行移库
            if (CheckForInternalTransfer(locationID))
            {
                // 计算对应位置的相对库位 (奇数行的下一行或者偶数行的上一行)
                var newLocationID = GetRelativeLocationID(locationID);
 
                // 获取新的库位的任务
                var internalTransferTask = await _taskService.GetByLocation(newLocationID);
 
                // 如果新的库位没有找到对应的任务
                if (internalTransferTask == null)
                {
                    return await HandleNoTaskAtLocation(locationID, newLocationID, outboundTask);
                }
 
                // 直接返回一深位出库任务
                return internalTransferTask;
            }
 
            // 返回当前库位的出库任务
            return outboundTask;
        }
        catch (Exception)
        {
            return null;
        }
    }
 
    #region 内部方法
 
    /// <summary>
    /// 计算相对的库位ID
    /// </summary>
    /// <param name="locationID">当前库位ID</param>
    /// <returns>相对的库位ID</returns>
    private string GetRelativeLocationID(string locationID)
    {
        string[] parts = locationID.Split('-');
        int line = int.Parse(parts[0]);
 
        // 计算相对的货位行值,奇数行的下一行或者偶数行的上一行
        int relativeLine = line % 2 == 1 ? line + 1 : line - 1;
 
        // 构建新的库位ID
        string[] newLocationParts = new string[] { relativeLine.ToString().PadLeft(3, '0'), parts[1], parts[2] };
        return string.Join("-", newLocationParts);
    }
 
    /// <summary>
    /// 处理没有任务的库位情况
    /// </summary>
    /// <param name="originalLocationID">原始库位ID</param>
    /// <param name="newLocationID">新的库位ID</param>
    /// <param name="outboundTask">出库任务</param>
    /// <returns>生成的移库任务或原始出库任务</returns>
    private async Task<Dt_Task> HandleNoTaskAtLocation(string originalLocationID, string newLocationID, Dt_Task outboundTask)
    {
        // 判断该位置是否有库存
        var stockInfo = await _BillGroupStockService.GetStocks(locationID: newLocationID);
 
        if (stockInfo == null)
        {
            // 如果没有库存,直接返回当前出库任务
            return outboundTask;
        }
        else
        {
            // 如果有库存,生成移库任务
            var emptyLocation = GetTransferLocationEmpty(outboundTask.Roadway);
 
            Dt_Task newTransferTask = new Dt_Task()
            {
                CreateDate = DateTime.Now,
                Creater = "System",
                CurrentAddress = originalLocationID,
                Grade = 99,
                MaterialNo = stockInfo.MaterialNo,
                NextAddress = emptyLocation.LocationID,
                PalletCode = stockInfo.PalletCode,
                Remark = "移库",
                Roadway = stockInfo.LocationInfo.Roadway,
                SourceAddress = originalLocationID,
                TaskNum = 0,
                TargetAddress = emptyLocation.LocationID,
                TaskState = TaskStateConst.PendingDispatch.ToString(),
                TaskType = TaskTypeConst.InternalTransfer.ToString(),
            };
 
            return await _taskService.Create(newTransferTask);
        }
    }
 
    /// <summary>
    /// 根据货位检查一深位是否需要移库
    /// </summary>
    /// <param name="locationID">货位ID</param>
    /// <returns>是否需要移库</returns>
    private bool CheckForInternalTransfer(string locationID)
    {
        // 根据 "-" 截取字符串并获取第一位数字
        string[] parts = locationID.Split('-');
        if (parts.Length > 0 && int.TryParse(parts[0], out int row))
        {
            // 获取二深位的行号列表,表示需要移库
            List<int> transfertRows = AppSettings.app("TransfertRows").Split(',').ToList().ConvertAll(x => int.Parse(x));
            // 判断行号是否在目标行号列表中
            return transfertRows.Contains(row);
        }
        return false;
    }
 
    /// <summary>
    /// 根据巷道获取二深位的空库位
    /// </summary>
    /// <param name="roadway">巷道</param>
    /// <returns>货位对象</returns>
    private Dt_LocationInfo GetTransferLocationEmpty(string roadway)
    {
        return Db.Queryable<Dt_LocationInfo>()
            .Where(x => x.Status == LocationStateConst.LocationState_Empty)
            .Where(x => x.Depth == 2.ToString())
            .Where(x => x.Roadway == roadway)
            .First();
    }
 
    #endregion 内部方法
}