using Admin.NET.Plugin.AiDOP.Dto.S0.Supply;
using Admin.NET.Plugin.AiDOP.Entity.S0.Sales;
using Admin.NET.Plugin.AiDOP.Entity.S0.Supply;
using Admin.NET.Plugin.AiDOP.Infrastructure;
namespace Admin.NET.Plugin.AiDOP.Controllers.S0.Supply;
///
/// S0 货源清单(srm_purchase 语义,左联物料主数据展示)
///
[ApiController]
[Route("api/s0/supply/srm-purchases")]
[AllowAnonymous]
[NonUnify]
public class AdoS0SrmPurchasesController : ControllerBase
{
private readonly SqlSugarRepository _rep;
private readonly SqlSugarRepository _itemRep;
private readonly SqlSugarRepository _suppRep;
public AdoS0SrmPurchasesController(
SqlSugarRepository rep,
SqlSugarRepository itemRep,
SqlSugarRepository suppRep)
{
_rep = rep;
_itemRep = itemRep;
_suppRep = suppRep;
}
[HttpGet]
public async Task GetPagedAsync([FromQuery] AdoS0SrmPurchaseQueryDto q)
{
(q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize);
var baseQuery = _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.SupplierType), x => x.SupplierType != null && x.SupplierType.Contains(q.SupplierType!))
.WhereIF(q.IsActive.HasValue, x => x.IsActive == q.IsActive.Value)
.WhereIF(!string.IsNullOrWhiteSpace(q.SupplierName), x => x.SupplierName != null && x.SupplierName.Contains(q.SupplierName!))
.WhereIF(!string.IsNullOrWhiteSpace(q.SupplierNumber), x => x.SupplierNumber != null && x.SupplierNumber.Contains(q.SupplierNumber!))
.WhereIF(!string.IsNullOrWhiteSpace(q.CurrencyType), x => x.CurrencyType != null && x.CurrencyType.Contains(q.CurrencyType!));
if (!string.IsNullOrWhiteSpace(q.Keyword))
{
var kw = q.Keyword!;
var itemIds = await _itemRep.AsQueryable()
.Where(it =>
it.ItemNum.Contains(kw) ||
it.Descr.Contains(kw) ||
(it.Descr1 != null && it.Descr1.Contains(kw)))
.Select(it => it.Id)
.ToListAsync();
baseQuery = baseQuery.Where(x =>
(x.IcitemName != null && x.IcitemName.Contains(kw)) ||
(x.SupplierName != null && x.SupplierName.Contains(kw)) ||
(x.SupplierNumber != null && x.SupplierNumber.Contains(kw)) ||
(itemIds.Count > 0 && itemIds.Contains(x.IcitemId)));
}
var total = await baseQuery.CountAsync();
var list = await baseQuery
.OrderByDescending(x => x.CreateTime)
.Skip((q.Page - 1) * q.PageSize)
.Take(q.PageSize)
.ToListAsync();
await ApplyItemAndSupplierDisplayAsync(list);
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();
await ApplyItemAndSupplierDisplayAsync(new List { item });
return Ok(item);
}
[HttpPost]
public async Task CreateAsync([FromBody] AdoS0SrmPurchaseUpsertDto dto)
{
var dateErr = ValidateDateRange(dto.EffectiveDate, dto.ExpiringDate);
if (dateErr != null) return AdoS0ApiErrors.InvalidRequest(dateErr);
var refErr = await ValidateReferencesAsync(dto.IcitemId, dto.SupplierId);
if (refErr != null) return refErr;
var now = DateTime.Now;
var entity = MapDtoToEntity(dto, new AdoS0SrmPurchase(), now, isNew: true);
await _rep.AsInsertable(entity).ExecuteReturnEntityAsync();
await ApplyItemAndSupplierDisplayAsync(new List { entity });
return Ok(entity);
}
[HttpPut("{id:long}")]
public async Task UpdateAsync(long id, [FromBody] AdoS0SrmPurchaseUpsertDto dto)
{
var entity = await _rep.GetByIdAsync(id);
if (entity == null) return NotFound();
var dateErr = ValidateDateRange(dto.EffectiveDate, dto.ExpiringDate);
if (dateErr != null) return AdoS0ApiErrors.InvalidRequest(dateErr);
var refErr = await ValidateReferencesAsync(dto.IcitemId, dto.SupplierId);
if (refErr != null) return refErr;
MapDtoToEntity(dto, entity, DateTime.Now, isNew: false);
await _rep.AsUpdateable(entity).ExecuteCommandAsync();
await ApplyItemAndSupplierDisplayAsync(new List { entity });
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? ValidateDateRange(DateTime? effective, DateTime? expiring)
{
if (effective.HasValue && expiring.HasValue && effective.Value.Date > expiring.Value.Date)
return "生效日期不能晚于失效日期";
return null;
}
private async Task ValidateReferencesAsync(long icitemId, long supplierId)
{
if (!await _itemRep.IsAnyAsync(x => x.Id == icitemId))
return AdoS0ApiErrors.InvalidReference(AdoS0ErrorCodes.MaterialReferenceInvalid, "物料主数据引用无效");
if (!await _suppRep.IsAnyAsync(x => x.Id == supplierId))
return AdoS0ApiErrors.InvalidReference(AdoS0ErrorCodes.InvalidReference, "供应商主数据引用无效");
return null;
}
private static AdoS0SrmPurchase MapDtoToEntity(AdoS0SrmPurchaseUpsertDto dto, AdoS0SrmPurchase entity, DateTime now, bool isNew)
{
entity.CompanyRefId = dto.CompanyRefId;
entity.FactoryRefId = dto.FactoryRefId;
entity.DomainCode = dto.DomainCode;
entity.IcitemId = dto.IcitemId;
entity.IcitemName = dto.IcitemName;
entity.SupplierType = dto.SupplierType;
entity.IsActive = dto.IsActive;
entity.SupplierId = dto.SupplierId;
entity.SupplierName = dto.SupplierName;
entity.SupplierNumber = dto.SupplierNumber;
entity.OrderPrice = dto.OrderPrice;
entity.CurrencyType = dto.CurrencyType;
entity.Taxrate = dto.Taxrate;
entity.Tariff = dto.Tariff;
entity.Freight = dto.Freight;
entity.PriceTerms = dto.PriceTerms;
entity.EffectiveDate = dto.EffectiveDate;
entity.ExpiringDate = dto.ExpiringDate;
entity.QuotaRate = dto.QuotaRate;
entity.LeadTime = dto.LeadTime;
entity.QtyMin = dto.QtyMin;
entity.PackagingQty = dto.PackagingQty;
entity.OrderRectorName = dto.OrderRectorName;
entity.OrderRectorNum = dto.OrderRectorNum;
entity.IsRequireGoods = dto.IsRequireGoods;
if (isNew)
{
entity.CreateUser = dto.CreateUser;
entity.CreateTime = now;
entity.UpdateUser = dto.UpdateUser;
entity.UpdateTime = null;
}
else
{
entity.UpdateUser = dto.UpdateUser;
entity.UpdateTime = now;
}
return entity;
}
private async Task ApplyItemAndSupplierDisplayAsync(List rows)
{
if (rows.Count == 0) return;
var itemIds = rows.Select(x => x.IcitemId).Where(id => id > 0).Distinct().ToList();
var items = itemIds.Count == 0
? new List()
: await _itemRep.AsQueryable().Where(it => itemIds.Contains(it.Id)).ToListAsync();
foreach (var sp in rows)
{
var it = items.Find(i => i.Id == sp.IcitemId);
sp.MaterialCode = it?.ItemNum;
sp.Model = it?.Descr1;
sp.Unit = it?.UM;
sp.ItemTypeLabel = string.IsNullOrWhiteSpace(it?.ItemType) ? "原材料" : it!.ItemType;
var num = sp.MaterialCode ?? "";
var name = sp.IcitemName ?? "";
sp.Icitem = $"{num}{name}";
var sname = sp.SupplierName ?? "";
var snum = sp.SupplierNumber ?? "";
sp.Supplier = $"{sname}{snum}";
}
}
}