新增库存出入库单据及下拉选项相关接口
本次提交为物料库存管理模块增加了出入库单据的创建接口(入库单、出库单),并补充了物料及出入库类型下拉选项接口。新增了相关DTO数据结构,服务接口与实现,完善了库存变更的业务流程,所有操作均支持事务控制,提升了数据一致性和系统健壮性。
This commit is contained in:
@@ -98,5 +98,86 @@ namespace DOAN.Admin.WebApi.Controllers.BZFM
|
||||
return ToResponse(_MmInventoryService.Delete(idArr));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取物料清单下拉数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetMaterialOption")]
|
||||
public IActionResult GetMaterialOption()
|
||||
{
|
||||
var response = _MmInventoryService.GetMaterialOption();
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取出/入库操作类型下拉数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("GetTransactionOption")]
|
||||
public IActionResult GetTransactionOption()
|
||||
{
|
||||
var response = _MmInventoryService.GetTransactionOption();
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建入库单
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("CreateInboundReceipt")]
|
||||
[AllowAnonymous]
|
||||
[Log(Title = "入库单", BusinessType = BusinessType.INSERT)]
|
||||
public IActionResult CreateInboundReceipt([FromBody] InboundReceiptDto parm)
|
||||
{
|
||||
try
|
||||
{
|
||||
string response = _MmInventoryService.CreateInboundReceipt(parm);
|
||||
if(response == "ok")
|
||||
{
|
||||
return ToResponse(new ApiResult(200, "ok"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return ToResponse(new ApiResult(500, response));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建出库单
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("CreateOutboundReceipt")]
|
||||
[AllowAnonymous]
|
||||
[Log(Title = "出库单", BusinessType = BusinessType.INSERT)]
|
||||
public IActionResult CreateOutboundReceipt([FromBody] OutboundReceiptDto parm)
|
||||
{
|
||||
try
|
||||
{
|
||||
string response = _MmInventoryService.CreateOutboundReceipt(parm);
|
||||
if (response == "ok")
|
||||
{
|
||||
return ToResponse(new ApiResult(200, "ok"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return ToResponse(new ApiResult(500, response));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -60,4 +60,15 @@ namespace DOAN.Model.BZFM.Dto
|
||||
[ExcelColumn(Name = "物料类型(原材料/半成品/产成品/打包材料/辅料)")]
|
||||
public string TypeLabel { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 物料清单下拉内容
|
||||
/// </summary>
|
||||
public class MmMaterialOption
|
||||
{
|
||||
public string MaterialCode { get; set; }
|
||||
public string MaterialName { get; set; }
|
||||
public string Specification { get; set; }
|
||||
public string CategoryCode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -62,4 +62,38 @@ namespace DOAN.Model.BZFM.Dto
|
||||
[ExcelColumn(Name = "入库类型")]
|
||||
public string TransactionTypeLabel { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入库单
|
||||
/// </summary>
|
||||
public class InboundReceiptDto
|
||||
{
|
||||
public string Unit { get; set; }
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
public string Remarks { get; set; }
|
||||
public string Operator { get; set; }
|
||||
public string SupplierName { get; set; }
|
||||
public string SupplierCode { get; set; }
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
public DateTime? ProductionDate { get; set; }
|
||||
public string BatchNo { get; set; }
|
||||
[Required(ErrorMessage = "入库类型不能为空")]
|
||||
public string TransactionType { get; set; }
|
||||
[Required(ErrorMessage = "入库数量不能为空")]
|
||||
public decimal Quantity { get; set; }
|
||||
public string LocationName { get; set; }
|
||||
public string LocationCode { get; set; }
|
||||
public string WarehouseName { get; set; }
|
||||
[Required(ErrorMessage = "仓库编码不能为空")]
|
||||
public string WarehouseCode { get; set; }
|
||||
public string MaterialName { get; set; }
|
||||
[Required(ErrorMessage = "物料编码不能为空")]
|
||||
public string MaterialCode { get; set; }
|
||||
[Required(ErrorMessage = "入库单号不能为空")]
|
||||
public string InboundNo { get; set; }
|
||||
[ExcelColumn(Name = "入库类型")]
|
||||
public string TransactionTypeLabel { get; set; }
|
||||
// 1-蓝单正向 2-红单逆向
|
||||
public int ReceiptType { get; set; } = 1;
|
||||
}
|
||||
}
|
||||
@@ -56,4 +56,50 @@ namespace DOAN.Model.BZFM.Dto
|
||||
[ExcelColumn(Name = "出库类型")]
|
||||
public string TransactionTypeLabel { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出库单
|
||||
/// </summary>
|
||||
public class OutboundReceiptDto
|
||||
{
|
||||
[Required(ErrorMessage = "出库单号不能为空")]
|
||||
public string OutboundNo { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "物料编码不能为空")]
|
||||
public string MaterialCode { get; set; }
|
||||
|
||||
public string MaterialName { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "仓库编码不能为空")]
|
||||
public string WarehouseCode { get; set; }
|
||||
|
||||
public string WarehouseName { get; set; }
|
||||
|
||||
public string LocationCode { get; set; }
|
||||
|
||||
public string LocationName { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "出库数量不能为空")]
|
||||
public decimal Quantity { get; set; }
|
||||
|
||||
public string Unit { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "出库类型不能为空")]
|
||||
public string TransactionType { get; set; }
|
||||
|
||||
public string BatchNo { get; set; }
|
||||
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
public string Operator { get; set; }
|
||||
|
||||
public string Remarks { get; set; }
|
||||
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
[ExcelColumn(Name = "出库类型")]
|
||||
public string TransactionTypeLabel { get; set; }
|
||||
|
||||
// 1-蓝单正向 2-红单逆向
|
||||
public int ReceiptType { get; set; } = 1;
|
||||
}
|
||||
}
|
||||
@@ -38,4 +38,13 @@ namespace DOAN.Model.BZFM.Dto
|
||||
[ExcelColumn(Name = "状态(停用/启用)")]
|
||||
public string StatusLabel { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出入库类别对照表下拉内容
|
||||
/// </summary>
|
||||
public class MmTransactionOption
|
||||
{
|
||||
public string Label { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,25 @@ namespace DOAN.Service.BZFM.IBZFMService
|
||||
MmInventory AddMmInventory(MmInventory parm);
|
||||
int UpdateMmInventory(MmInventory parm);
|
||||
|
||||
/// <summary>
|
||||
/// 获取物料清单下拉数据
|
||||
/// </summary>
|
||||
List<MmMaterialOption> GetMaterialOption();
|
||||
|
||||
/// <summary>
|
||||
/// 获取出/入库操作类型下拉数据
|
||||
/// </summary>
|
||||
List<MmTransactionOption> GetTransactionOption();
|
||||
/// <summary>
|
||||
/// 创建入库单 成功返回ok ReceiptType = 1蓝单 ReceiptType = 2 红单(逆向)
|
||||
/// </summary>
|
||||
string CreateInboundReceipt(InboundReceiptDto parm);
|
||||
/// <summary>
|
||||
/// 创建出库单 成功返回ok
|
||||
/// </summary>
|
||||
string CreateOutboundReceipt(OutboundReceiptDto parm);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Extensions;
|
||||
using DOAN.Model.BZFM.Dto;
|
||||
using DOAN.Model.BZFM;
|
||||
using DOAN.Model.BZFM.Dto;
|
||||
using DOAN.Model.Mobile.Dto;
|
||||
using DOAN.Repository;
|
||||
using DOAN.Service.BZFM.IBZFMService;
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Extensions;
|
||||
|
||||
namespace DOAN.Service.BZFM
|
||||
{
|
||||
@@ -78,5 +79,265 @@ namespace DOAN.Service.BZFM
|
||||
|
||||
return predicate;
|
||||
}
|
||||
|
||||
public List<MmMaterialOption> GetMaterialOption()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Context.Queryable<MmMaterial>()
|
||||
.Where(it => it.Status == "启用")
|
||||
.Select(it => new MmMaterialOption
|
||||
{
|
||||
MaterialCode = it.MaterialCode,
|
||||
MaterialName = it.MaterialName,
|
||||
CategoryCode = it.CategoryCode,
|
||||
Specification = it.Specification
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public List<MmTransactionOption> GetTransactionOption()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Context.Queryable<MmTransactionType>()
|
||||
.Where(it => it.Status == "启用")
|
||||
.Select(it => new MmTransactionOption
|
||||
{
|
||||
Label = it.TypeName,
|
||||
Value = it.TypeCode
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public string CreateInboundReceipt(InboundReceiptDto parm)
|
||||
{
|
||||
try
|
||||
{
|
||||
DateTime nowDate = DateTime.Now;
|
||||
// 验证信息
|
||||
// 校验蓝单红单
|
||||
int receiptType = parm.ReceiptType;
|
||||
decimal CurrentQty = parm.Quantity;
|
||||
if(receiptType == 1)
|
||||
{
|
||||
CurrentQty = Math.Abs(CurrentQty);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentQty = - Math.Abs(CurrentQty);
|
||||
}
|
||||
|
||||
MmMaterial mmMaterial = Context.Queryable<MmMaterial>()
|
||||
.Where(it => it.MaterialCode == parm.MaterialCode)
|
||||
.First();
|
||||
if(mmMaterial == null)
|
||||
{
|
||||
return "物料不存在!";
|
||||
}
|
||||
|
||||
// 验证信息
|
||||
|
||||
MmLocation mmLocation = Context.Queryable<MmLocation>()
|
||||
.Where(it => it.LocationCode == parm.LocationCode)
|
||||
.First();
|
||||
if (mmLocation == null)
|
||||
{
|
||||
return "仓库不存在!";
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool hasInventory = true;
|
||||
MmInventory mmInventory = Context.Queryable<MmInventory>()
|
||||
.Where(it => it.MaterialCode == parm.MaterialCode)
|
||||
.Where(it => it.BatchNo == parm.BatchNo)
|
||||
.Where(it => it.LocationCode == parm.LocationCode)
|
||||
.First();
|
||||
if(mmInventory == null)
|
||||
{
|
||||
hasInventory = false;
|
||||
}
|
||||
// 启用事务
|
||||
Context.Ado.BeginTran();
|
||||
|
||||
if (!hasInventory)
|
||||
{
|
||||
|
||||
// 添加库存
|
||||
MmInventory newInventory = new MmInventory()
|
||||
{
|
||||
MaterialCode = mmMaterial.MaterialCode,
|
||||
LocationCode = mmLocation.LocationCode,
|
||||
LocationName = mmLocation.LocationName,
|
||||
WarehouseCode = mmLocation.WarehouseCode,
|
||||
WarehouseName = mmLocation.WarehouseName,
|
||||
BatchNo = parm.BatchNo,
|
||||
CurrentQty = parm.Quantity,
|
||||
Unit = parm.Unit,
|
||||
ExpiryDate = parm.ExpiryDate,
|
||||
LastUpdatedTime = null,
|
||||
ProductionDate = parm.ProductionDate,
|
||||
CreatedTime = nowDate
|
||||
};
|
||||
Context.Insertable(newInventory).ExecuteCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.Updateable(mmInventory)
|
||||
.SetColumns(it => it.CurrentQty == it.CurrentQty + CurrentQty)
|
||||
.ExecuteCommand();
|
||||
}
|
||||
// 插入记录
|
||||
MmRecordInbound newRecord = new MmRecordInbound()
|
||||
{
|
||||
// TODO处理入库单号自动累计增加
|
||||
InboundNo = "RK" + DateTime.Now.ToString("yyyyMMdd"),
|
||||
BatchNo = parm.BatchNo,
|
||||
Operator = parm.Operator,
|
||||
MaterialCode = mmMaterial.MaterialCode,
|
||||
MaterialName = mmMaterial.MaterialName,
|
||||
LocationCode = mmLocation.LocationCode,
|
||||
LocationName = mmLocation.LocationName,
|
||||
WarehouseCode = mmLocation.WarehouseCode,
|
||||
WarehouseName = mmLocation.WarehouseName,
|
||||
Quantity = parm.Quantity,
|
||||
Unit = parm.Unit,
|
||||
SupplierCode = parm.SupplierCode,
|
||||
SupplierName = parm.SupplierName,
|
||||
ProductionDate = parm.ProductionDate,
|
||||
ExpiryDate = parm.ExpiryDate,
|
||||
CreatedTime = nowDate,
|
||||
TransactionType = parm.TransactionType,
|
||||
Remarks = parm.Remarks
|
||||
};
|
||||
Context.Insertable(newRecord).ExecuteCommand();
|
||||
|
||||
Context.Ado.CommitTran();
|
||||
return "ok";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 回滚操作
|
||||
Context.Ado.RollbackTran();
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public string CreateOutboundReceipt(OutboundReceiptDto parm)
|
||||
{
|
||||
try
|
||||
{
|
||||
DateTime nowDate = DateTime.Now;
|
||||
// 验证信息
|
||||
// 校验蓝单红单
|
||||
int receiptType = parm.ReceiptType;
|
||||
decimal CurrentQty = parm.Quantity;
|
||||
if (receiptType == 1)
|
||||
{
|
||||
CurrentQty = Math.Abs(CurrentQty);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentQty = -Math.Abs(CurrentQty);
|
||||
}
|
||||
|
||||
MmMaterial mmMaterial = Context.Queryable<MmMaterial>()
|
||||
.Where(it => it.MaterialCode == parm.MaterialCode)
|
||||
.First();
|
||||
if (mmMaterial == null)
|
||||
{
|
||||
return "物料不存在!";
|
||||
}
|
||||
|
||||
// 验证信息
|
||||
|
||||
MmLocation mmLocation = Context.Queryable<MmLocation>()
|
||||
.Where(it => it.LocationCode == parm.LocationCode)
|
||||
.First();
|
||||
if (mmLocation == null)
|
||||
{
|
||||
return "仓库不存在!";
|
||||
}
|
||||
bool hasInventory = true;
|
||||
MmInventory mmInventory = Context.Queryable<MmInventory>()
|
||||
.Where(it => it.MaterialCode == parm.MaterialCode)
|
||||
.Where(it => it.BatchNo == parm.BatchNo)
|
||||
.Where(it => it.LocationCode == parm.LocationCode)
|
||||
.First();
|
||||
if (mmInventory == null)
|
||||
{
|
||||
hasInventory = false;
|
||||
}
|
||||
// 启用事务
|
||||
Context.Ado.BeginTran();
|
||||
|
||||
if (!hasInventory)
|
||||
{
|
||||
|
||||
// 添加库存
|
||||
MmInventory newInventory = new MmInventory()
|
||||
{
|
||||
MaterialCode = mmMaterial.MaterialCode,
|
||||
LocationCode = mmLocation.LocationCode,
|
||||
LocationName = mmLocation.LocationName,
|
||||
WarehouseCode = mmLocation.WarehouseCode,
|
||||
WarehouseName = mmLocation.WarehouseName,
|
||||
BatchNo = parm.BatchNo,
|
||||
CurrentQty = - parm.Quantity,
|
||||
Unit = parm.Unit,
|
||||
LastUpdatedTime = null,
|
||||
CreatedTime = nowDate
|
||||
};
|
||||
Context.Insertable(newInventory).ExecuteCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.Updateable(mmInventory)
|
||||
.SetColumns(it => it.CurrentQty == it.CurrentQty - CurrentQty)
|
||||
.ExecuteCommand();
|
||||
}
|
||||
// 插入记录
|
||||
MmRecordOutbound newRecord = new MmRecordOutbound()
|
||||
{
|
||||
// TODO处理出库单号自动累计增加
|
||||
OutboundNo = "CK" + DateTime.Now.ToString("yyyyMMdd"),
|
||||
BatchNo = parm.BatchNo,
|
||||
Operator = parm.Operator,
|
||||
MaterialCode = mmMaterial.MaterialCode,
|
||||
MaterialName = mmMaterial.MaterialName,
|
||||
LocationCode = mmLocation.LocationCode,
|
||||
LocationName = mmLocation.LocationName,
|
||||
WarehouseCode = mmLocation.WarehouseCode,
|
||||
WarehouseName = mmLocation.WarehouseName,
|
||||
Quantity = parm.Quantity,
|
||||
Unit = parm.Unit,
|
||||
CreatedTime = nowDate,
|
||||
TransactionType = parm.TransactionType,
|
||||
Remarks = parm.Remarks
|
||||
};
|
||||
Context.Insertable(newRecord).ExecuteCommand();
|
||||
Context.Ado.CommitTran();
|
||||
return "ok";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 回滚操作
|
||||
Context.Ado.RollbackTran();
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user