using Admin.NET.Plugin.AiDOP.Dto.S0.Sales;
using Admin.NET.Plugin.AiDOP.Entity.S0.Sales;
using Admin.NET.Plugin.AiDOP.Infrastructure;
namespace Admin.NET.Plugin.AiDOP.Controllers.S0.Sales;
///
/// S0 物料主数据(ItemMaster 语义)
///
[ApiController]
[Route("api/s0/sales/materials")]
[AllowAnonymous]
[NonUnify]
public class AdoS0MaterialsController : ControllerBase
{
private readonly SqlSugarRepository _rep;
public AdoS0MaterialsController(SqlSugarRepository rep)
{
_rep = rep;
}
[HttpGet]
public async Task GetPagedAsync([FromQuery] AdoS0ItemMasterQueryDto q)
{
(q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize);
var query = _rep.AsQueryable()
.WhereIF(q.CompanyRefId.HasValue, x => x.CompanyRefId == q.CompanyRefId.Value)
.WhereIF(q.FactoryRefId.HasValue, x => x.FactoryRefId == q.FactoryRefId.Value)
.WhereIF(!string.IsNullOrWhiteSpace(q.DomainCode), x => x.DomainCode == q.DomainCode)
.WhereIF(!string.IsNullOrWhiteSpace(q.ItemNum), x => x.ItemNum.Contains(q.ItemNum!))
.WhereIF(!string.IsNullOrWhiteSpace(q.Descr), x => x.Descr.Contains(q.Descr!))
.WhereIF(!string.IsNullOrWhiteSpace(q.Descr1), x => x.Descr1 != null && x.Descr1.Contains(q.Descr1!))
.WhereIF(!string.IsNullOrWhiteSpace(q.ItemType), x => x.ItemType == q.ItemType)
.WhereIF(!string.IsNullOrWhiteSpace(q.PurMfg), x => x.PurMfg == q.PurMfg)
.WhereIF(!string.IsNullOrWhiteSpace(q.Location), x => x.Location != null && x.Location.Contains(q.Location!))
.WhereIF(!string.IsNullOrWhiteSpace(q.Status), x => x.Status == q.Status)
.WhereIF(q.IsActive.HasValue, x => x.IsActive == q.IsActive.Value)
.WhereIF(q.IsConfirm.HasValue, x => x.IsConfirm == q.IsConfirm.Value)
.WhereIF(
!string.IsNullOrWhiteSpace(q.Keyword),
x => x.ItemNum.Contains(q.Keyword!) || x.Descr.Contains(q.Keyword!));
var total = await query.CountAsync();
var list = await query
.OrderByDescending(x => x.CreateTime)
.Skip((q.Page - 1) * q.PageSize)
.Take(q.PageSize)
.ToListAsync();
foreach (var x in list)
x.LocationDescr = FormatLocationDescr(x.Location, null);
return Ok(new { total, page = q.Page, pageSize = q.PageSize, list });
}
[HttpGet("{id:long}")]
public async Task GetAsync(long id)
{
var item = await _rep.GetByIdAsync(id);
if (item == null) return NotFound();
item.LocationDescr = FormatLocationDescr(item.Location, null);
return Ok(item);
}
[HttpPost]
public async Task CreateAsync([FromBody] AdoS0ItemMasterUpsertDto dto)
{
if (await _rep.IsAnyAsync(x =>
x.CompanyRefId == dto.CompanyRefId &&
x.FactoryRefId == dto.FactoryRefId &&
x.ItemNum == dto.ItemNum))
{
return AdoS0ApiErrors.Conflict(AdoS0ErrorCodes.MaterialCodeExists, "物料编码已存在");
}
var now = DateTime.Now;
var entity = MapDtoToNewEntity(dto, now);
entity.Status = ResolveStatus(dto);
await _rep.AsInsertable(entity).ExecuteReturnEntityAsync();
return Ok(entity);
}
[HttpPut("{id:long}")]
public async Task UpdateAsync(long id, [FromBody] AdoS0ItemMasterUpsertDto dto)
{
var entity = await _rep.GetByIdAsync(id);
if (entity == null) return NotFound();
if (await _rep.IsAnyAsync(x =>
x.Id != id &&
x.CompanyRefId == dto.CompanyRefId &&
x.FactoryRefId == dto.FactoryRefId &&
x.ItemNum == dto.ItemNum))
{
return AdoS0ApiErrors.Conflict(AdoS0ErrorCodes.MaterialCodeExists, "物料编码已存在");
}
ApplyDtoToEntity(entity, dto);
entity.Status = ResolveStatus(dto);
entity.UpdateTime = DateTime.Now;
await _rep.AsUpdateable(entity).ExecuteCommandAsync();
return Ok(entity);
}
[HttpPatch("{id:long}/toggle-enabled")]
public async Task ToggleActiveAsync(long id, [FromBody] AdoS0ItemMasterToggleActiveDto dto)
{
var entity = await _rep.GetByIdAsync(id);
if (entity == null) return NotFound();
entity.IsActive = dto.IsActive;
entity.Status = AdoS0SalesRules.ForbidStatusFromIsEnabled(dto.IsActive);
entity.UpdateTime = DateTime.Now;
await _rep.AsUpdateable(entity).ExecuteCommandAsync();
return Ok(entity);
}
[HttpDelete("{id:long}")]
public async Task DeleteAsync(long id)
{
var item = await _rep.GetByIdAsync(id);
if (item == null) return NotFound();
await _rep.DeleteAsync(item);
return Ok(new { message = "删除成功" });
}
private static string ResolveStatus(AdoS0ItemMasterUpsertDto dto) =>
string.IsNullOrWhiteSpace(dto.Status)
? AdoS0SalesRules.ForbidStatusFromIsEnabled(dto.IsActive)
: dto.Status!;
private static string FormatLocationDescr(string? location, string? locationMasterDescr)
{
var a = location?.Trim();
var b = locationMasterDescr?.Trim();
if (string.IsNullOrEmpty(a)) return b ?? string.Empty;
if (string.IsNullOrEmpty(b)) return a;
return $"{a} {b}".Trim();
}
private static AdoS0ItemMaster MapDtoToNewEntity(AdoS0ItemMasterUpsertDto dto, DateTime now) => new()
{
CompanyRefId = dto.CompanyRefId,
FactoryRefId = dto.FactoryRefId,
DomainCode = dto.DomainCode,
ItemNum = dto.ItemNum,
Descr = dto.Descr,
Descr1 = dto.Descr1,
PkgCode = dto.PkgCode,
UM = dto.UM,
PurMfg = dto.PurMfg,
Drawing = dto.Drawing,
ItemType = dto.ItemType,
Location = dto.Location,
DefaultShelf = dto.DefaultShelf,
KeyItem = dto.KeyItem,
NetWeight = dto.NetWeight,
NetWeightUM = dto.NetWeightUM,
Inspect = dto.Inspect,
PurLT = dto.PurLT,
InsLT = dto.InsLT,
MfgLT = dto.MfgLT,
Length = dto.Length,
Size = dto.Size,
SizeUM = dto.SizeUM,
IssuePolicy = dto.IssuePolicy,
MfgMttr = dto.MfgMttr,
LocationType = dto.LocationType,
CommodityCode = dto.CommodityCode,
Rev = dto.Rev,
MaxOrd = dto.MaxOrd,
MinOrd = dto.MinOrd,
OrdMult = dto.OrdMult,
MinOrdSales = dto.MinOrdSales,
AutoLotNums = dto.AutoLotNums,
Install = dto.Install,
SafetyStk = dto.SafetyStk,
DaysBetweenPM = dto.DaysBetweenPM,
ExpireAlarmDay = dto.ExpireAlarmDay,
StockTurnOver = dto.StockTurnOver,
LotSerialControl = dto.LotSerialControl,
AllocateSingleLot = dto.AllocateSingleLot,
Planner = dto.Planner,
TraceDetail = dto.TraceDetail,
IsMainMas = dto.IsMainMas,
Remark = dto.Remark,
EMTType = dto.EMTType,
OwnerApplication = dto.OwnerApplication,
BOMDesign = dto.BOMDesign,
RoutingDes = dto.RoutingDes,
CustSupplied = dto.CustSupplied,
DrawingDesign = dto.DrawingDesign,
DesignOwner = dto.DesignOwner,
IsActive = dto.IsActive,
IsConfirm = dto.IsConfirm,
CreateUser = dto.CreateUser,
CreateTime = now,
UpdateUser = dto.UpdateUser,
UpdateTime = null
};
private static void ApplyDtoToEntity(AdoS0ItemMaster entity, AdoS0ItemMasterUpsertDto dto)
{
entity.CompanyRefId = dto.CompanyRefId;
entity.FactoryRefId = dto.FactoryRefId;
entity.DomainCode = dto.DomainCode;
entity.ItemNum = dto.ItemNum;
entity.Descr = dto.Descr;
entity.Descr1 = dto.Descr1;
entity.PkgCode = dto.PkgCode;
entity.UM = dto.UM;
entity.PurMfg = dto.PurMfg;
entity.Drawing = dto.Drawing;
entity.ItemType = dto.ItemType;
entity.Location = dto.Location;
entity.DefaultShelf = dto.DefaultShelf;
entity.KeyItem = dto.KeyItem;
entity.NetWeight = dto.NetWeight;
entity.NetWeightUM = dto.NetWeightUM;
entity.Inspect = dto.Inspect;
entity.PurLT = dto.PurLT;
entity.InsLT = dto.InsLT;
entity.MfgLT = dto.MfgLT;
entity.Length = dto.Length;
entity.Size = dto.Size;
entity.SizeUM = dto.SizeUM;
entity.IssuePolicy = dto.IssuePolicy;
entity.MfgMttr = dto.MfgMttr;
entity.LocationType = dto.LocationType;
entity.CommodityCode = dto.CommodityCode;
entity.Rev = dto.Rev;
entity.MaxOrd = dto.MaxOrd;
entity.MinOrd = dto.MinOrd;
entity.OrdMult = dto.OrdMult;
entity.MinOrdSales = dto.MinOrdSales;
entity.AutoLotNums = dto.AutoLotNums;
entity.Install = dto.Install;
entity.SafetyStk = dto.SafetyStk;
entity.DaysBetweenPM = dto.DaysBetweenPM;
entity.ExpireAlarmDay = dto.ExpireAlarmDay;
entity.StockTurnOver = dto.StockTurnOver;
entity.LotSerialControl = dto.LotSerialControl;
entity.AllocateSingleLot = dto.AllocateSingleLot;
entity.Planner = dto.Planner;
entity.TraceDetail = dto.TraceDetail;
entity.IsMainMas = dto.IsMainMas;
entity.Remark = dto.Remark;
entity.EMTType = dto.EMTType;
entity.OwnerApplication = dto.OwnerApplication;
entity.BOMDesign = dto.BOMDesign;
entity.RoutingDes = dto.RoutingDes;
entity.CustSupplied = dto.CustSupplied;
entity.DrawingDesign = dto.DrawingDesign;
entity.DesignOwner = dto.DesignOwner;
entity.IsActive = dto.IsActive;
entity.IsConfirm = dto.IsConfirm;
entity.UpdateUser = dto.UpdateUser;
}
}