添加采购订单
在领域共享项目中添加常量
在 Domain.Shared
项目中添加文件夹Purchase
,在文件夹下添加类PurchaseConsts.cs
,添加以下代码:
public static class PurchaseConsts
{
public const int MaxPoNumLength = 20;
public const int MaxItemNumLength = 50;
/// <summary>
/// 订单已存在异常代码
/// </summary>
public const string PurchaseOrderAlreadyExists = "PurchaseOrder:00001";
/// <summary>
/// 订单不存在异常代码
/// </summary>
public const string PurchaseOrderNotExists = "PurchaseOrder:00002";
/// <summary>
/// 订单明细已存在异常代码
/// </summary>
public const string PurchaseOrderItemAlreadyExists = "PurchaseOrder:00003";
/// <summary>
/// 订单名称不存在异常代码
/// </summary>
public const string PurchaseOrderItemNotExists = "PurchaseOrder:00004";
}
添加领域实体
添加实体
在 Domain
项目中添加文件夹 Purchase
,在文件夹中添加实体 PurchaseOrder
,添加以下代码:
public class PurchaseOrder : FullAuditedAggregateRoot<Guid>
{
public string PoNum { get; private set; } = string.Empty;
public DateTime IDate { get; set; }
public string Buyer { get; set; } = string.Empty;
public string VenName { get; set; } = string.Empty;
public decimal TotalQty { get; internal set; }
public decimal TotalAmount { get; internal set; }
private PurchaseOrder() { }
internal PurchaseOrder(Guid id, string poNum, DateTime idate, [NotNull] string buyer, [NotNull] string venName) : base(id)
{
SetPoNum(poNum);
IDate = idate;
Buyer = buyer;
VenName = venName;
}
internal void UpdatePoNum(string poNum)
{
SetPoNum(poNum);
}
private void SetPoNum(string poNum)
{
PoNum = Check.NotNullOrEmpty(poNum, nameof(poNum), maxLength: PurchaseConsts.MaxPoNumLength);
}
internal PurchaseOrderItem CreateNewItem(Guid itemId, string itemNum, decimal qty, decimal price)
{
var item = new PurchaseOrderItem(Id, itemId, itemNum, qty, price);
TotalQty += item.Qty;
TotalAmount+= item.Amount;
return item;
}
}
添加实体PurchaseOrderItem
,添加以下代码:
public class PurchaseOrderItem : FullAuditedAggregateRoot<Guid>
{
public string ItemNum { get; private set; } = string.Empty;
public decimal Qty { get; private set; }
public decimal Price { get; private set; }
public decimal Amount { get; private set; }
public Guid PurchaseOrderId { get; private set; }
private PurchaseOrderItem() { }
internal PurchaseOrderItem(Guid purchaseOrderId,Guid id,string itemNum,decimal qty,decimal price):base(id)
{
PurchaseOrderId= purchaseOrderId;
SetItemNum(itemNum);
UpdateQty(qty);
UpdatePrice(price);
}
internal void UpdateQty(decimal qty)
{
Qty = qty;
ResetAmount();
}
internal void UpdatePrice(decimal price)
{
Price = price;
ResetAmount();
}
internal void ResetAmount()
{
Amount = Qty * Price;
}
internal void UpdateItemNum([NotNull] string itemNum)
{
SetItemNum(itemNum);
}
private void SetItemNum([NotNull] string itemNum)
{
ItemNum = Check.NotNullOrEmpty(itemNum,nameof(itemNum),maxLength:PurchaseConsts.MaxItemNumLength);
}
}
添加领域服务
在 Domain
项目的文件夹 Purchase
下添加类PurchaseOrderManage.cs
,并添加以下代码:
public class PurchaseOrderManage : DomainService
{
private readonly IRepository<PurchaseOrder, Guid> _purchaseOrderRepository;
private readonly IRepository<PurchaseOrderItem, Guid> _purchaseOrderItemRepository;
public PurchaseOrderManage(IRepository<PurchaseOrder, Guid> purchaseOrderRepository, IRepository<PurchaseOrderItem, Guid> purchaseOrderItemRepository)
{
_purchaseOrderRepository = purchaseOrderRepository;
_purchaseOrderItemRepository = purchaseOrderItemRepository;
}
public async Task<PurchaseOrder> CreateAsync([NotNull] string poNum, [NotNull] DateTime iDate, [NotNull] string buyer, [NotNull] string venName)
{
Check.NotNullOrWhiteSpace(poNum, nameof(poNum));
Check.NotNull(iDate, nameof(iDate));
Check.NotNullOrWhiteSpace(buyer, nameof(buyer));
Check.NotNullOrWhiteSpace(venName, nameof(venName));
var po = await _purchaseOrderRepository.FindAsync(p => p.PoNum.Equals(poNum));
if (po != null)
{
throw new PurchaseOrderAlreadyExistsException(poNum);
}
return new PurchaseOrder(GuidGenerator.Create(), poNum, iDate, buyer, venName);
}
public async Task UpdatePoNum([NotNull] PurchaseOrder purchaseOrder, [NotNull] string poNum)
{
Check.NotNull(purchaseOrder, nameof(purchaseOrder));
Check.NotNullOrWhiteSpace(poNum, nameof(poNum));
var exstingPurchaseOrder = await _purchaseOrderRepository.FindAsync(p => p.PoNum.Equals(poNum));
if (exstingPurchaseOrder != null && exstingPurchaseOrder.Id != purchaseOrder.Id)
{
throw new PurchaseOrderAlreadyExistsException(poNum);
}
purchaseOrder.UpdatePoNum(poNum);
}
public PurchaseOrderItem AddPurchaseOrderItem([NotNull] PurchaseOrder purchaseOrder, string itemNum, decimal qty, decimal price)
{
Check.NotNull(purchaseOrder, nameof(purchaseOrder));
Check.NotNullOrWhiteSpace(itemNum, nameof(itemNum));
var item = purchaseOrder.CreateNewItem(GuidGenerator.Create(), itemNum, qty, price);
return item;
}
public async Task<PurchaseOrder> UpdatePurchaseOrderItem([NotNull] PurchaseOrderItem purchaseOrderItem, string itemNum, decimal qty, decimal price)
{
Check.NotNull(purchaseOrderItem, nameof(purchaseOrderItem));
var differenceQty = qty - purchaseOrderItem.Qty;
var diferenceAmount = qty * price - purchaseOrderItem.Amount;
purchaseOrderItem.UpdateItemNum(itemNum);
purchaseOrderItem.UpdateQty(qty);
purchaseOrderItem.UpdatePrice(price);
var po = await _purchaseOrderRepository.FindAsync(purchaseOrderItem.PurchaseOrderId);
po.TotalQty += differenceQty;
po.TotalAmount += diferenceAmount;
return po;
}
public async Task<PurchaseOrder> RemovePurchaseOrderItem([NotNull] PurchaseOrderItem purchaseOrderItem)
{
Check.NotNull(purchaseOrderItem, nameof(purchaseOrderItem));
var po = await _purchaseOrderRepository.FindAsync(purchaseOrderItem.PurchaseOrderId);
po.TotalQty -= purchaseOrderItem.Qty;
po.TotalAmount -= purchaseOrderItem.Amount;
return po;
}
public async Task ResetPurchaseOrderTotalQtyTotalAmountAsync([NotNull] PurchaseOrder purchaseOrder)
{
Check.NotNull(purchaseOrder, nameof(purchaseOrder));
await ResetPurchaseOrderTotalQtyAsync(purchaseOrder);
await ResetPurchaseOrderTotalAmountAsync(purchaseOrder);
}
public async Task ResetPurchaseOrderTotalQtyAsync([NotNull] PurchaseOrder purchaseOrder)
{
Check.NotNull(purchaseOrder, nameof(purchaseOrder));
var query = await _purchaseOrderItemRepository.GetQueryableAsync();
var totalQty = query
.Where(p=>p.PurchaseOrderId.Equals(purchaseOrder.Id))
.Sum(p => p.Qty);
purchaseOrder.TotalQty = totalQty;
}
public async Task ResetPurchaseOrderTotalAmountAsync([NotNull] PurchaseOrder purchaseOrder)
{
Check.NotNull(purchaseOrder, nameof(purchaseOrder));
var query = await _purchaseOrderItemRepository.GetQueryableAsync();
var totalAmount = query
.Where(p => p.PurchaseOrderId.Equals(purchaseOrder.Id))
.Sum(p => p.Amount);
purchaseOrder.TotalAmount = totalAmount;
}
}
添加异常类PurchaseOrderAlreadyExistsException.cs
、PurchaseOrderNotExistsException.cs
,代码如下:
public class PurchaseOrderAlreadyExistsException : BusinessException
{
public PurchaseOrderAlreadyExistsException(string poNum) : base(PurchaseConsts.PurchaseOrderAlreadyExists)
{
WithData("poNum", poNum);
}
}
public class PurchaseOrderNotExistsException: BusinessException
{
public PurchaseOrderNotExistsException(Guid id) : base(PurchaseConsts.PurchaseOrderNotExists)
{
WithData("id", id);
}
}
数据库配置
添加数据库配置常量
在项目EntityFrameworkCore
中添加类MyDbContextConsts.cs
,添加以下代码:
public static class MyDbContextConsts
{
public const string DbTablePrefix = "Study";
public const string DbSchema = null;
}
添加数据库上下文
在项目EntityFrameworkCore
中添加类MyDbContext.cs
,添加以下代码:
[ConnectionStringName("Default")]
public class MyDbContext : AbpDbContext<MyDbContext>
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
{
}
public DbSet<PurchaseOrder> PurchaseOrders { get; set; }
public DbSet<PurchaseOrderItem> PurchaseOrderItems { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PurchaseOrder>(p =>
{
p.ToTable(MyDbContextConsts.DbTablePrefix + "_PurchaseOrders", MyDbContextConsts.DbSchema);
p.ConfigureByConvention();
p.Property(x => x.PoNum)
.IsRequired()
.HasMaxLength(PurchaseConsts.MaxPoNumLength);
});
modelBuilder.Entity<PurchaseOrderItem>(p =>
{
p.ToTable(MyDbContextConsts.DbTablePrefix+"_PurchaseOrderItems",MyDbContextConsts.DbSchema);
p.ConfigureByConvention();
p.Property(x=>x.ItemNum)
.IsRequired()
.HasMaxLength(PurchaseConsts.MaxItemNumLength);
p.HasOne<PurchaseOrder>()
.WithMany()
.HasForeignKey(x => x.PurchaseOrderId)
.IsRequired();
});
}
}
在EntityFrameworkCoreModule.cs
添加以下代码:
// 添加数据库上下文
context.Services.AddAbpDbContext<MyDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
});
完整代码:
[DependsOn(
typeof(AbpEntityFrameworkCoreSqlServerModule)
)]
public class EntityFrameworkCoreModule:AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
base.ConfigureServices(context);
// 添加数据库上下文
context.Services.AddAbpDbContext<MyDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
});
// 配置使用 SqlServer
Configure<AbpDbContextOptions>(options =>
{
options.UseSqlServer();
});
}
}
应用层约定
添加数据传输对象
public class CreatePurchaseOrderDto
{
[Required]
[StringLength(PurchaseConsts.MaxPoNumLength)]
public string PoNum { get; set; }
[Required]
public DateTime IDate { get; set; }
[Required]
public string Buyer { get; set; }
[Required]
public string VenName { get; set; }
}
public class CreatePurchaseOrderAndDetailDto: CreatePurchaseOrderDto
{
public IList<DetailItemDto> Details { get; set; }
public class DetailItemDto
{
[Required]
[StringLength(PurchaseConsts.MaxItemNumLength)]
public string ItemNum { get; set; }
[Required]
public decimal Qty { get; set; }
[Required]
public decimal Price { get; set; }
}
}
public class CreatePurchaseOrderDetailDto
{
[Required]
public Guid PurchaseOrderId { get; set; }
[Required]
[StringLength(PurchaseConsts.MaxItemNumLength)]
public string ItemNum { get; set; }
[Required]
public decimal Qty { get; set; }
[Required]
public decimal Price { get; set; }
}
public class GetPurchaseOrderListDto:PagedAndSortedResultRequestDto
{
public DateTime? BeginIDate { get; set; }
public DateTime? EndIDate { get; set;}
public string? VenName { get; set; }
public string? PoNum { get; set; }
public string? Buyer { get;}
}
public class PurchaseOrderDto
{
public Guid Id { get; set; }
public string PoNum { get; set; }
public DateTime IDate { get; set; }
public string Buyer { get; set; }
public string VenName { get; set; }
public decimal TotalQty { get; set; }
public decimal TotalAmount { get; set; }
}
public class PurchaseOrderDetailDto
{
public Guid Id { get; set; }
public string PonNum { get; set; }
public string ItemNum { get; set; }
public decimal Qty { get; set; }
public decimal Price { get; set; }
public decimal Amount { get; set; }
public Guid PurchaseOrderId { get; set; }
}
public class PurchaseOrderAndDetailDto: PurchaseOrderDto
{
public IList<PurchaseOrderDetailDto> Details { get; set; }
}
public class UpdatePurchaseOrderDetailDto
{
[Required]
[StringLength(PurchaseConsts.MaxItemNumLength)]
public string ItemNum { get; set; }
[Required]
public decimal Qty { get; set; }
[Required]
public decimal Price { get; set; }
}
public class UpdatePurchaseOrderDto
{
[Required]
[StringLength(PurchaseConsts.MaxPoNumLength)]
public string PoNum { get; set; }
[Required]
public DateTime IDate { get; set; }
[Required]
public string Buyer { get; set; }
[Required]
public string VenName { get; set; }
}
添加应用服务接口
public interface IPurchaseOrderService:IApplicationService
{
Task<PurchaseOrderAndDetailDto> GetAsync(Guid id);
Task<PurchaseOrderDetailDto> GetDetailAsync(Guid id);
Task<PagedResultDto<PurchaseOrderDto>> GetListAsync(GetPurchaseOrderListDto input);
Task<List<PurchaseOrderDetailDto>> GetDetailListAsync(Guid id);
Task<PurchaseOrderAndDetailDto> CreatePurchaseOrderAndDetailAsync(CreatePurchaseOrderAndDetailDto createPurchaseOrderAndDetail);
Task<PurchaseOrderDto> CreatePurchaseOrderAsync(CreatePurchaseOrderDto createPurchaseOrder);
Task UpdatePurchaseOrderAsync(Guid id,UpdatePurchaseOrderDto updatePurchaseOrder);
Task DeletePurchaseOrderAsync(Guid id);
Task<PurchaseOrderDetailDto> CreatePurchaseOrderDetail(CreatePurchaseOrderDetailDto createPurchaseOrderDetail);
Task UpdatePurchaseOrderDetailAsync(Guid id, UpdatePurchaseOrderDetailDto updatePurchaseOrder);
Task DeletePurchaseOrderDetailAsync(Guid id);
}
应用层
实现应用服务
/// <summary>
/// 应用层服务基类
/// </summary>
public abstract class ApplicationAppService:ApplicationService
{
protected ApplicationAppService()
{
// 配置本地资源
LocalizationResource = typeof(MyLocalizationResource);
}
}
public class PurchaseOrderService : ApplicationAppService, IPurchaseOrderService
{
private readonly IRepository<Domain.Purchase.PurchaseOrder, Guid> _repository;
private readonly IRepository<PurchaseOrderItem, Guid> _itemRepository;
private readonly PurchaseOrderManage _purchaseOrderManage;
public PurchaseOrderService(IRepository<Domain.Purchase.PurchaseOrder, Guid> repository, IRepository<PurchaseOrderItem, Guid> itemRepository, PurchaseOrderManage purchaseOrderManage)
{
_repository = repository;
_itemRepository = itemRepository;
_purchaseOrderManage = purchaseOrderManage;
}
public async Task<PurchaseOrderAndDetailDto> CreatePurchaseOrderAndDetailAsync(CreatePurchaseOrderAndDetailDto createPurchaseOrderAndDetail)
{
Check.NotNull(createPurchaseOrderAndDetail, nameof(createPurchaseOrderAndDetail));
var details = new List<Domain.Purchase.PurchaseOrderItem>();
var po = await _purchaseOrderManage.CreateAsync(createPurchaseOrderAndDetail.PoNum, createPurchaseOrderAndDetail.IDate, createPurchaseOrderAndDetail.Buyer, createPurchaseOrderAndDetail.VenName);
foreach (var item in createPurchaseOrderAndDetail.Details)
{
details.Add(_purchaseOrderManage.AddPurchaseOrderItem(po, item.ItemNum, item.Qty, item.Price));
}
/**
对资源库数据的多次修改是在一个事务中进行的,详情请见
https://docs.abp.io/zh-Hans/abp/latest/Unit-Of-Work
*/
await _repository.InsertAsync(po);
await _itemRepository.InsertManyAsync(details);
await _purchaseOrderManage.ResetPurchaseOrderTotalQtyTotalAmountAsync(po);
await _repository.UpdateAsync(po);
// 在单元工作结束而没有任何异常是,所有的数据库更改都会自动保存,因此无需手动调用 SaveChangesAsync
//await UnitOfWorkManager.Current.SaveChangesAsync();
return await GetAsync(po.Id);
}
public async Task<PurchaseOrderDto> CreatePurchaseOrderAsync(CreatePurchaseOrderDto createPurchaseOrder)
{
Check.NotNull(createPurchaseOrder, nameof(createPurchaseOrder));
var po = await _purchaseOrderManage.CreateAsync(createPurchaseOrder.PoNum, createPurchaseOrder.IDate, createPurchaseOrder.Buyer, createPurchaseOrder.VenName);
po = await _repository.InsertAsync(po);
return ObjectMapper.Map<Domain.Purchase.PurchaseOrder,PurchaseOrderDto>(po);
}
public async Task<PurchaseOrderDetailDto> CreatePurchaseOrderDetail(CreatePurchaseOrderDetailDto createPurchaseOrderDetail)
{
Check.NotNull(createPurchaseOrderDetail, nameof(createPurchaseOrderDetail));
var po = await GetPurchaseOrderAndChecked(createPurchaseOrderDetail.PurchaseOrderId);
var item = _purchaseOrderManage.AddPurchaseOrderItem(po, createPurchaseOrderDetail.ItemNum, createPurchaseOrderDetail.Qty, createPurchaseOrderDetail.Price);
await _itemRepository.InsertAsync(item);
await _purchaseOrderManage.ResetPurchaseOrderTotalQtyTotalAmountAsync(po);
await _repository.UpdateAsync(po);
return ObjectMapper.Map<PurchaseOrderItem, PurchaseOrderDetailDto>(item);
}
public async Task DeletePurchaseOrderAsync(Guid id)
{
await _repository.DeleteAsync(id);
}
public async Task DeletePurchaseOrderDetailAsync(Guid id)
{
var item = await GetPurchaseOrderItemAndChecked(id);
var po = await GetPurchaseOrderAndChecked(item.PurchaseOrderId);
await _itemRepository.DeleteAsync(id);
await _purchaseOrderManage.ResetPurchaseOrderTotalQtyTotalAmountAsync(po);
}
public async Task<PurchaseOrderAndDetailDto> GetAsync(Guid id)
{
var purchaseOrder = await _repository.GetAsync(id);
var dto = ObjectMapper.Map<Domain.Purchase.PurchaseOrder, PurchaseOrderAndDetailDto>(purchaseOrder);
dto.Details = await GetDetailListAsync(dto.Id);
return dto;
}
public async Task<PurchaseOrderDetailDto> GetDetailAsync(Guid id)
{
var detail = await _itemRepository.FindAsync(id);
return ObjectMapper.Map<PurchaseOrderItem, PurchaseOrderDetailDto>(detail);
}
public async Task<List<PurchaseOrderDetailDto>> GetDetailListAsync(Guid id)
{
var query = await _itemRepository.GetQueryableAsync();
var details = query.Where(x => x.PurchaseOrderId == id).ToList();
return ObjectMapper.Map<List<PurchaseOrderItem>, List<PurchaseOrderDetailDto>>(details);
}
public async Task<PagedResultDto<PurchaseOrderDto>> GetListAsync(GetPurchaseOrderListDto input)
{
if (input.Sorting.IsNullOrWhiteSpace())
{
input.Sorting = nameof(Domain.Purchase.PurchaseOrder.PoNum);
}
var query = await _repository.GetQueryableAsync();
query = query.WhereIf(input.BeginIDate.HasValue, p => p.IDate >= input.BeginIDate)
.WhereIf(input.EndIDate.HasValue, p => p.IDate <= input.EndIDate)
.WhereIf(!string.IsNullOrWhiteSpace(input.VenName), p => p.VenName.Contains(input.VenName == null ? string.Empty : input.VenName))
.WhereIf(!string.IsNullOrWhiteSpace(input.PoNum), p => p.PoNum.Contains(input.PoNum == null ? string.Empty : input.PoNum))
.WhereIf(!string.IsNullOrWhiteSpace(input.Buyer), p => p.PoNum.Contains(input.Buyer == null ? string.Empty : input.Buyer))
.OrderBy(input.Sorting)
.Skip(input.SkipCount)
.Take(input.MaxResultCount);
var queryResult = await AsyncExecuter.ToListAsync(query);
var totalCount = await _repository.GetCountAsync();
return new PagedResultDto<PurchaseOrderDto>(totalCount, ObjectMapper.Map<List<Domain.Purchase.PurchaseOrder>, List<PurchaseOrderDto>>(queryResult));
}
public async Task UpdatePurchaseOrderAsync(Guid id, UpdatePurchaseOrderDto updatePurchaseOrder)
{
var po = await GetPurchaseOrderAndChecked(id);
po.Buyer = updatePurchaseOrder.Buyer;
po.VenName = updatePurchaseOrder.VenName;
po.IDate = updatePurchaseOrder.IDate;
await _purchaseOrderManage.UpdatePoNum(po, updatePurchaseOrder.PoNum);
_ = await _repository.UpdateAsync(po);
}
public async Task UpdatePurchaseOrderDetailAsync(Guid id, UpdatePurchaseOrderDetailDto updatePurchaseOrder)
{
var item = await GetPurchaseOrderItemAndChecked(id);
var po = await GetPurchaseOrderAndChecked(item.PurchaseOrderId);
await _purchaseOrderManage.UpdatePurchaseOrderItem(item, updatePurchaseOrder.ItemNum, updatePurchaseOrder.Qty, updatePurchaseOrder.Price);
await _itemRepository.UpdateAsync(item);
await _purchaseOrderManage.ResetPurchaseOrderTotalQtyTotalAmountAsync(po);
await _repository.UpdateAsync(po);
}
private async Task<Domain.Purchase.PurchaseOrder> GetPurchaseOrderAndChecked(Guid id)
{
var po = await _repository.FindAsync(id);
if (po == null)
{
throw new PurchaseOrderNotExistsException(id);
}
return po;
}
private async Task<Domain.Purchase.PurchaseOrderItem> GetPurchaseOrderItemAndChecked(Guid id)
{
var item = await _itemRepository.FindAsync(id);
if (item == null)
{
var ex = new BusinessException(PurchaseConsts.PurchaseOrderItemNotExists);
ex.WithData("id", id);
throw ex;
}
return item;
}
}
标签:02,set,string,get,await,po,订单,添加,public
From: https://www.cnblogs.com/shipengfei/p/17015624.html