AdoS0MaterialsController.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. using Admin.NET.Plugin.AiDOP.Dto.S0.Sales;
  2. using Admin.NET.Plugin.AiDOP.Entity.S0.Sales;
  3. using Admin.NET.Plugin.AiDOP.Infrastructure;
  4. namespace Admin.NET.Plugin.AiDOP.Controllers.S0.Sales;
  5. /// <summary>
  6. /// S0 物料主数据(ItemMaster 语义)
  7. /// </summary>
  8. [ApiController]
  9. [Route("api/s0/sales/materials")]
  10. [AllowAnonymous]
  11. [NonUnify]
  12. public class AdoS0MaterialsController : ControllerBase
  13. {
  14. private readonly SqlSugarRepository<AdoS0ItemMaster> _rep;
  15. private readonly AdoS0ReferenceChecker _refChecker;
  16. public AdoS0MaterialsController(SqlSugarRepository<AdoS0ItemMaster> rep, AdoS0ReferenceChecker refChecker)
  17. {
  18. _rep = rep;
  19. _refChecker = refChecker;
  20. }
  21. [HttpGet]
  22. public async Task<IActionResult> GetPagedAsync([FromQuery] AdoS0ItemMasterQueryDto q)
  23. {
  24. (q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize);
  25. var query = _rep.AsQueryable()
  26. .WhereIF(q.CompanyRefId.HasValue, x => x.CompanyRefId == q.CompanyRefId.Value)
  27. .WhereIF(q.FactoryRefId.HasValue, x => x.FactoryRefId == q.FactoryRefId.Value)
  28. .WhereIF(!string.IsNullOrWhiteSpace(q.DomainCode), x => x.DomainCode == q.DomainCode)
  29. .WhereIF(!string.IsNullOrWhiteSpace(q.ItemNum), x => x.ItemNum.Contains(q.ItemNum!))
  30. .WhereIF(!string.IsNullOrWhiteSpace(q.Descr), x => x.Descr.Contains(q.Descr!))
  31. .WhereIF(!string.IsNullOrWhiteSpace(q.Descr1), x => x.Descr1 != null && x.Descr1.Contains(q.Descr1!))
  32. .WhereIF(!string.IsNullOrWhiteSpace(q.ItemType), x => x.ItemType == q.ItemType)
  33. .WhereIF(!string.IsNullOrWhiteSpace(q.PurMfg), x => x.PurMfg == q.PurMfg)
  34. .WhereIF(!string.IsNullOrWhiteSpace(q.Location), x => x.Location != null && x.Location.Contains(q.Location!))
  35. .WhereIF(!string.IsNullOrWhiteSpace(q.Status), x => x.Status == q.Status)
  36. .WhereIF(q.IsActive.HasValue, x => x.IsActive == q.IsActive.Value)
  37. .WhereIF(q.IsConfirm.HasValue, x => x.IsConfirm == q.IsConfirm.Value)
  38. .WhereIF(
  39. !string.IsNullOrWhiteSpace(q.Keyword),
  40. x => x.ItemNum.Contains(q.Keyword!) || x.Descr.Contains(q.Keyword!));
  41. var total = await query.CountAsync();
  42. var list = await query
  43. .OrderByDescending(x => x.CreateTime)
  44. .Skip((q.Page - 1) * q.PageSize)
  45. .Take(q.PageSize)
  46. .ToListAsync();
  47. foreach (var x in list)
  48. x.LocationDescr = FormatLocationDescr(x.Location, null);
  49. return Ok(new { total, page = q.Page, pageSize = q.PageSize, list });
  50. }
  51. [HttpGet("{id:long}")]
  52. public async Task<IActionResult> GetAsync(long id)
  53. {
  54. var item = await _rep.GetByIdAsync(id);
  55. if (item == null) return NotFound();
  56. item.LocationDescr = FormatLocationDescr(item.Location, null);
  57. return Ok(item);
  58. }
  59. [HttpPost]
  60. public async Task<IActionResult> CreateAsync([FromBody] AdoS0ItemMasterUpsertDto dto)
  61. {
  62. if (await _rep.IsAnyAsync(x =>
  63. x.CompanyRefId == dto.CompanyRefId &&
  64. x.FactoryRefId == dto.FactoryRefId &&
  65. x.ItemNum == dto.ItemNum))
  66. {
  67. return AdoS0ApiErrors.Conflict(AdoS0ErrorCodes.MaterialCodeExists, "物料编码已存在");
  68. }
  69. var now = DateTime.Now;
  70. var entity = MapDtoToNewEntity(dto, now);
  71. entity.Status = ResolveStatus(dto);
  72. await _rep.AsInsertable(entity).ExecuteReturnEntityAsync();
  73. return Ok(entity);
  74. }
  75. [HttpPut("{id:long}")]
  76. public async Task<IActionResult> UpdateAsync(long id, [FromBody] AdoS0ItemMasterUpsertDto dto)
  77. {
  78. var entity = await _rep.GetByIdAsync(id);
  79. if (entity == null) return NotFound();
  80. if (await _rep.IsAnyAsync(x =>
  81. x.Id != id &&
  82. x.CompanyRefId == dto.CompanyRefId &&
  83. x.FactoryRefId == dto.FactoryRefId &&
  84. x.ItemNum == dto.ItemNum))
  85. {
  86. return AdoS0ApiErrors.Conflict(AdoS0ErrorCodes.MaterialCodeExists, "物料编码已存在");
  87. }
  88. ApplyDtoToEntity(entity, dto);
  89. entity.Status = ResolveStatus(dto);
  90. entity.UpdateTime = DateTime.Now;
  91. await _rep.AsUpdateable(entity).ExecuteCommandAsync();
  92. return Ok(entity);
  93. }
  94. [HttpPatch("{id:long}/toggle-enabled")]
  95. public async Task<IActionResult> ToggleActiveAsync(long id, [FromBody] AdoS0ItemMasterToggleActiveDto dto)
  96. {
  97. var entity = await _rep.GetByIdAsync(id);
  98. if (entity == null) return NotFound();
  99. entity.IsActive = dto.IsActive;
  100. entity.Status = AdoS0SalesRules.ForbidStatusFromIsEnabled(dto.IsActive);
  101. entity.UpdateTime = DateTime.Now;
  102. await _rep.AsUpdateable(entity).ExecuteCommandAsync();
  103. return Ok(entity);
  104. }
  105. [HttpDelete("{id:long}")]
  106. public async Task<IActionResult> DeleteAsync(long id)
  107. {
  108. var item = await _rep.GetByIdAsync(id);
  109. if (item == null) return NotFound();
  110. var refInfo = await _refChecker.MaterialReferencesAsync(item.ItemNum);
  111. if (refInfo is { } r)
  112. return AdoS0ApiErrors.Conflict(AdoS0ErrorCodes.DeleteBlocked,
  113. $"存在 {r.Count} 条 {r.Table} 引用该物料,无法删除");
  114. await _rep.DeleteAsync(item);
  115. return Ok(new { message = "删除成功" });
  116. }
  117. private static string ResolveStatus(AdoS0ItemMasterUpsertDto dto) =>
  118. string.IsNullOrWhiteSpace(dto.Status)
  119. ? AdoS0SalesRules.ForbidStatusFromIsEnabled(dto.IsActive)
  120. : dto.Status!;
  121. private static string FormatLocationDescr(string? location, string? locationMasterDescr)
  122. {
  123. var a = location?.Trim();
  124. var b = locationMasterDescr?.Trim();
  125. if (string.IsNullOrEmpty(a)) return b ?? string.Empty;
  126. if (string.IsNullOrEmpty(b)) return a;
  127. return $"{a} {b}".Trim();
  128. }
  129. private static AdoS0ItemMaster MapDtoToNewEntity(AdoS0ItemMasterUpsertDto dto, DateTime now) => new()
  130. {
  131. CompanyRefId = dto.CompanyRefId,
  132. FactoryRefId = dto.FactoryRefId,
  133. DomainCode = dto.DomainCode,
  134. ItemNum = dto.ItemNum,
  135. Descr = dto.Descr,
  136. Descr1 = dto.Descr1,
  137. PkgCode = dto.PkgCode,
  138. UM = dto.UM,
  139. PurMfg = dto.PurMfg,
  140. Drawing = dto.Drawing,
  141. ItemType = dto.ItemType,
  142. Location = dto.Location,
  143. DefaultShelf = dto.DefaultShelf,
  144. KeyItem = dto.KeyItem,
  145. NetWeight = dto.NetWeight,
  146. NetWeightUM = dto.NetWeightUM,
  147. Inspect = dto.Inspect,
  148. PurLT = dto.PurLT,
  149. InsLT = dto.InsLT,
  150. MfgLT = dto.MfgLT,
  151. Length = dto.Length,
  152. Size = dto.Size,
  153. SizeUM = dto.SizeUM,
  154. IssuePolicy = dto.IssuePolicy,
  155. MfgMttr = dto.MfgMttr,
  156. LocationType = dto.LocationType,
  157. CommodityCode = dto.CommodityCode,
  158. Rev = dto.Rev,
  159. MaxOrd = dto.MaxOrd,
  160. MinOrd = dto.MinOrd,
  161. OrdMult = dto.OrdMult,
  162. MinOrdSales = dto.MinOrdSales,
  163. AutoLotNums = dto.AutoLotNums,
  164. Install = dto.Install,
  165. SafetyStk = dto.SafetyStk,
  166. DaysBetweenPM = dto.DaysBetweenPM,
  167. ExpireAlarmDay = dto.ExpireAlarmDay,
  168. StockTurnOver = dto.StockTurnOver,
  169. LotSerialControl = dto.LotSerialControl,
  170. AllocateSingleLot = dto.AllocateSingleLot,
  171. Planner = dto.Planner,
  172. TraceDetail = dto.TraceDetail,
  173. IsMainMas = dto.IsMainMas,
  174. Remark = dto.Remark,
  175. EMTType = dto.EMTType,
  176. OwnerApplication = dto.OwnerApplication,
  177. BOMDesign = dto.BOMDesign,
  178. RoutingDes = dto.RoutingDes,
  179. CustSupplied = dto.CustSupplied,
  180. DrawingDesign = dto.DrawingDesign,
  181. DesignOwner = dto.DesignOwner,
  182. IsActive = dto.IsActive,
  183. IsConfirm = dto.IsConfirm,
  184. CreateUser = dto.CreateUser,
  185. CreateTime = now,
  186. UpdateUser = dto.UpdateUser,
  187. UpdateTime = null
  188. };
  189. private static void ApplyDtoToEntity(AdoS0ItemMaster entity, AdoS0ItemMasterUpsertDto dto)
  190. {
  191. entity.CompanyRefId = dto.CompanyRefId;
  192. entity.FactoryRefId = dto.FactoryRefId;
  193. entity.DomainCode = dto.DomainCode;
  194. entity.ItemNum = dto.ItemNum;
  195. entity.Descr = dto.Descr;
  196. entity.Descr1 = dto.Descr1;
  197. entity.PkgCode = dto.PkgCode;
  198. entity.UM = dto.UM;
  199. entity.PurMfg = dto.PurMfg;
  200. entity.Drawing = dto.Drawing;
  201. entity.ItemType = dto.ItemType;
  202. entity.Location = dto.Location;
  203. entity.DefaultShelf = dto.DefaultShelf;
  204. entity.KeyItem = dto.KeyItem;
  205. entity.NetWeight = dto.NetWeight;
  206. entity.NetWeightUM = dto.NetWeightUM;
  207. entity.Inspect = dto.Inspect;
  208. entity.PurLT = dto.PurLT;
  209. entity.InsLT = dto.InsLT;
  210. entity.MfgLT = dto.MfgLT;
  211. entity.Length = dto.Length;
  212. entity.Size = dto.Size;
  213. entity.SizeUM = dto.SizeUM;
  214. entity.IssuePolicy = dto.IssuePolicy;
  215. entity.MfgMttr = dto.MfgMttr;
  216. entity.LocationType = dto.LocationType;
  217. entity.CommodityCode = dto.CommodityCode;
  218. entity.Rev = dto.Rev;
  219. entity.MaxOrd = dto.MaxOrd;
  220. entity.MinOrd = dto.MinOrd;
  221. entity.OrdMult = dto.OrdMult;
  222. entity.MinOrdSales = dto.MinOrdSales;
  223. entity.AutoLotNums = dto.AutoLotNums;
  224. entity.Install = dto.Install;
  225. entity.SafetyStk = dto.SafetyStk;
  226. entity.DaysBetweenPM = dto.DaysBetweenPM;
  227. entity.ExpireAlarmDay = dto.ExpireAlarmDay;
  228. entity.StockTurnOver = dto.StockTurnOver;
  229. entity.LotSerialControl = dto.LotSerialControl;
  230. entity.AllocateSingleLot = dto.AllocateSingleLot;
  231. entity.Planner = dto.Planner;
  232. entity.TraceDetail = dto.TraceDetail;
  233. entity.IsMainMas = dto.IsMainMas;
  234. entity.Remark = dto.Remark;
  235. entity.EMTType = dto.EMTType;
  236. entity.OwnerApplication = dto.OwnerApplication;
  237. entity.BOMDesign = dto.BOMDesign;
  238. entity.RoutingDes = dto.RoutingDes;
  239. entity.CustSupplied = dto.CustSupplied;
  240. entity.DrawingDesign = dto.DrawingDesign;
  241. entity.DesignOwner = dto.DesignOwner;
  242. entity.IsActive = dto.IsActive;
  243. entity.IsConfirm = dto.IsConfirm;
  244. entity.UpdateUser = dto.UpdateUser;
  245. }
  246. }