You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

867 lines
42 KiB

3 weeks ago
  1. using Newtonsoft.Json.Linq;
  2. using Newtonsoft.Json;
  3. using NFine.Code;
  4. using NFine.Data.Extensions;
  5. using NFine.Domain._03_Entity.SRM;
  6. using NFine.Repository;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Data;
  10. using System.Data.Common;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.Configuration;
  15. using System.IO;
  16. using System.Net;
  17. using NFine.Application.WMS;
  18. using NFine.Application.Models;
  19. using System.Reflection;
  20. using NFine.Application.Entity;
  21. using NFine.Domain.Entity.SystemSecurity;
  22. using System.Xml;
  23. using System.Collections;
  24. namespace NFine.Application.MFWMS
  25. {
  26. /// <summary>
  27. /// HUB仓销售出库、销售退货
  28. /// </summary>
  29. public class ICSSSDApp : RepositoryFactory<ICSVendor>
  30. {
  31. public static DataTable Invmes = new DataTable();
  32. /// <summary>
  33. /// 销售发货 汇总查询
  34. /// </summary>
  35. /// <param name="queryJson"></param>
  36. /// <param name="jqgridparam"></param>
  37. /// <returns></returns>
  38. public DataTable GetSDNBackApplyNeg(string queryJson, string Type, ref Pagination jqgridparam)
  39. {
  40. //站点信息
  41. string WorkPoint = NFine.Code.OperatorProvider.Provider.GetCurrent().Location;
  42. DataTable dt = new DataTable();
  43. List<DbParameter> parameter = new List<DbParameter>();
  44. var queryParam = queryJson.ToJObject();
  45. object Figure = GetDecimalDigits();
  46. #region [SQL]
  47. string sql = "";
  48. // 同步过来的销售发货 出库
  49. if (Type == "001")
  50. {
  51. // AccomplishFlag 决定是否完成了审核
  52. sql = @" select * from (
  53. select distinct ROW_NUMBER() OVER(PARTITION BY a.SDNCode, a.MUSERName,a.MTIME,a.Status,a.Type,a.ArriveDate,d.ID order by a.MTIME desc) RowFalg
  54. ,a.SDNCode, a.MUSERName,a.MTIME,a.Status,a.Type ,b.WarehouseCode as WHCode,b.WarehouseName as WHName,a.ArriveDate
  55. ,case when ISNULL(d.ID,'') != '' then 1 else 0 end as AccomplishFlag
  56. from ICSSDN a
  57. join ICSWarehouse b on a.WHCode = b.WarehouseCode and a.WorkPoint = b.WorkPoint
  58. join ICSInventory c on a.InvCode = c.InvCode and a.WorkPoint = b.WorkPoint
  59. left join ICSSSD d on a.SDNCode = d.SDNCode and a.Sequence = d.SDNSequence and a.WorkPoint=d.WorkPoint
  60. where a.Type = '1' ";
  61. sql = string.Format(sql, Figure);
  62. sql = string.Format(sql, DbHelper.GetErpIp(), DbHelper.GetErpName());
  63. }
  64. else
  65. {
  66. // AccomplishFlag 决定是否完成了审核
  67. // 销售退货 入库
  68. sql = @" select * from (
  69. select distinct ROW_NUMBER() OVER(PARTITION BY a.SDNCode, a.MUSERName,a.MTIME,a.Status,a.Type,a.ArriveDate,d.ID order by a.MTIME desc) RowFalg
  70. ,a.SDNCode, a.MUSERName,a.MTIME,a.Status,a.Type ,b.WarehouseCode as WHCode,b.WarehouseName as WHName,a.ArriveDate
  71. ,case when ISNULL(d.ID,'') != '' then 1 else 0 end as AccomplishFlag
  72. from ICSSDN a
  73. join ICSWarehouse b on a.WHCode = b.WarehouseCode and a.WorkPoint = b.WorkPoint
  74. join ICSInventory c on a.InvCode = c.InvCode and a.WorkPoint = b.WorkPoint
  75. left join ICSSSD d on a.SDNCode = d.SDNCode and a.Sequence = d.SDNSequence and a.InvCode = d.InvCode and a.WorkPoint=d.WorkPoint
  76. where a.Type = '2' ";
  77. sql = string.Format(sql, Figure);
  78. sql = string.Format(sql, DbHelper.GetErpIp(), DbHelper.GetErpName());
  79. }
  80. #endregion
  81. if (!string.IsNullOrWhiteSpace(queryJson))
  82. {
  83. if (!string.IsNullOrWhiteSpace(queryParam["POCode"].ToString()))
  84. {
  85. sql += " and a.SDNCode like '%" + queryParam["POCode"].ToString() + "%' ";
  86. }
  87. if (!string.IsNullOrWhiteSpace(queryParam["InvCode"].ToString()))
  88. {
  89. sql += " and a.InvCode like '%" + queryParam["InvCode"].ToString() + "%' ";
  90. }
  91. if (!string.IsNullOrWhiteSpace(queryParam["InvName"].ToString()))
  92. {
  93. sql += " and c.InvName like '%" + queryParam["InvName"].ToString() + "%' ";
  94. }
  95. if (!string.IsNullOrWhiteSpace(queryParam["WHCode"].ToString()))
  96. {
  97. sql += " and b.WarehouseCode like '%" + queryParam["WHCode"].ToString() + "%' ";
  98. }
  99. if (!string.IsNullOrWhiteSpace(queryParam["WHName"].ToString()))
  100. {
  101. sql += " and b.WarehouseName like '%" + queryParam["WHName"].ToString() + "%' ";
  102. }
  103. if (!string.IsNullOrWhiteSpace(queryParam["FromTime"].ToString()))
  104. {
  105. sql += " and a.ArriveDate >= '" + queryParam["FromTime"].ToString() + "' ";
  106. }
  107. if (!string.IsNullOrWhiteSpace(queryParam["ToTime"].ToString()))
  108. {
  109. sql += " and a.ArriveDate <= '" + queryParam["ToTime"].ToString() + "' ";
  110. }
  111. //if (!string.IsNullOrWhiteSpace(queryParam["BatchCode"].ToString()))
  112. //{
  113. // sql += " and f.BatchCode like '%" + queryParam["BatchCode"].ToString() + "%' ";
  114. //}
  115. if (!string.IsNullOrWhiteSpace(queryParam["AuditStatus"].ToString()))
  116. {
  117. var AuditStatus = queryParam["AuditStatus"].ToInt();
  118. if (AuditStatus == 1)
  119. {
  120. //已审核
  121. sql += " and ISNULL(d.ID,'') != '' ";
  122. }
  123. else if (AuditStatus == 2)
  124. {
  125. //未审核
  126. sql += " and ISNULL(d.ID,'') = '' ";
  127. }
  128. else
  129. {
  130. }
  131. }
  132. if (Type == "001")
  133. {
  134. if (!string.IsNullOrWhiteSpace(queryParam["SDNQtyFlag"].ToString()))
  135. {
  136. var SDNQtyFlag = queryParam["SDNQtyFlag"].ToInt();
  137. if (SDNQtyFlag == 1)
  138. {
  139. //已审核
  140. sql += " and a.SDNQuantity >= a.Quantity ";
  141. }
  142. else if (SDNQtyFlag == 2)
  143. {
  144. //未审核
  145. sql += " and a.SDNQuantity < a.Quantity ";
  146. }
  147. else
  148. {
  149. }
  150. }
  151. }
  152. }
  153. if (NFine.Code.OperatorProvider.Provider.GetCurrent().RoleEnCode != "admin")
  154. {
  155. sql += " and a.WorkPoint='" + NFine.Code.OperatorProvider.Provider.GetCurrent().Location + "'";
  156. }
  157. sql += @" --GROUP BY a.SDNCode, a.MUSERName,a.MTIME,a.Status,a.Type,a.ArriveDate,d.ID
  158. ) t where RowFalg = 1";
  159. return Repository().FindTablePageBySql(sql.ToString(), parameter.ToArray(), ref jqgridparam);
  160. }
  161. public object GetDecimalDigits()
  162. {
  163. string WorkPoint = NFine.Code.OperatorProvider.Provider.GetCurrent().Location.TrimEnd(',');
  164. try
  165. {
  166. string sql = string.Empty;
  167. sql = @"select Figure from ICSConfiguration where Code='Figure001' and Enable='1' and WorkPoint='" + WorkPoint + "'";
  168. object Figure = SqlHelper.ExecuteScalar(sql);
  169. return Figure;
  170. }
  171. catch (Exception ex)
  172. {
  173. throw new Exception(ex.Message.ToString());
  174. }
  175. }
  176. /// <summary>
  177. /// HUB销售出库
  178. /// </summary>
  179. /// <param name="queryJson"></param>
  180. /// <returns></returns>
  181. public string AuditDelSDN(string keyValue)
  182. {
  183. string msg = string.Empty;
  184. try
  185. {
  186. string WorkPoint = NFine.Code.OperatorProvider.Provider.GetCurrent().Location.TrimEnd(',');
  187. string UserName = NFine.Code.OperatorProvider.Provider.GetCurrent().UserName;
  188. string UserCode = NFine.Code.OperatorProvider.Provider.GetCurrent().UserCode;
  189. List<LOTStockModel> lOTStockModels = new List<LOTStockModel>();
  190. var dateNow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  191. var Code = keyValue.TrimEnd(',');
  192. //单据先进行拣料
  193. DataTable dateTable = GetICSMOPickMergeTemp(Code, "7");
  194. if (dateTable == null)
  195. {
  196. msg = "库存数据为空,请先检查库存";
  197. return msg;
  198. }
  199. DataRow[] dateRowsIsNull = dateTable?.Select($@"ISNULL(LotNo,'') = ''");
  200. //是否条码匹配错误
  201. if (dateRowsIsNull.Length > 0)
  202. {
  203. msg = "过滤空条码库存后库存数据为空,请先检查库存";
  204. return msg;
  205. }
  206. DataRow[] dateRows = dateTable?.Select($@"LotNo <> '' And LotNo is not null");
  207. //decimal ToltalCount = 0.0M;
  208. string tablesql = $@" SELECT ID,SDNCode,Sequence,Quantity FROM ICSSDN WHERE SDNCode in({Code}) and Type = '1' and WorkPoint='{WorkPoint}' ";
  209. var dt = SqlHelper.CmdExecuteDataTable(tablesql);
  210. if (dateRows == null || dateRows.Length <= 0)
  211. {
  212. msg = "过滤空条码库存后库存数据为空,请先检查库存";
  213. return msg;
  214. }
  215. else
  216. {
  217. string docCode = string.Empty;
  218. string docCodeAfter = string.Empty;
  219. LOTStockModel lOTStockModel = null;
  220. // 使用 LINQ 根据 Code 字段对 DataRow[] 进行分组
  221. var groups = dateRows.Cast<DataRow>().GroupBy(row => new
  222. {
  223. Code = row.Field<string>("Code"),
  224. Sequence = row.Field<string>("Sequence"),
  225. iQuantity = row.Field<string>("iQuantity")
  226. });
  227. //将捡料数据分组
  228. foreach (var group in groups)
  229. {
  230. var firstRow = group.First();
  231. var code = firstRow["Code"];
  232. decimal count = 0.0M;
  233. // 存储过程返回的条码 匹配到具体数据的ID
  234. DataRow[] SDNSequenceRow = dt?.Select("SDNCode='" + firstRow["Code"].ToString() + "' and Sequence='" + firstRow["Sequence"].ToString() + "'");
  235. if (SDNSequenceRow.Length <= 0)
  236. {
  237. msg = "条码未能匹配销售发货表!";
  238. return msg;
  239. }
  240. //出库数量
  241. decimal Qty = Convert.ToDecimal(SDNSequenceRow[0]["Quantity"]);
  242. lOTStockModel = new LOTStockModel
  243. {
  244. TransID = SDNSequenceRow[0]["ID"].ToString(),
  245. TransCode = firstRow["Code"].ToString(),
  246. TransSequence = firstRow["Sequence"].ToString(),
  247. TransType = "销售发货-销售发货单",
  248. Amount = "0",
  249. User = UserCode,
  250. Quantity = SDNSequenceRow[0]["Quantity"].ToString(),
  251. MTime = dateNow,
  252. WorkPoint = WorkPoint,
  253. detail = new List<LOTStockModelList>(),
  254. };
  255. foreach (var row in group)
  256. {
  257. count += row["QTY"].ToDecimal();
  258. LOTStockModelList lOTStockModelList = new LOTStockModelList
  259. {
  260. CurrentQuantity = row["QTY"].ToString(),
  261. LotNo = row["LotNo"].ToString(),
  262. CurrentAmount = "0",
  263. Sequence = row["Sequence"].ToString(),
  264. WarehouseCode = row["WarehouseCode"].ToString(),
  265. LocationCode = row["LocationCode"].ToString()
  266. };
  267. lOTStockModel.detail.Add(lOTStockModelList);
  268. }
  269. // 库存数量与出库审核数量对比
  270. if (Qty > count)
  271. {
  272. msg = "出库单编码:" + firstRow["Code"].ToString() + ",库存数量不足。当前库存数量:" + count.ToString();
  273. return msg;
  274. }
  275. //lOTStockModel.Quantity = count.ToString();
  276. lOTStockModels.Add(lOTStockModel);
  277. }
  278. string Inputstr = JsonConvert.SerializeObject(lOTStockModels.Distinct());
  279. string APIURL = ConfigurationManager.ConnectionStrings["APIURL"].ConnectionString + "LOTStockDown/Create";
  280. string result = HttpPost(APIURL, Inputstr);
  281. JObject Obj = (JObject)JsonConvert.DeserializeObject(result);//或者JObject jo = JObject.Parse(jsonText);
  282. string MessAge = Obj["Message"].ToString();
  283. string Success = Obj["Success"].ToString();
  284. if (Success.ToUpper() == "FALSE")
  285. {
  286. msg = MessAge;
  287. return msg;
  288. }
  289. //生成销售出库单
  290. string SDNsql = $@"select a.SDNCode,a.Sequence as SDNSequence,a.Amount,a.WHCode,a.CusCode,a.CusName,a.ArriveDate,a.InvCode,a.ExtensionID,a.Quantity
  291. from ICSSDN a where a.SDNCode in({Code}) and WorkPoint='{WorkPoint}' and a.Type = '1' ";
  292. DataTable SDNdt = SqlHelper.CmdExecuteDataTable(SDNsql);
  293. DataRow[] SDNRows = SDNdt?.Select($@"SDNCode <> '' And SDNCode is not null");
  294. var ICSSSDList = new List<ICSSSD>();
  295. var SDNgroups = SDNRows.Cast<DataRow>().GroupBy(row => new
  296. {
  297. Code = row.Field<string>("SDNCode"),
  298. });
  299. foreach (var SDNgroup in SDNgroups)
  300. {
  301. var SSDCode = GetOOCode(WorkPoint);
  302. foreach (var SDNitem in SDNgroup)
  303. {
  304. var index = 1;
  305. var entity = new ICSSSD
  306. {
  307. ID = Guid.NewGuid().ToString(),
  308. SSDCode = SSDCode,
  309. Quantity = Convert.ToDecimal(SDNitem["Quantity"]),
  310. Amount = Convert.ToDecimal(SDNitem["Amount"]),
  311. Status = "1",
  312. InvCode = SDNitem["InvCode"].ToString(),
  313. Sequence = index.ToString(),
  314. SDNCode = SDNitem["SDNCode"].ToString(),
  315. SDNSequence = SDNitem["SDNSequence"].ToString(),
  316. CusCode = SDNitem["CusCode"].ToString(),
  317. CusName = SDNitem["CusName"].ToString(),
  318. Type = "1",
  319. WHCode = SDNitem["WHCode"].ToString(),
  320. ArriveDate = Convert.ToDateTime(SDNitem["ArriveDate"]),
  321. CreateDateTime = Convert.ToDateTime(dateNow),
  322. CreatePerson = UserCode,
  323. SSDQuantity = 0,
  324. SSDDetailID = "",
  325. SSDID = "",
  326. MTIME = Convert.ToDateTime(dateNow),
  327. MUSER = UserCode,
  328. MUSERName = UserName,
  329. ExtensionID = SDNitem["ExtensionID"].ToString(),
  330. WorkPoint = WorkPoint,
  331. };
  332. ICSSSDList.Add(entity);
  333. }
  334. }
  335. var result1 = MsSqlData.Insert(ICSSSDList);
  336. if (!result1)
  337. {
  338. msg = "销售出库表新增失败!";
  339. return msg;
  340. }
  341. }
  342. }
  343. catch (Exception ex)
  344. {
  345. msg = ex.Message;
  346. }
  347. return msg;
  348. }
  349. /// <summary>
  350. /// HUB销售退货
  351. /// </summary>
  352. /// <param name="queryJson"></param>
  353. /// <returns></returns>
  354. public string AuditSalesReturnSDN(string keyValue, string WhCode, string LotCode)
  355. {
  356. //准备条码回滚
  357. var lotNoArr = "";
  358. string MUSER = NFine.Code.OperatorProvider.Provider.GetCurrent().UserCode;
  359. string WorkPoint = NFine.Code.OperatorProvider.Provider.GetCurrent().Location;
  360. string MUSERNAME = NFine.Code.OperatorProvider.Provider.GetCurrent().UserName;
  361. string msg = "";
  362. DateTime TimeNow = DateTime.Now;
  363. string sqls = string.Empty;
  364. string sql = string.Empty;
  365. //根据退货单找到销售订单,找到对应出库单,根据出库单列表中最新的批次排序
  366. //生成一条条码数据
  367. try
  368. {
  369. keyValue = keyValue.TrimEnd(',');
  370. //根据退货单找到销售订单 废弃
  371. //取退货单上的批次
  372. string SOList = $@"
  373. select a.SDNCode,a.Sequence,a.InvCode,a.SOCode,a.SOSequence,a.Type,a.ExtensionID,e.BatchCode,a.Amount,a.Quantity,a.WHCode
  374. from ICSSDN a
  375. left join ICSExtension e on a.ExtensionID = e.ID and a.WorkPoint = e.WorkPoint
  376. where a.SDNCode in ({keyValue}) and a.Type = '2' and a.WorkPoint='{WorkPoint}' ";
  377. DataTable SOListdt = SqlHelper.CmdExecuteDataTable(SOList);
  378. if (SOListdt.Rows.Count <= 0)
  379. {
  380. throw new Exception("未找到退货单!");
  381. }
  382. else
  383. {
  384. //判断退货单仓库和输入的仓库是否一致 yangtm 20251217
  385. string mes = string.Empty;
  386. foreach (DataRow dr1 in SOListdt.Rows)
  387. {
  388. if (dr1["WhCode"].ToString() != WhCode)
  389. {
  390. mes += "退货单" + dr1["WhCode"].ToString() + "行" + dr1["Sequence"].ToString() + "仓库" + dr1["WhCode"].ToString() + "和本次退货仓库" + WhCode + "不一致,请确认";
  391. }
  392. }
  393. if (!string.IsNullOrWhiteSpace(mes))
  394. {
  395. throw new Exception(mes);
  396. }
  397. List<LOTStockUpCreateIModel> models = new List<LOTStockUpCreateIModel>();
  398. //找到对应出库单 若退货单上没有批次 则用出库单最新的批次
  399. //根据单据号分组
  400. //DataRow[] dateRows = SOListdt?.Select($@"SOCode <> '' And SOCode is not null");
  401. //if (dateRows.Length <= 0)
  402. //{
  403. // throw new Exception("退货单未关联销售订单!");
  404. //}
  405. // 使用 LINQ 根据 界面选择的单据号 字段对 DataRow[] 进行分组 分组后 每
  406. var groups = SOListdt.Rows.Cast<DataRow>().GroupBy(row => new
  407. {
  408. Code = row.Field<string>("SDNCode"),
  409. });
  410. foreach (var group in groups)
  411. {
  412. //model在循环内还是外 决定 API中请求ERP的次数
  413. LOTStockUpCreateIModel model = new LOTStockUpCreateIModel
  414. {
  415. User = MUSER,
  416. MTime = TimeNow.ToString("yyyy-MM-dd HH:mm:ss"),
  417. WorkPoint = WorkPoint,
  418. TransType = "销售退货-销售退货单",
  419. detail = new List<LOTStockUpCreateIModelList>()
  420. };
  421. foreach (var item in group)
  422. {
  423. var ExtensionID = "";
  424. string LotNo = "";
  425. //判断 退货数据中有批次,就直接用
  426. if (!string.IsNullOrEmpty(item["ExtensionID"].ToString()))
  427. {
  428. ExtensionID = item["ExtensionID"].ToString();
  429. }
  430. else
  431. {
  432. throw new Exception("关联批次创建条码失败,未找到批次!");
  433. //判断 退货没批次 找销售订单管理的出库表 最新的批次
  434. //SOList = $@"
  435. // -- 找同销售订单下的发货单、出库单 得到销售单的结果
  436. //if exists(select * from tempdb..sysobjects where id=object_id('tempdb..#tempDeliver'))
  437. //begin
  438. // drop table #tempDeliver
  439. //end
  440. //-- 退货临时表 关联发货表 为了结果集直接拿到退货表需要的批次
  441. //select a.SDNCode,a.Sequence,a.InvCode,a.SOCode,a.SOSequence,a.Type,a.WorkPoint into #tempDeliver
  442. //from ICSSDN a where a.SOCode = '{item["SOCode"].ToString()}' and a.SOSequence = '{item["SOSequence"].ToString()}' and a.InvCode = '{item["InvCode"].ToString()}' and Type = '2'
  443. //-- 查询销售出库表 按批次、时间倒叙 找最后一个批次
  444. //select TOP(1) ROW_NUMBER() OVER(PARTITION BY a.SOCode,a.SOSequence ORDER BY e.BatchCode,e.MTIME desc),
  445. //a.SDNCode,a.Sequence,a.InvCode,a.SOCode,a.SOSequence,a.Type,e.BatchCode,e.MTIME,a.MTIME,e.ID as ExtensionID
  446. //from ICSSDN a
  447. //join #tempDeliver q on a.SOCode = q.SOCode and a.SOSequence = q.SOSequence and a.InvCode = q.InvCode and a.WorkPoint = q.WorkPoint
  448. //Left join ICSSSD b on a.SDNCode = b.SDNCode and a.Sequence = b.SDNSequence and a.WorkPoint = b.WorkPoint
  449. //left join ICSExtension e on b.ExtensionID = e.ID and b.WorkPoint = e.WorkPoint
  450. //where a.Type = '1'
  451. //if exists(select * from tempdb..sysobjects where id=object_id('tempdb..#tempDeliver'))
  452. //begin
  453. // drop table #tempDeliver
  454. //end ";
  455. //DataTable SDNdt = SqlHelper.CmdExecuteDataTable(SOList);
  456. //ExtensionID = string.IsNullOrEmpty(SDNdt.Rows[0]["ExtensionID"].ToString()) && SDNdt.Rows[0]["ExtensionID"].ToString() != "NULL" ? SDNdt.Rows[0]["ExtensionID"].ToString() : "";
  457. }
  458. //创建新的条码入库
  459. var SDNCode = item["SDNCode"].ToString();
  460. string Sequence = item["Sequence"].ToString();
  461. var sqlLot = string.Format(@"SELECT A.LotNO AS LOTNO FROM ICSInventoryLot A WHERE A.LotNO LIKE '{0}%'", SDNCode);
  462. var parentLot = Repository().FindTableBySql(sqlLot.ToString());
  463. var drs = parentLot.Select("1 = 1", "LOTNO DESC");
  464. if (drs.Length == 0)
  465. {
  466. LotNo = SDNCode + Sequence + "00001";
  467. }
  468. else
  469. {
  470. var OldLotNo = drs[0]["LOTNO"].ToString();
  471. LotNo = SDNCode + Sequence + (Convert.ToInt64(OldLotNo.Substring(OldLotNo.Length - 5)) + 1).ToString().PadLeft(5, '0');
  472. }
  473. lotNoArr = string.IsNullOrEmpty(lotNoArr) ? "'" + LotNo + "'" : lotNoArr + "," + "'" + LotNo + "'";
  474. sqls += @"INSERT INTO ICSInventoryLot(ID,LotNo,InvCode,ProductDate,ExpirationDate,Quantity,Amount,ExtensionID,Type,
  475. PrintTimes,LastPrintUser,LastPrintTime,MUSER,MUSERName,MTIME,WorkPoint)
  476. Values(NEWID(),'{0}','{1}',getdate(),'2999-12-31','{2}','{3}','{4}','100','','','','{5}','{6}',getdate(),'{7}')
  477. ";
  478. sqls += @"INSERT INTO ICSInventoryLotDetail( LotNo,TransCode,TransSequence,MUSER,MUSERName,MTIME,WorkPoint)
  479. Values('{0}','{8}','{9}','{5}','{6}',getdate(),'{7}')
  480. ";
  481. //循环中不妨碍多次执行sql的替换 因为每次都只会替换{0}特殊字符 每次循环都只有一个{0}
  482. sqls = string.Format(sqls, LotNo, item["InvCode"].ToString(), item["Quantity"].ToString(), item["Amount"].ToString(), ExtensionID, MUSER, MUSERNAME, WorkPoint, SDNCode, Sequence);
  483. //完成数据准备
  484. LOTStockUpCreateIModelList detail = new LOTStockUpCreateIModelList
  485. {
  486. LotNo = LotNo,
  487. WarehouseCode = WhCode,
  488. LocationCode = LotCode,
  489. TransCode = item["SDNCode"].ToString(),
  490. TransSequence = item["Sequence"].ToString(),
  491. Quantity = item["Quantity"].ToString(),
  492. InvCode = item["InvCode"].ToString()
  493. };
  494. model.detail.Add(detail);
  495. }
  496. //此时 每个SOListdt结果集的行 都会请求一次ERP 将new model的动作移动到循环外即可只请求一次
  497. models.Add(model);
  498. }
  499. if (!String.IsNullOrEmpty(sqls))
  500. {
  501. SqlHelper.CmdExecuteNonQueryLi(sqls);
  502. }
  503. var input = models.Distinct().ToJson();
  504. string APIURL = ConfigurationManager.ConnectionStrings["APIURL"].ConnectionString + "LOTStockUp/Create";
  505. string result = HttpPost(APIURL, input);
  506. Result res = result.ToObject<Result>();
  507. if (!res.Success)
  508. {
  509. throw new Exception(res.Message);
  510. }
  511. //生成销售出库单
  512. string SDNsql = $@"select a.SDNCode,a.Sequence as SDNSequence,a.Amount,a.WHCode,a.CusCode,a.CusName,a.ArriveDate,a.InvCode,a.ExtensionID,a.Quantity
  513. from ICSSDN a where a.SDNCode in({keyValue}) and WorkPoint='{WorkPoint}' and a.Type = '2' ";
  514. DataTable SDNToCreatedt = SqlHelper.CmdExecuteDataTable(SDNsql);
  515. DataRow[] SDNRows = SDNToCreatedt?.Select($@"SDNCode <> '' And SDNCode is not null");
  516. var ICSSSDList = new List<ICSSSD>();
  517. var SDNgroups = SDNRows.Cast<DataRow>().GroupBy(row => new
  518. {
  519. Code = row.Field<string>("SDNCode"),
  520. });
  521. foreach (var SDNgroup in SDNgroups)
  522. {
  523. var SSDCode = GetOOCode(WorkPoint);
  524. foreach (var SDNitem in SDNgroup)
  525. {
  526. var index = 1;
  527. var entity = new ICSSSD
  528. {
  529. ID = Guid.NewGuid().ToString(),
  530. SSDCode = SSDCode,
  531. Quantity = Convert.ToDecimal(SDNitem["Quantity"]),
  532. Amount = Convert.ToDecimal(SDNitem["Amount"]),
  533. Status = "1",
  534. InvCode = SDNitem["InvCode"].ToString(),
  535. Sequence = index.ToString(),
  536. SDNCode = SDNitem["SDNCode"].ToString(),
  537. SDNSequence = SDNitem["SDNSequence"].ToString(),
  538. CusCode = SDNitem["CusCode"].ToString(),
  539. CusName = SDNitem["CusName"].ToString(),
  540. Type = "2",
  541. WHCode = SDNitem["WHCode"].ToString(),
  542. ArriveDate = Convert.ToDateTime(SDNitem["ArriveDate"]),
  543. CreateDateTime = TimeNow,
  544. CreatePerson = MUSER,
  545. SSDQuantity = 0,
  546. SSDDetailID = "",
  547. SSDID = "",
  548. MTIME = TimeNow,
  549. MUSER = MUSER,
  550. MUSERName = MUSERNAME,
  551. ExtensionID = SDNitem["ExtensionID"].ToString(),
  552. WorkPoint = WorkPoint,
  553. };
  554. ICSSSDList.Add(entity);
  555. }
  556. }
  557. var result1 = MsSqlData.Insert(ICSSSDList);
  558. if (!result1)
  559. {
  560. msg = "销售出库表新增失败!";
  561. return msg;
  562. }
  563. }
  564. }
  565. catch (Exception ex)
  566. {
  567. //回退
  568. if (!string.IsNullOrEmpty(lotNoArr))
  569. {
  570. sqls = $@"
  571. delete from ICSInventoryLot where LotNo in ({lotNoArr}) and WorkPoint = '{WorkPoint}'
  572. delete from ICSInventoryLotDetail where LotNo in ({lotNoArr}) and WorkPoint = '{WorkPoint}'
  573. delete from ICSSSD where SDNCode in ({keyValue}) and Type = 2 and WorkPoint = '{WorkPoint}' ";
  574. SqlHelper.CmdExecuteNonQueryLi(sqls);
  575. }
  576. throw new Exception(ex.Message);
  577. }
  578. return msg;
  579. }
  580. /// <summary>
  581. /// 创建自增单号
  582. /// </summary>
  583. /// <param name="WorkPoint"></param>
  584. /// <returns></returns>
  585. public string GetOOCode(string WorkPoint)
  586. {
  587. WorkPoint = NFine.Code.OperatorProvider.Provider.GetCurrent().Location;
  588. string OOCode = string.Empty;
  589. if (!string.IsNullOrEmpty(WorkPoint))
  590. {
  591. OOCode = GetSerialCode(WorkPoint, "ICSSSD", "SSDCode", "00", 8);
  592. }
  593. if (!string.IsNullOrWhiteSpace(OOCode))
  594. {
  595. string sqlISHave = @"SELECT SSDCode FROM ICSSSD a
  596. WHERE a.SSDCode = '{0}'";
  597. sqlISHave = string.Format(sqlISHave, OOCode);
  598. DataTable dtIsHave = SqlHelper.GetDataTableBySql(sqlISHave);
  599. if (dtIsHave.Rows.Count > 0)
  600. {
  601. throw new Exception("单号已存在!");
  602. }
  603. }
  604. return OOCode;
  605. }
  606. public string GetSerialCode(string workPointCode, string tbName, string colName, string Pre, int numLen)
  607. {
  608. string sql = "EXEC Addins_GetSerialCode '{0}','{1}','{2}','{3}',{4}";
  609. sql = string.Format(sql, new object[] { workPointCode, tbName, colName, Pre, numLen });
  610. return SqlHelper.ExecuteScalar(sql).ToString();
  611. }
  612. /// <summary>
  613. /// 销售发货明细查询
  614. /// </summary>
  615. /// <param name="jqgridparam"></param>
  616. /// <returns></returns>
  617. public DataTable GetSDNApplyNegDetail(string SDNCode, ref Pagination jqgridparam)
  618. {
  619. DataTable dt = new DataTable();
  620. //object Figure = GetDecimalDigits();
  621. List<DbParameter> parameter = new List<DbParameter>();
  622. string sql = @"SELECT a.ID,a.SDNCode,a.Sequence,a.SOSequence,a.SOCode,a.InvCode,a.Quantity,a.Amount,a.SDNQuantity,a.WHCode,e.WarehouseName as WHName,a.Type,a.CusCode,a.CusName,a.ArriveDate
  623. ,a.ExtensionID,a.MUSER,a.MUSERName,a.MTIME,a.WorkPoint,b.InvName,a.CreateDateTime,a.CreatePerson
  624. ,f.Colspan ,f.ProjectCode ,f.BatchCode ,f.Version ,f.Brand ,f.cFree1 ,f.cFree2 ,f.cFree3 ,f.cFree4
  625. ,f.cFree5 ,f.cFree6 ,f.cFree7 ,f.cFree8 ,f.cFree9 ,f.cFree10
  626. ,a.EATTRIBUTE1,a.EATTRIBUTE2,a.EATTRIBUTE3,a.EATTRIBUTE4,a.EATTRIBUTE5,a.EATTRIBUTE6,a.EATTRIBUTE7,a.EATTRIBUTE8,a.EATTRIBUTE9,a.EATTRIBUTE10
  627. from ICSSDN a
  628. left join ICSInventory b on a.InvCode = b.InvCode and a.WorkPoint = b.WorkPoint
  629. left join ICSExtension f on a.ExtensionID=f.ID and a.WorkPoint=f.WorkPoint
  630. left join ICSWarehouse e on a.WHCode = e.WarehouseCode and a.WorkPoint=e.WorkPoint
  631. -- left join ICSSSD d on a.SDNCode = d.SDNCode and a.Sequence = d.SDNSequence and a.InvCode = d.InvCode and a.WorkPoint=d.WorkPoint
  632. where a.SDNCode = '" + SDNCode + "' ";
  633. //sql = string.Format(sql, Figure);
  634. DataTable dttest = Repository().FindTablePageBySql(sql.ToString(), parameter.ToArray(), ref jqgridparam);
  635. return Repository().FindTablePageBySql(sql.ToString(), parameter.ToArray(), ref jqgridparam);
  636. }
  637. //拣料
  638. public DataTable GetICSMOPickMergeTemp(string ID, string Type)
  639. {
  640. string MUSER = NFine.Code.OperatorProvider.Provider.GetCurrent().UserCode;
  641. string MUSERNAME = NFine.Code.OperatorProvider.Provider.GetCurrent().UserName;
  642. string WorkPoint = NFine.Code.OperatorProvider.Provider.GetCurrent().Location;
  643. ID = ID.Replace("'", "''");
  644. ID = string.IsNullOrWhiteSpace(ID) ? "''" : ID.TrimEnd(',');
  645. string Code = SqlHelper.GetItemsDetailEnabledMark("MtimeControl");
  646. string sql = @"EXEC ICSPicking '{0}','{1}','0','{2}'";
  647. sql = string.Format(sql, ID, Type, WorkPoint);
  648. var dataset = Repository().FindDataSetBySql(sql);
  649. if (dataset.Tables[0].Rows.Count == 0)
  650. return null;
  651. DataTable table = dataset.Tables[0];
  652. try
  653. {
  654. DataRow[] dss = table.Select("LotNO=''");
  655. foreach (var item in dss)
  656. {
  657. DataRow[] dsss = table.Select("Code='" + item["Code"].ToString() + "' and Sequence='" + item["Sequence"].ToString() + "' and LotNO <> '' ");
  658. if (dsss != null && dsss.Length > 0)
  659. {
  660. table.Rows.Remove(item);
  661. }
  662. }
  663. var result = ConvertCellToString(table);
  664. if (Invmes.Rows.Count > 0)
  665. {
  666. result.Merge(Invmes, false);
  667. }
  668. var groupedData = from row in table.AsEnumerable()
  669. group row by new
  670. {
  671. Code = row.Field<string>("Code"),
  672. Sequence = row.Field<string>("Sequence")
  673. } into g
  674. select new
  675. {
  676. Code = g.Key.Code,
  677. Sequence = g.Key.Sequence,
  678. TotalQTY = g.Sum(x =>
  679. {
  680. return !x.IsNull("QTY") ? x.Field<decimal>("QTY") : 0;
  681. }),
  682. TotaliQuantity = g.First().IsNull("iQuantity") ? 0 : g.First().Field<decimal>("iQuantity"),
  683. };
  684. foreach (var item in groupedData)
  685. {
  686. if (item.TotalQTY != item.TotaliQuantity)
  687. {
  688. string msg = "单据号:" + item.Code + "行号:" + item.Sequence + "库存不足,请先检查库存";
  689. throw new Exception(msg);
  690. }
  691. }
  692. return result;
  693. }
  694. catch (Exception ex)
  695. {
  696. throw new Exception(ex.Message);
  697. }
  698. }
  699. public DataTable ConvertCellToString(DataTable data)
  700. {
  701. DataTable dtCloned = data.Clone();
  702. foreach (DataColumn col in dtCloned.Columns)
  703. {
  704. col.DataType = typeof(string);
  705. }
  706. foreach (DataRow row in data.Rows)
  707. {
  708. DataRow newrow = dtCloned.NewRow();
  709. foreach (DataColumn column in dtCloned.Columns)
  710. {
  711. newrow[column.ColumnName] = row[column.ColumnName].ToString();
  712. }
  713. dtCloned.Rows.Add(newrow);
  714. }
  715. return dtCloned;
  716. }
  717. //接口api解析
  718. public static string HttpPost(string url, string body)
  719. {
  720. try
  721. {
  722. Encoding encoding = Encoding.UTF8;
  723. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  724. request.Method = "POST";
  725. request.Accept = "application/json, text/javascript, */*"; //"text/html, application/xhtml+xml, */*";
  726. request.ContentType = "application/json; charset=utf-8";
  727. byte[] buffer = encoding.GetBytes(body);
  728. request.ContentLength = buffer.Length;
  729. request.GetRequestStream().Write(buffer, 0, buffer.Length);
  730. HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  731. using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding))
  732. {
  733. return reader.ReadToEnd();
  734. }
  735. }
  736. catch (WebException ex)
  737. {
  738. throw new Exception(ex.Message);
  739. }
  740. }
  741. public void ClearTemp()
  742. {
  743. Invmes.Rows.Clear();
  744. }
  745. /// <summary>
  746. /// 材料出库
  747. /// </summary>
  748. public class LOTStockModel
  749. {
  750. /// <summary>
  751. /// 源头单据号
  752. /// </summary>
  753. public string TransCode { get; set; }
  754. /// <summary>
  755. /// 源头单据行号
  756. /// </summary>
  757. public string TransSequence { get; set; }
  758. /// <summary>
  759. /// 源头单据iD
  760. /// </summary>
  761. public string TransID { get; set; }
  762. /// <summary>
  763. /// 数量
  764. /// </summary>
  765. public string Quantity { get; set; }
  766. /// <summary>
  767. /// 辅计量数量
  768. /// </summary>
  769. public string Amount { get; set; }
  770. /// <summary>
  771. /// 操作类型
  772. /// </summary>
  773. public string TransType { get; set; }
  774. /// <summary>
  775. /// 操作人
  776. /// </summary>
  777. public string User { get; set; }
  778. /// <summary>
  779. /// 操作时间
  780. /// </summary>
  781. public string MTime { get; set; }
  782. /// <summary>
  783. /// 交接人--东辉
  784. /// </summary>
  785. public string Heir { get; set; }
  786. //站点
  787. public string WorkPoint { get; set; }
  788. //快递单号
  789. public string CourierCode { get; set; }
  790. public List<LOTStockModelList> detail { get; set; }
  791. }
  792. public class LOTStockModelList
  793. {
  794. /// <summary>
  795. /// 源头单据行号
  796. /// </summary>
  797. public string TransSequence { get; set; }
  798. /// <summary>
  799. /// 条码
  800. /// </summary>
  801. public string LotNo { get; set; }
  802. /// <summary>
  803. /// 数量
  804. /// </summary>
  805. public string CurrentQuantity { get; set; }
  806. /// <summary>
  807. /// 辅计量数量
  808. /// </summary>
  809. public string CurrentAmount { get; set; }
  810. public string Sequence { get; set; }
  811. /// <summary>
  812. /// 仓库代码
  813. /// </summary>
  814. public string WarehouseCode { get; set; }
  815. /// <summary>
  816. /// 库位代码
  817. /// </summary>
  818. public string LocationCode { get; set; }
  819. /// <summary>
  820. /// LogID
  821. /// </summary>
  822. public string LogID { get; set; }
  823. }
  824. }
  825. }