kazelee
7 天以前 2ca90a404fa1ab94eb6374f50c6ddd47a2b7f0e6
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using HH.WCS.Mobox3.DSZSH.models;
using HH.WCS.Mobox3.DSZSH.util;
 
using Newtonsoft.Json;
 
using SqlSugar;
 
namespace HH.WCS.Mobox3.DSZSH.wms {
    /// <summary>
    /// 数据库 [ 事务处理 ] 帮助类
    /// </summary>
    public class DbTran {
        /// <summary>
        /// 数据库事务处理 ( 创建任务 )
        /// </summary>
        /// <remarks><b>[ 要求 ]</b> obj ≠ null<br/>
        /// <b>[ 注意 ]</b> 所有的数据库操作 , 都会在对象 = null 时选择跳过 , 且不会报错 ( 除了 TaskToInsert )
        /// <br/>如果存在某个必须完成的数据库操作 , 需在调用时确保该对象 ≠ null</remarks>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static (bool, string) CreateTask(CreateTaskObj obj) {
            var db = new SqlHelper<object>().GetInstance();
 
            using (var tran = db.Ado.UseTran()) {
                // 更新[容器表](业务需要)
                if (obj.ContainerToUpdate != null && db.Updateable(obj.ContainerToUpdate).UpdateColumns(c => new { c.S_SPEC, c.S_SOURCE, c.T_MODIFY }).ExecuteCommand() <= 0) {
                    return (false, $"更新[容器][规格(物料编码)]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.ContainerToUpdate)}\n");
                }
 
                // 更新[容器货品明细](业务需要)
                if (obj.CgDetailToUpdate != null && db.Updateable(obj.CgDetailToUpdate).UpdateColumns(it => new { it.N_ITEM_STATE, it.S_ITEM_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[容器货品明细][物料状态]失败!!物料号='{obj.CgDetailToUpdate}',物料状态=>'{obj.CgDetailToUpdate.S_ITEM_STATE}'");
                }
 
                #region 删除[旧]容器绑定信息
                if (obj.Old != null) {
                    if (obj.Old.CgDetail != null && db.Deleteable(obj.Old.CgDetail).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"删除[旧容器货品明细]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.Old.CgDetail)}\n");
                    }
                    if (obj.Old.LocCntrRel != null && db.Deleteable(obj.Old.LocCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"删除[旧货位容器绑定]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.Old.LocCntrRel)}\n");
                    }
                    if (obj.Old.Location != null && db.Updateable(obj.Old.Location).UpdateColumns(l => new { l.N_CURRENT_NUM, l.T_MODIFY }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"更新[旧货位][当前容器数量]失败!!货位='{obj.Old.Location.S_CODE}',数量=>{obj.Old.Location.N_CURRENT_NUM}");
                    }
                }
                #endregion
 
                #region 添加[新]容器绑定信息
                if (obj.New != null) {
                    if (obj.New.CgDetail != null && db.Insertable(obj.New.CgDetail).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"插入[新容器货品明细]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.New.CgDetail)}\n");
                    }
                    if (obj.New.LocCntrRel != null && db.Insertable(obj.New.LocCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"插入[旧货位容器绑定]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.New.LocCntrRel)}\n");
                    }
                    // 新货位信息通常就是 StartLoc , 在 StartLocToUpdate 中处理即可
                }
                #endregion
 
                #region 创建任务 + 货位锁
                if (obj.StartLocToUpdate != null && db.Updateable(obj.StartLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[起点货位][锁状态]失败!!起点='{obj.StartLocToUpdate.S_CODE}',锁状态=>'{obj.StartLocToUpdate.S_LOCK_STATE}'");
                }
                if (obj.EndLocToUpdate != null && db.Updateable(obj.EndLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[终点货位][锁状态]失败!!终点='{obj.EndLocToUpdate.S_CODE}',锁状态=>'{obj.EndLocToUpdate.S_LOCK_STATE}'");
                }
                if (obj.TaskToInsert == null) {
                    tran.RollbackTran();
                    throw new ArgumentException("数据库事务处理:待插入的[任务]为空!!"); // 待插入的任务不存在,直接抛出异常
                }
                if (db.Insertable(obj.TaskToInsert).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"生成任务'{obj.TaskToInsert.S_TYPE}'失败!!任务号='{obj.TaskToInsert.S_CODE}',容器号='{obj.TaskToInsert.S_CNTR_CODE}',起点='{obj.TaskToInsert.S_START_LOC}',终点='{obj.TaskToInsert.S_END_LOC}'");
                }
                #endregion
 
                // 提交数据库更改
                tran.CommitTran();
                return (true, $"生成任务'{obj.TaskToInsert.S_TYPE}'成功!!任务号='{obj.TaskToInsert.S_CODE}',容器号='{obj.TaskToInsert.S_CNTR_CODE}',起点='{obj.TaskToInsert.S_START_LOC}',终点='{obj.TaskToInsert.S_END_LOC}'");
            }
        }
 
        /// <summary>
        /// 数据库事务 : 涉及单据明细更新的任务创建
        /// </summary>
        /// <param name="obj"></param>
        /// <remarks><b>[ 要求 ]</b> obj ≠ null ; obj.TaskToInsert ≠ null</remarks>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public static (bool, string) CreateTaskOrderObj(CreateTaskOrderObj obj) {
            var db = new SqlHelper<object>().GetInstance();
 
            using (var tran = db.Ado.UseTran()) {
 
                if (obj.OutboundDetailToUpdate != null && db.Updateable(obj.OutboundDetailToUpdate).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[明细表][状态]为[完成]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.OutboundDetailToUpdate)}\n");
                }
 
                if (obj.SpotCheckDetailToUpdate != null && db.Updateable(obj.SpotCheckDetailToUpdate).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[明细表][状态]为[完成]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.SpotCheckDetailToUpdate)}\n");
                }
 
                if (obj.RelocationDetailToUpdate != null && db.Updateable(obj.RelocationDetailToUpdate).UpdateColumns(it => new { it.N_B_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[明细表][状态]为[完成]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.RelocationDetailToUpdate)}\n");
                }
 
                #region 创建任务 + 货位锁
                if (obj.StartLocToUpdate != null && db.Updateable(obj.StartLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[起点货位][锁状态]失败!!起点='{obj.StartLocToUpdate.S_CODE}',锁状态=>'{obj.StartLocToUpdate.S_LOCK_STATE}'");
                }
                if (obj.EndLocToUpdate != null && db.Updateable(obj.EndLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"更新[终点货位][锁状态]失败!!终点='{obj.EndLocToUpdate.S_CODE}',锁状态=>'{obj.EndLocToUpdate.S_LOCK_STATE}'");
                }
                if (obj.TaskToInsert == null) {
                    tran.RollbackTran();
                    throw new ArgumentException("数据库事务处理:待插入的[任务]为空!!"); // 待插入的任务不存在,直接抛出异常
                }
                if (db.Insertable(obj.TaskToInsert).ExecuteCommand() <= 0) {
                    tran.RollbackTran();
                    return (false, $"生成任务'{obj.TaskToInsert.S_TYPE}'失败!!任务号='{obj.TaskToInsert.S_CODE}',容器号='{obj.TaskToInsert.S_CNTR_CODE}',起点='{obj.TaskToInsert.S_START_LOC}',终点='{obj.TaskToInsert.S_END_LOC}'");
                }
                #endregion
 
                // 提交数据库更改
                tran.CommitTran();
                return (true, $"生成任务'{obj.TaskToInsert.S_TYPE}'成功!!任务号='{obj.TaskToInsert.S_CODE}',容器号='{obj.TaskToInsert.S_CNTR_CODE}',起点='{obj.TaskToInsert.S_START_LOC}',终点='{obj.TaskToInsert.S_END_LOC}'");
            }
        }
 
    }
 
    public class CreateTaskObj {
 
        #region 起点货位 / 终点货位 / 任务
        public TN_Location StartLocToUpdate { get; set; } = null;
        public TN_Location EndLocToUpdate { get; set; } = null;
        public TN_Task TaskToInsert { get; set; } = null;
        #endregion
 
        #region 容器绑定信息 ( 旧 / 新 )
        /// <summary>
        /// [ 旧 ] 容器绑定信息 ( 货位 / 货位容器 / 容器货品 )
        /// </summary>
        public LocCntrCg Old { get; set; } = null;
        /// <summary>
        /// [ 新 ] 容器绑定信息 ( 货位 / 货位容器 / 容器货品 )
        /// </summary>
        public LocCntrCg New { get; set; } = null; 
        #endregion
 
        public TN_Container ContainerToUpdate { get; set; } = null;
        public TN_CG_Detail CgDetailToUpdate { get; set; } = null;
    }
 
    public class CreateTaskOrderObj {
 
        #region 起点货位 / 终点货位 / 任务
        public TN_Location StartLocToUpdate { get; set; } = null;
        public TN_Location EndLocToUpdate { get; set; } = null;
        public TN_Task TaskToInsert { get; set; } = null;
        #endregion
 
        public TN_Outbound_Detail OutboundDetailToUpdate { get; set; } = null;
        public TN_SpotCheck_Detail SpotCheckDetailToUpdate { get; set; } = null;
        public TN_RelocationList_Detail RelocationDetailToUpdate { get; set; } = null;
    }
 
}