Make_ShipmentVerify.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. using UAS_MES_NEW.CustomControl.ButtonUtil;
  12. using UAS_MES_NEW.CustomControl.RichText;
  13. using UAS_MES_NEW.DataOperate;
  14. using UAS_MES_NEW.Entity;
  15. using UAS_MES_NEW.PublicMethod;
  16. namespace UAS_MES_NEW.Make
  17. {
  18. public partial class Make_ShipmentVerify : Form
  19. {
  20. public Make_ShipmentVerify()
  21. {
  22. InitializeComponent();
  23. }
  24. DataTable dt, data;
  25. DataHelper dh;
  26. int panelQty;
  27. string oMakeCode, oMSID, reworkstatus, ifrework, ErrorMessage;
  28. private void Make_HandFeedRegistration_Load(object sender, EventArgs e)
  29. {
  30. dh = SystemInf.dh;
  31. data = new DataTable();
  32. data.Columns.Add("isDel", typeof(bool));
  33. data.Columns.Add("rn", typeof(int));
  34. data.Columns.Add("ms_sncode", typeof(string));
  35. data.Columns.Add("ms_makecode", typeof(string));
  36. dgv.AutoGenerateColumns = false;
  37. dgv.DataSource = data;
  38. snVal.Enabled = false;
  39. if (string.IsNullOrEmpty(BoxQtyVal.Text))
  40. BoxQtyVal.Text = "0";
  41. PanelQtyVal.Focus();
  42. }
  43. private void Confirm_Click(object sender, EventArgs e)
  44. {
  45. if (Confirm.Text == "确认")
  46. {
  47. if (string.IsNullOrEmpty(PanelQtyVal.Text))
  48. {
  49. PanelQtyVal.Text = "";
  50. ShowMsg(Msg1, 0, "请输入拼板数");
  51. PanelQtyVal.Focus();
  52. return;
  53. }
  54. if (!int.TryParse(PanelQtyVal.Text, out int qty) || qty <= 0)
  55. {
  56. PanelQtyVal.Text = "";
  57. ShowMsg(Msg1, 0, "拼板数请输入正整数");
  58. PanelQtyVal.Focus();
  59. return;
  60. }
  61. if (!int.TryParse(BoxQtyVal.Text.Trim(), out int boxQty) || boxQty < 0)
  62. {
  63. ShowMsg(Msg1, 0, "当前箱容量请输入非负整数");
  64. BoxQtyVal.Focus();
  65. BoxQtyVal.SelectAll();
  66. return;
  67. }
  68. panelQty = qty;
  69. BoxQtyVal.Text = boxQty.ToString();
  70. Confirm.Text = "取消";
  71. PanelQtyVal.Enabled = false;
  72. BoxQtyVal.Enabled = false;
  73. snVal.Enabled = true;
  74. snVal.Focus();
  75. snVal.SelectAll();
  76. }
  77. else if (Confirm.Text == "取消")
  78. {
  79. Confirm.Text = "确认";
  80. panelQty = 0;
  81. PanelQtyVal.Enabled = true;
  82. BoxQtyVal.Enabled = true;
  83. snVal.Enabled = false;
  84. snVal.Text = "";
  85. data.Rows.Clear();
  86. UpdateSN("C");
  87. PanelQtyVal.Focus();
  88. PanelQtyVal.SelectAll();
  89. }
  90. }
  91. private void snVal_KeyDown(object sender, KeyEventArgs e)
  92. {
  93. if (e.KeyCode != Keys.Enter) return;
  94. e.Handled = true;
  95. e.SuppressKeyPress = true;
  96. if (PanelQtyVal.Enabled || panelQty <= 0)
  97. {
  98. ShowMsg(Msg1, 0, "请先确认拼板数量");
  99. return;
  100. }
  101. string scanSn = snVal.Text.Trim();
  102. if (string.IsNullOrEmpty(scanSn))
  103. {
  104. ShowMsg(Msg1, 0, "请扫描序列号");
  105. snVal.Focus();
  106. return;
  107. }
  108. if (data.Rows.Count >= panelQty)
  109. {
  110. ShowMsg(Msg1, 0, "已达到拼板数量");
  111. snVal.Focus();
  112. snVal.SelectAll();
  113. return;
  114. }
  115. string snSql = scanSn.Replace("'", "''");
  116. dt = (DataTable)dh.ExecuteSql($@"SELECT ms_sncode, ms_makecode FROM makeserial a WHERE
  117. a.ms_sncode = '{snSql}'", "select");
  118. if (dt.Rows.Count > 0)
  119. {
  120. string snCode = dt.Rows[0]["ms_sncode"].ToString();
  121. string makeCode = dt.Rows[0]["ms_makecode"].ToString();
  122. foreach (DataRow row in data.Rows)
  123. {
  124. if (string.Equals(row["ms_sncode"].ToString(), snCode, StringComparison.OrdinalIgnoreCase))
  125. {
  126. ShowMsg(Msg1, 0, "序列号已扫描");
  127. snVal.Focus();
  128. snVal.SelectAll();
  129. return;
  130. }
  131. }
  132. if (!CheckCollectSN(snCode, makeCode))
  133. {
  134. snVal.Focus();
  135. snVal.SelectAll();
  136. return;
  137. }
  138. data.Rows.Add(false, data.Rows.Count + 1, snCode, makeCode);
  139. UpdateSN("L", snCode);
  140. snVal.Text = "";
  141. snVal.Focus();
  142. if (data.Rows.Count >= panelQty)
  143. {
  144. ShowMsg(Msg1, 1, "拼板数量已扫满");
  145. PanelFull();
  146. }
  147. }
  148. else
  149. {
  150. ShowMsg(Msg1, 0, "序列号不存在");
  151. UpdateSN("C");
  152. snVal.Focus();
  153. snVal.SelectAll();
  154. }
  155. }
  156. /// <summary>
  157. /// 采集工序校验。不通过时已输出红色提示,调用处只需处理焦点。
  158. /// </summary>
  159. private bool CheckCollectSN(string snCode, string makeCode)
  160. {
  161. if (!LogicHandler.CheckStepAttribute(Tag.ToString(), User.UserSourceCode, out ErrorMessage))
  162. {
  163. ShowMsg(Msg1, 0, ErrorMessage);
  164. return false;
  165. }
  166. bool NoteAlready = LogicHandler.CheckDiffMakeCodeBeforeStepCheck(snCode, makeCode, true, out oMakeCode, out ErrorMessage);
  167. if (!NoteAlready)
  168. {
  169. ShowMsg(Msg1, 0, ErrorMessage);
  170. return false;
  171. }
  172. if (!LogicHandler.CheckStepSNAndMacode(oMakeCode, User.UserSourceCode, snCode, User.UserCode, out oMakeCode, out oMSID, out ErrorMessage))
  173. {
  174. ShowMsg(Msg1, 0, ErrorMessage);
  175. return false;
  176. }
  177. if (!LogicHandler.CheckDiffMakeCodeAfterStepCheck(snCode, oMakeCode, true, NoteAlready, workOrder, out ErrorMessage))
  178. {
  179. ShowMsg(Msg1, 0, ErrorMessage);
  180. return false;
  181. }
  182. if (workOrder.Text != oMakeCode && oMakeCode != null)
  183. {
  184. string makeSql = oMakeCode.Replace("'", "''");
  185. dt = (DataTable)dh.ExecuteSql("select ma_code,ma_prodcode,ma_softversion,ma_salecode,pr_spec,nvl(pr_sendchecktype,'LineCode')pr_sendchecktype,ma_qty from make left join product on ma_prodcode=pr_code where ma_code='" + makeSql + "'", "select");
  186. if (dt.Rows.Count > 0)
  187. {
  188. BaseUtil.SetFormValue(this.Controls, dt);
  189. workOrder.Text = dt.Rows[0]["ma_code"].ToString();
  190. productCode.Text = dt.Rows[0]["ma_prodcode"].ToString();
  191. productName.Text = dt.Rows[0]["pr_spec"].ToString();
  192. }
  193. }
  194. string msIdSql = (oMSID ?? "").Replace("'", "''");
  195. dt = (DataTable)dh.ExecuteSql("select ms_nextstepcode,ms_sncode,ms_reworkstatus,nvl(ms_ifrework,0)ms_ifrework,ms_stepcode,ms_status,nvl(st_ifrepair,0) st_ifrepair from makeserial left join step on ms_stepcode=st_code where ms_id='" + msIdSql + "'", "select");
  196. if (dt.Rows.Count == 0)
  197. {
  198. ShowMsg(Msg1, 0, "未查询到序列号工序信息");
  199. return false;
  200. }
  201. string status = dt.Rows[0]["ms_status"].ToString();
  202. reworkstatus = dt.Rows[0]["ms_reworkstatus"].ToString();
  203. string stepcode = dt.Rows[0]["ms_stepcode"].ToString();
  204. string ifrepair = dt.Rows[0]["st_ifrepair"].ToString();
  205. string ms_nextstepcode = dt.Rows[0]["ms_nextstepcode"].ToString();
  206. string sncode = dt.Rows[0]["ms_sncode"].ToString();
  207. if (sncode != snCode)
  208. {
  209. ShowMsg(Msg1, 0, snCode + " 序列号已执行过转号,不允许使用TSN采集");
  210. return false;
  211. }
  212. ifrework = dt.Rows[0]["ms_ifrework"].ToString();
  213. bool sameStep = stepcode == User.CurrentStepCode && ms_nextstepcode != User.CurrentStepCode && ifrepair == "0";
  214. if (ifrework != "0" && sameStep && (reworkstatus == "1" || reworkstatus == "2"))
  215. {
  216. ShowMsg(Msg1, 0, snCode + " 序列号已执行过" + User.CurrentStepCode + "工序,采集结果为良品");
  217. return false;
  218. }
  219. if (ifrework == "0" && sameStep && (status == "1" || status == "2"))
  220. {
  221. ShowMsg(Msg1, 0, snCode + " 序列号已执行过" + User.CurrentStepCode + "工序,采集结果为良品");
  222. return false;
  223. }
  224. return true;
  225. }
  226. /// <summary>
  227. /// 拼板扫满后,表格中的序列号一次全部过站。
  228. /// </summary>
  229. private void PanelFull()
  230. {
  231. dgv.EndEdit();
  232. List<DataRow> rows = new List<DataRow>();
  233. foreach (DataRow row in data.Rows)
  234. {
  235. if (row.RowState == DataRowState.Deleted) continue;
  236. rows.Add(row);
  237. }
  238. if (rows.Count == 0)
  239. {
  240. ShowMsg(Msg1, 0, "没有可过站的序列号");
  241. return;
  242. }
  243. List<string> successList = new List<string>();
  244. List<string> afterList = new List<string>();
  245. List<string> failList = new List<string>();
  246. List<DataRow> passedRows = new List<DataRow>();
  247. foreach (DataRow row in rows)
  248. {
  249. string snCode = row["ms_sncode"].ToString();
  250. string makeCode = row["ms_makecode"].ToString();
  251. string stepError;
  252. if (!PassOneSN(snCode, makeCode, out stepError))
  253. {
  254. failList.Add(string.IsNullOrEmpty(stepError) ? snCode : snCode + "(" + stepError + ")");
  255. continue;
  256. }
  257. successList.Add(snCode);
  258. passedRows.Add(row);
  259. if (!string.IsNullOrEmpty(stepError) && stepError.IndexOf("AFTERSUCCESS", StringComparison.OrdinalIgnoreCase) >= 0)
  260. afterList.Add(snCode + " " + stepError);
  261. LogicHandler.DoCommandLog(Tag.ToString(), User.UserCode, makeCode, User.UserLineCode, User.UserSourceCode, "出货核对", "过站成功", snCode, "");
  262. }
  263. foreach (DataRow row in passedRows)
  264. data.Rows.Remove(row);
  265. for (int i = 0; i < data.Rows.Count; i++)
  266. data.Rows[i]["rn"] = i + 1;
  267. if (successList.Count > 0 && failList.Count == 0)
  268. {
  269. int boxQty = 0;
  270. int.TryParse(BoxQtyVal.Text.Trim(), out boxQty);
  271. boxQty += successList.Count;
  272. BoxQtyVal.Text = boxQty.ToString();
  273. ShowMsg(Msg1, 1, $"过站成功{successList.Count}条,序列号:{string.Join("、", successList)},当前箱容量:{boxQty}");
  274. }
  275. else if (successList.Count > 0)
  276. {
  277. ShowMsg(Msg1, 1, $"过站成功{successList.Count}条,序列号:{string.Join("、", successList)}");
  278. }
  279. foreach (string afterMsg in afterList)
  280. ShowMsg(Msg1, 2, afterMsg);
  281. if (failList.Count > 0)
  282. ShowMsg(Msg1, 0, $"过站失败{failList.Count}条,序列号:{string.Join("、", failList)}");
  283. if (snVal.Enabled)
  284. {
  285. snVal.Focus();
  286. snVal.SelectAll();
  287. }
  288. }
  289. /// <summary>
  290. /// 单条过站。失败原因写入 stepError,成功且带 AFTERSUCCESS 时 stepError 为附加信息。
  291. /// </summary>
  292. private bool PassOneSN(string snCode, string makeCode, out string stepError)
  293. {
  294. stepError = "";
  295. try
  296. {
  297. string snSql = (snCode ?? "").Replace("'", "''");
  298. string makeSql = (makeCode ?? "").Replace("'", "''");
  299. DataTable reworkDt = (DataTable)dh.ExecuteSql($@"SELECT nvl(ms_ifrework,0) ms_ifrework, ms_reworkstatus FROM makeserial WHERE ms_sncode='{snSql}' AND ms_makecode='{makeSql}'", "select");
  300. if (reworkDt.Rows.Count == 0)
  301. {
  302. stepError = "未查询到序列号";
  303. return false;
  304. }
  305. string rowIfRework = reworkDt.Rows[0]["ms_ifrework"].ToString();
  306. string rowReworkStatus = reworkDt.Rows[0]["ms_reworkstatus"].ToString();
  307. if (rowIfRework != "0" && rowReworkStatus == "3")
  308. {
  309. stepError = "返修不良必须先维修";
  310. return false;
  311. }
  312. if (rowIfRework == "0")
  313. {
  314. DataTable badDt = (DataTable)dh.ExecuteSql($@"SELECT mb_id,bc_name,mbr_mbid FROM makebad LEFT JOIN makebadreason ON mbr_mbid=mb_id LEFT JOIN badcode ON mb_badcode=bc_code WHERE mb_sncode='{snSql}' AND mb_makecode='{makeSql}' AND mb_status=0", "select");
  315. List<string> badNames = new List<string>();
  316. for (int i = 0; i < badDt.Rows.Count; i++)
  317. {
  318. if (badDt.Rows[i]["mb_id"].ToString() != badDt.Rows[i]["mbr_mbid"].ToString())
  319. badNames.Add("【" + badDt.Rows[i]["bc_name"].ToString() + "】");
  320. }
  321. if (badNames.Count > 0)
  322. {
  323. stepError = "已判为不良品" + string.Join("", badNames);
  324. return false;
  325. }
  326. }
  327. if (!LogicHandler.SetStepResult(makeCode, User.UserSourceCode, snCode, "出货核对", "检测合格", User.UserCode, out stepError))
  328. {
  329. if (string.IsNullOrEmpty(stepError) || stepError == "null")
  330. stepError = "过站失败";
  331. return false;
  332. }
  333. if (stepError == "null")
  334. stepError = "";
  335. return true;
  336. }
  337. catch (Exception ex)
  338. {
  339. stepError = ex.Message;
  340. return false;
  341. }
  342. }
  343. private void Delete_Click(object sender, EventArgs e)
  344. {
  345. dgv.EndEdit();
  346. List<DataRow> removeRows = new List<DataRow>();
  347. foreach (DataRow row in data.Rows)
  348. {
  349. if (row.RowState == DataRowState.Deleted) continue;
  350. if (row["isDel"] != DBNull.Value && Convert.ToBoolean(row["isDel"]))
  351. removeRows.Add(row);
  352. }
  353. if (removeRows.Count == 0)
  354. {
  355. ShowMsg(Msg1, 0, "请勾选要删除的序列号");
  356. return;
  357. }
  358. List<string> snList = new List<string>();
  359. foreach (DataRow row in removeRows)
  360. {
  361. snList.Add(row["ms_sncode"].ToString());
  362. data.Rows.Remove(row);
  363. }
  364. for (int i = 0; i < data.Rows.Count; i++)
  365. data.Rows[i]["rn"] = i + 1;
  366. ShowMsg(Msg1, 1, $"已删除{removeRows.Count}条,序列号:{string.Join("、", snList)}");
  367. if (snVal.Enabled)
  368. {
  369. snVal.Focus();
  370. snVal.SelectAll();
  371. }
  372. }
  373. private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
  374. {
  375. if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
  376. var column = dgv.Columns[e.ColumnIndex];
  377. if (column is DataGridViewCheckBoxColumn)
  378. {
  379. var cell = dgv[e.ColumnIndex, e.RowIndex] as DataGridViewCheckBoxCell;
  380. if (cell != null && !cell.ReadOnly)
  381. {
  382. bool currentValue = false;
  383. if (cell.Value != null && cell.Value != DBNull.Value)
  384. {
  385. currentValue = Convert.ToBoolean(cell.Value);
  386. }
  387. bool nextValue = !currentValue;
  388. cell.Value = nextValue;
  389. if (e.RowIndex < data.Rows.Count)
  390. data.Rows[e.RowIndex]["isDel"] = nextValue;
  391. dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
  392. dgv.EndEdit();
  393. var row = dgv.Rows[e.RowIndex];
  394. if (currentValue)
  395. {
  396. row.DefaultCellStyle.BackColor = dgv.DefaultCellStyle.BackColor;
  397. row.DefaultCellStyle.ForeColor = dgv.DefaultCellStyle.ForeColor;
  398. }
  399. else
  400. {
  401. row.DefaultCellStyle.BackColor = Color.LightSkyBlue;
  402. row.DefaultCellStyle.ForeColor = Color.Black;
  403. }
  404. }
  405. }
  406. }
  407. private void UpdateSN(string type, string sn = "")
  408. {
  409. if (type == "C")
  410. {
  411. serialNumber.Text = "";
  412. workOrder.Text = "";
  413. productCode.Text = "";
  414. productName.Text = "";
  415. }
  416. else if (type == "L")
  417. {
  418. string snSql = sn.Replace("'", "''");
  419. dt = (DataTable)dh.ExecuteSql($@"SELECT ms_sncode,ma_code,pr_code,pr_spec FROM makeserial,make,product
  420. WHERE ms_sncode = '{snSql}' AND ms_makecode = ma_code AND ms_prodcode = pr_code", "select");
  421. if (dt.Rows.Count > 0)
  422. {
  423. serialNumber.Text = dt.Rows[0]["ms_sncode"].ToString();
  424. workOrder.Text = dt.Rows[0]["ma_code"].ToString();
  425. productCode.Text = dt.Rows[0]["pr_code"].ToString();
  426. productName.Text = dt.Rows[0]["pr_spec"].ToString();
  427. }
  428. else
  429. {
  430. UpdateSN("C", sn);
  431. }
  432. }
  433. }
  434. private void claerBtn_Click(object sender, EventArgs e)
  435. {
  436. Msg1.Clear();
  437. }
  438. private void boxResetBtn_Click(object sender, EventArgs e)
  439. {
  440. BoxQtyVal.Text = "0";
  441. ShowMsg(Msg1, 1, "当前箱容量已归零");
  442. }
  443. private void ShowMsg(RichTextAutoBottom msgBox, int type, string msg)
  444. {
  445. msg = msg.Replace("\r", "").Replace("\n", "");
  446. string msgTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  447. string showMsg = $"{msgTime}: {msg}\n";
  448. if (type == 0)
  449. {
  450. msgBox.AppendText(showMsg, Color.Red);
  451. msgBox.SelectionStart = msgBox.Text.Length;
  452. msgBox.ScrollToCaret();
  453. }
  454. else if (type == 1)
  455. {
  456. msgBox.AppendText(showMsg, Color.Green);
  457. msgBox.SelectionStart = msgBox.Text.Length;
  458. msgBox.ScrollToCaret();
  459. }
  460. else if (type == 2)
  461. {
  462. msgBox.AppendText(showMsg, Color.YellowGreen);
  463. msgBox.SelectionStart = msgBox.Text.Length;
  464. msgBox.ScrollToCaret();
  465. }
  466. }
  467. }
  468. }