PurchaseRequestService.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. using Yitter.IdGenerator;
  2. namespace Admin.NET.Plugin.AiDOP.Supply;
  3. /// <summary>
  4. /// 物料采购申请服务
  5. /// </summary>
  6. [ApiDescriptionSettings(Order = 308, Description = "物料采购申请")]
  7. [Route("api/Supply")]
  8. [AllowAnonymous]
  9. [NonUnify]
  10. public class PurchaseRequestService : IDynamicApiController, ITransient
  11. {
  12. private readonly ISqlSugarClient _db;
  13. private readonly UserManager _userManager;
  14. public PurchaseRequestService(ISqlSugarClient db, UserManager userManager)
  15. {
  16. _db = db;
  17. _userManager = userManager;
  18. }
  19. [DisplayName("物料采购申请列表")]
  20. [HttpGet("purchase-request/list")]
  21. public async Task<object> GetList([FromQuery] PurchaseRequestListInput input)
  22. {
  23. var page = input.Page <= 0 ? 1 : input.Page;
  24. var pageSize = input.PageSize <= 0 ? 10 : input.PageSize;
  25. var offset = (page - 1) * pageSize;
  26. var pars = new List<SugarParameter>();
  27. var where = new List<string>
  28. {
  29. "IFNULL(pm.IsDeleted,0)=0",
  30. "IFNULL(pm.state,0)<>0",
  31. "IFNULL(pm.analogcalcversion,'')=''"
  32. };
  33. if (_userManager.TenantId > 0)
  34. {
  35. where.Add("pm.tenant_id=@TenantId");
  36. pars.Add(new SugarParameter("@TenantId", _userManager.TenantId));
  37. }
  38. if (!string.IsNullOrWhiteSpace(input.PrBillNo))
  39. {
  40. where.Add("pm.pr_billno LIKE @PrBillNo");
  41. pars.Add(new SugarParameter("@PrBillNo", $"%{input.PrBillNo.Trim()}%"));
  42. }
  43. if (!string.IsNullOrWhiteSpace(input.ItemNumber))
  44. {
  45. where.Add("ic.number LIKE @ItemNumber");
  46. pars.Add(new SugarParameter("@ItemNumber", $"%{input.ItemNumber.Trim()}%"));
  47. }
  48. if (!string.IsNullOrWhiteSpace(input.SupplierName))
  49. {
  50. where.Add("pm.pr_purchasename LIKE @SupplierName");
  51. pars.Add(new SugarParameter("@SupplierName", $"%{input.SupplierName.Trim()}%"));
  52. }
  53. if (input.State.HasValue)
  54. {
  55. where.Add("pm.state=@State");
  56. pars.Add(new SugarParameter("@State", input.State.Value));
  57. }
  58. var orderBy = BuildOrderBy(input.SortField, input.SortOrder);
  59. var fromSql = $"""
  60. FROM srm_pr_main pm
  61. LEFT JOIN ic_item ic ON pm.icitem_id=ic.Id
  62. LEFT JOIN srm_purchase pur ON pm.icitem_id=pur.icitem_id AND pm.pr_purchaseid = pur.supplier_id
  63. LEFT JOIN ic_item_stock its ON ic.Id=its.icitem_id
  64. LEFT JOIN PurOrdDetail pod ON pm.pr_billno=pod.Req OR pm.SAP_pr_billno=pod.Req
  65. WHERE {string.Join(" AND ", where)}
  66. """;
  67. var total = await _db.Ado.GetIntAsync($"SELECT COUNT(1) FROM (SELECT DISTINCT pm.Id {fromSql}) t", pars);
  68. var list = await _db.Ado.SqlQueryAsync<PurchaseRequestListRow>(
  69. $"""
  70. SELECT
  71. pm.id AS Id,
  72. pm.pr_billno AS PrBillNo,
  73. pod.PurOrd AS PurOrd,
  74. pm.pr_type AS PrType,
  75. pm.supplier_type AS SupplierType,
  76. pm.IsRequireGoods AS IsRequireGoods,
  77. pm.state AS State,
  78. ic.number AS Number,
  79. ic.name AS Name,
  80. ic.model AS Model,
  81. pm.pr_unit AS PrUnit,
  82. pm.pr_purchasenumber AS PrPurchaseNumber,
  83. pm.pr_purchasename AS PrPurchaseName,
  84. pm.pr_sqty AS PrSqty,
  85. pm.pr_aqty AS PrAqty,
  86. its.sqty AS StockQty,
  87. pm.pr_ssend_date AS PrSsendDate,
  88. pm.pr_sarrive_date AS PrSarriveDate,
  89. pm.pr_purchaser AS PrPurchaser,
  90. pm.create_time AS CreateTime
  91. {fromSql}
  92. ORDER BY {orderBy}
  93. LIMIT {pageSize} OFFSET {offset}
  94. """,
  95. pars);
  96. return new { total, page, pageSize, list };
  97. }
  98. [DisplayName("获取物料采购申请详情")]
  99. [HttpGet("purchase-request/{id:long}")]
  100. public async Task<object> GetDetail(long id)
  101. {
  102. var row = (await _db.Ado.SqlQueryAsync<PurchaseRequestDetailRow>(
  103. """
  104. SELECT
  105. pm.id AS Id,
  106. pm.pr_billno AS PrBillNo,
  107. pm.icitem_id AS IcitemId,
  108. pm.icitem_name AS IcitemName,
  109. pm.pr_unit AS PrUnit,
  110. pm.pr_purchasenumber AS PrPurchaseNumber,
  111. pm.pr_purchasename AS PrPurchaseName,
  112. pm.supplier_type AS SupplierType,
  113. pm.pr_aqty AS PrAqty,
  114. pm.pr_ssend_date AS PrSsendDate,
  115. pm.pr_sarrive_date AS PrSarriveDate,
  116. pm.pr_type AS PrType,
  117. pm.state AS State,
  118. pm.pr_purchaseid AS PrPurchaseId,
  119. pm.IsRequireGoods AS IsRequireGoods,
  120. pm.pr_purchaser_num AS PrPurchaserNum,
  121. pm.pr_purchaser AS PrPurchaser,
  122. pm.currencytype AS CurrencyType
  123. FROM srm_pr_main pm
  124. WHERE pm.Id=@Id AND IFNULL(pm.IsDeleted,0)=0
  125. LIMIT 1
  126. """,
  127. new SugarParameter("@Id", id))).FirstOrDefault();
  128. return row ?? throw Oops.Oh("记录不存在");
  129. }
  130. [DisplayName("保存物料采购申请")]
  131. [ApiDescriptionSettings(Name = "SavePurchaseRequest"), HttpPost("purchase-request/save")]
  132. public async Task<object> Save([FromBody] PurchaseRequestSaveInput input)
  133. {
  134. if (!input.IcitemId.HasValue || input.IcitemId.Value <= 0) throw Oops.Oh("请选择物料");
  135. if (input.PrPurchaseId is null or <= 0) throw Oops.Oh("请选择供应商");
  136. if (!input.PrAqty.HasValue || input.PrAqty.Value <= 0) throw Oops.Oh("申请数量必须大于0");
  137. var now = DateTime.Now;
  138. var aqty = input.PrAqty.Value;
  139. var prSsendDate = ParseDate(input.PrSsendDate) ?? now.Date;
  140. var prSarriveDate = ParseDate(input.PrSarriveDate);
  141. var prType = input.PrType ?? 3;
  142. var state = input.State ?? 1;
  143. var currency = input.CurrencyType ?? 1;
  144. var companyId = _userManager.OrgId > 0 ? _userManager.OrgId : 1000;
  145. if (input.Id is null or 0)
  146. {
  147. var newId = YitIdHelper.NextId();
  148. var billNo = string.IsNullOrWhiteSpace(input.PrBillNo) ? GenerateBillNo() : input.PrBillNo.Trim();
  149. await _db.Ado.ExecuteCommandAsync(
  150. """
  151. INSERT INTO srm_pr_main
  152. (Id,pr_billno,pr_purchaseid,pr_purchasenumber,pr_purchasename,pr_purchaser,pr_purchaser_num,
  153. pr_rqty,pr_aqty,pr_sqty,icitem_id,icitem_name,pr_ssend_date,pr_sarrive_date,pr_unit,state,pr_type,currencytype,
  154. create_by,create_by_name,create_time,update_by,update_by_name,update_time,tenant_id,factory_id,org_id,IsDeleted,company_id,IsRequireGoods,supplier_type)
  155. VALUES
  156. (@Id,@PrBillNo,@PrPurchaseId,@PrPurchaseNumber,@PrPurchaseName,@PrPurchaser,@PrPurchaserNum,
  157. @PrRqty,@PrAqty,@PrSqty,@IcitemId,@IcitemName,@PrSsendDate,@PrSarriveDate,@PrUnit,@State,@PrType,@CurrencyType,
  158. @CreateBy,@CreateByName,@CreateTime,@UpdateBy,@UpdateByName,@UpdateTime,@TenantId,@FactoryId,@OrgId,@IsDeleted,@CompanyId,@IsRequireGoods,@SupplierType)
  159. """,
  160. new SugarParameter("@Id", newId),
  161. new SugarParameter("@PrBillNo", billNo),
  162. new SugarParameter("@PrPurchaseId", input.PrPurchaseId!.Value),
  163. new SugarParameter("@PrPurchaseNumber", input.PrPurchaseNumber?.Trim()),
  164. new SugarParameter("@PrPurchaseName", input.PrPurchaseName?.Trim()),
  165. new SugarParameter("@PrPurchaser", input.PrPurchaser?.Trim()),
  166. new SugarParameter("@PrPurchaserNum", input.PrPurchaserNum?.Trim()),
  167. new SugarParameter("@PrRqty", aqty),
  168. new SugarParameter("@PrAqty", aqty),
  169. new SugarParameter("@PrSqty", aqty),
  170. new SugarParameter("@IcitemId", input.IcitemId!.Value),
  171. new SugarParameter("@IcitemName", input.IcitemName?.Trim()),
  172. new SugarParameter("@PrSsendDate", prSsendDate),
  173. new SugarParameter("@PrSarriveDate", prSarriveDate),
  174. new SugarParameter("@PrUnit", input.PrUnit?.Trim()),
  175. new SugarParameter("@State", state),
  176. new SugarParameter("@PrType", prType),
  177. new SugarParameter("@CurrencyType", currency),
  178. new SugarParameter("@CreateBy", _userManager.UserId),
  179. new SugarParameter("@CreateByName", _userManager.Account),
  180. new SugarParameter("@CreateTime", now),
  181. new SugarParameter("@UpdateBy", _userManager.UserId),
  182. new SugarParameter("@UpdateByName", _userManager.Account),
  183. new SugarParameter("@UpdateTime", now),
  184. new SugarParameter("@TenantId", _userManager.TenantId),
  185. new SugarParameter("@FactoryId", _userManager.OrgId),
  186. new SugarParameter("@OrgId", _userManager.OrgId),
  187. new SugarParameter("@IsDeleted", 0),
  188. new SugarParameter("@CompanyId", companyId),
  189. new SugarParameter("@IsRequireGoods", input.IsRequireGoods ?? 0),
  190. new SugarParameter("@SupplierType", input.SupplierType?.Trim())
  191. );
  192. return new { id = newId, prBillNo = billNo, message = "新增成功" };
  193. }
  194. else
  195. {
  196. var exist = await _db.Ado.GetIntAsync(
  197. "SELECT COUNT(1) FROM srm_pr_main WHERE Id=@Id AND IFNULL(IsDeleted,0)=0",
  198. new SugarParameter("@Id", input.Id.Value));
  199. if (exist <= 0) throw Oops.Oh("记录不存在");
  200. await _db.Ado.ExecuteCommandAsync(
  201. """
  202. UPDATE srm_pr_main
  203. SET
  204. pr_purchaseid=@PrPurchaseId,
  205. pr_purchasenumber=@PrPurchaseNumber,
  206. pr_purchasename=@PrPurchaseName,
  207. pr_purchaser=@PrPurchaser,
  208. pr_purchaser_num=@PrPurchaserNum,
  209. pr_rqty=@PrRqty,
  210. pr_aqty=@PrAqty,
  211. pr_sqty=@PrSqty,
  212. icitem_id=@IcitemId,
  213. icitem_name=@IcitemName,
  214. pr_ssend_date=@PrSsendDate,
  215. pr_sarrive_date=@PrSarriveDate,
  216. pr_unit=@PrUnit,
  217. state=@State,
  218. pr_type=@PrType,
  219. currencytype=@CurrencyType,
  220. update_by=@UpdateBy,
  221. update_by_name=@UpdateByName,
  222. update_time=@UpdateTime,
  223. IsRequireGoods=@IsRequireGoods,
  224. supplier_type=@SupplierType
  225. WHERE Id=@Id AND IFNULL(IsDeleted,0)=0
  226. """,
  227. new SugarParameter("@Id", input.Id.Value),
  228. new SugarParameter("@PrPurchaseId", input.PrPurchaseId!.Value),
  229. new SugarParameter("@PrPurchaseNumber", input.PrPurchaseNumber?.Trim()),
  230. new SugarParameter("@PrPurchaseName", input.PrPurchaseName?.Trim()),
  231. new SugarParameter("@PrPurchaser", input.PrPurchaser?.Trim()),
  232. new SugarParameter("@PrPurchaserNum", input.PrPurchaserNum?.Trim()),
  233. new SugarParameter("@PrRqty", aqty),
  234. new SugarParameter("@PrAqty", aqty),
  235. new SugarParameter("@PrSqty", aqty),
  236. new SugarParameter("@IcitemId", input.IcitemId!.Value),
  237. new SugarParameter("@IcitemName", input.IcitemName?.Trim()),
  238. new SugarParameter("@PrSsendDate", prSsendDate),
  239. new SugarParameter("@PrSarriveDate", prSarriveDate),
  240. new SugarParameter("@PrUnit", input.PrUnit?.Trim()),
  241. new SugarParameter("@State", state),
  242. new SugarParameter("@PrType", prType),
  243. new SugarParameter("@CurrencyType", currency),
  244. new SugarParameter("@UpdateBy", _userManager.UserId),
  245. new SugarParameter("@UpdateByName", _userManager.Account),
  246. new SugarParameter("@UpdateTime", now),
  247. new SugarParameter("@IsRequireGoods", input.IsRequireGoods ?? 0),
  248. new SugarParameter("@SupplierType", input.SupplierType?.Trim())
  249. );
  250. return new { id = input.Id, message = "编辑成功" };
  251. }
  252. }
  253. [DisplayName("删除物料采购申请")]
  254. [HttpPost("purchase-request/delete/{id:long}")]
  255. public async Task<object> Delete(long id)
  256. {
  257. var affected = await _db.Ado.ExecuteCommandAsync(
  258. """
  259. UPDATE srm_pr_main
  260. SET IsDeleted=1,state=0,update_by=@UpdateBy,update_by_name=@UpdateByName,update_time=@UpdateTime
  261. WHERE Id=@Id AND IFNULL(IsDeleted,0)=0
  262. """,
  263. new SugarParameter("@Id", id),
  264. new SugarParameter("@UpdateBy", _userManager.UserId),
  265. new SugarParameter("@UpdateByName", _userManager.Account),
  266. new SugarParameter("@UpdateTime", DateTime.Now));
  267. if (affected <= 0) throw Oops.Oh("记录不存在");
  268. return new { message = "删除成功" };
  269. }
  270. private static string BuildOrderBy(string? sortField, string? sortOrder)
  271. {
  272. var dir = string.Equals(sortOrder, "asc", StringComparison.OrdinalIgnoreCase) ? "ASC" : "DESC";
  273. return sortField?.ToLowerInvariant() switch
  274. {
  275. "prbillno" => $"pm.pr_billno {dir}",
  276. "purord" => $"pod.PurOrd {dir}",
  277. "prtype" => $"pm.pr_type {dir}",
  278. "state" => $"pm.state {dir}",
  279. "number" => $"ic.number {dir}",
  280. "name" => $"ic.name {dir}",
  281. "prpurchasename" => $"pm.pr_purchasename {dir}",
  282. "prsqty" => $"pm.pr_sqty {dir}",
  283. "praqty" => $"pm.pr_aqty {dir}",
  284. "stockqty" => $"its.sqty {dir}",
  285. "prssenddate" => $"pm.pr_ssend_date {dir}",
  286. "prsarrivedate" => $"pm.pr_sarrive_date {dir}",
  287. "createtime" => $"pm.create_time {dir}",
  288. _ => "pm.id DESC"
  289. };
  290. }
  291. private static DateTime? ParseDate(string? value) => DateTime.TryParse(value, out var dt) ? dt : null;
  292. private static string GenerateBillNo()
  293. {
  294. return $"PR{DateTime.Now:yyyyMMddHHmmssfff}";
  295. }
  296. private sealed class PurchaseRequestListRow
  297. {
  298. public long Id { get; set; }
  299. public string? PrBillNo { get; set; }
  300. public string? PurOrd { get; set; }
  301. public int? PrType { get; set; }
  302. public string? SupplierType { get; set; }
  303. public int? IsRequireGoods { get; set; }
  304. public int? State { get; set; }
  305. public string? Number { get; set; }
  306. public string? Name { get; set; }
  307. public string? Model { get; set; }
  308. public string? PrUnit { get; set; }
  309. public string? PrPurchaseNumber { get; set; }
  310. public string? PrPurchaseName { get; set; }
  311. public decimal? PrSqty { get; set; }
  312. public decimal? PrAqty { get; set; }
  313. public decimal? StockQty { get; set; }
  314. public DateTime? PrSsendDate { get; set; }
  315. public DateTime? PrSarriveDate { get; set; }
  316. public string? PrPurchaser { get; set; }
  317. public DateTime? CreateTime { get; set; }
  318. }
  319. private sealed class PurchaseRequestDetailRow
  320. {
  321. public long Id { get; set; }
  322. public string? PrBillNo { get; set; }
  323. public long? IcitemId { get; set; }
  324. public string? IcitemName { get; set; }
  325. public string? PrUnit { get; set; }
  326. public string? PrPurchaseNumber { get; set; }
  327. public string? PrPurchaseName { get; set; }
  328. public string? SupplierType { get; set; }
  329. public decimal? PrAqty { get; set; }
  330. public DateTime? PrSsendDate { get; set; }
  331. public DateTime? PrSarriveDate { get; set; }
  332. public int? PrType { get; set; }
  333. public int? State { get; set; }
  334. public long? PrPurchaseId { get; set; }
  335. public int? IsRequireGoods { get; set; }
  336. public string? PrPurchaserNum { get; set; }
  337. public string? PrPurchaser { get; set; }
  338. public long? CurrencyType { get; set; }
  339. }
  340. }