From 5121aa323e20299a39ffa1c179219049dd587812 Mon Sep 17 00:00:00 2001
From: “wangming” <“wangming@antissoft.com”>
Date: Mon, 8 Dec 2025 22:51:59 +0800
Subject: [PATCH] feat: 完善采购入库功能,支持记录采购金额和产品最终金额
---
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryCrInput.cs | 35 +++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryListOutput.cs | 30 ++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory/LqInventoryEntity.cs | 30 ++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend/LqInventoryService.cs | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
sql/添加采购入库金额字段.sql | 32 ++++++++++++++++++++++++++++++++
5 files changed, 298 insertions(+), 4 deletions(-)
create mode 100644 sql/添加采购入库金额字段.sql
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryCrInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryCrInput.cs
index 22a5859..fba9467 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryCrInput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryCrInput.cs
@@ -49,5 +49,40 @@ namespace NCC.Extend.Entitys.Dto.LqInventory
[StringLength(100, ErrorMessage = "批次号长度不能超过100个字符")]
[Display(Name = "批次号")]
public string BatchNumber { get; set; }
+
+ ///
+ /// 入库类型(1:普通入库 2:采购入库)
+ ///
+ [Range(1, 2, ErrorMessage = "入库类型必须在1-2之间")]
+ [Display(Name = "入库类型")]
+ public int? StockInType { get; set; } = 1;
+
+ ///
+ /// 采购单号
+ ///
+ [StringLength(50, ErrorMessage = "采购单号长度不能超过50个字符")]
+ [Display(Name = "采购单号")]
+ public string PurchaseOrderNo { get; set; }
+
+ ///
+ /// 采购单价
+ ///
+ [Range(0, double.MaxValue, ErrorMessage = "采购单价不能小于0")]
+ [Display(Name = "采购单价")]
+ public decimal? PurchaseUnitPrice { get; set; }
+
+ ///
+ /// 采购总金额(采购单价 × 数量,系统自动计算)
+ ///
+ [Range(0, double.MaxValue, ErrorMessage = "采购总金额不能小于0")]
+ [Display(Name = "采购总金额")]
+ public decimal? PurchaseAmount { get; set; }
+
+ ///
+ /// 产品最终金额(采购金额或其他成本)
+ ///
+ [Range(0, double.MaxValue, ErrorMessage = "产品最终金额不能小于0")]
+ [Display(Name = "产品最终金额")]
+ public decimal? FinalAmount { get; set; }
}
}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryListOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryListOutput.cs
index 10da131..1297c33 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryListOutput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventory/LqInventoryListOutput.cs
@@ -75,6 +75,36 @@ namespace NCC.Extend.Entitys.Dto.LqInventory
public string batchNumber { get; set; }
///
+ /// 入库类型(1:普通入库 2:采购入库)
+ ///
+ [Display(Name = "入库类型")]
+ public int? stockInType { get; set; }
+
+ ///
+ /// 采购单号
+ ///
+ [Display(Name = "采购单号")]
+ public string purchaseOrderNo { get; set; }
+
+ ///
+ /// 采购单价
+ ///
+ [Display(Name = "采购单价")]
+ public decimal? purchaseUnitPrice { get; set; }
+
+ ///
+ /// 采购总金额
+ ///
+ [Display(Name = "采购总金额")]
+ public decimal? purchaseAmount { get; set; }
+
+ ///
+ /// 产品最终金额
+ ///
+ [Display(Name = "产品最终金额")]
+ public decimal? finalAmount { get; set; }
+
+ ///
/// 创建人ID
///
[Display(Name = "创建人ID")]
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory/LqInventoryEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory/LqInventoryEntity.cs
index d9387ae..9ab1f1a 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory/LqInventoryEntity.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory/LqInventoryEntity.cs
@@ -54,6 +54,36 @@ namespace NCC.Extend.Entitys.lq_inventory
public string BatchNumber { get; set; }
///
+ /// 入库类型(1:普通入库 2:采购入库)
+ ///
+ [SugarColumn(ColumnName = "F_StockInType")]
+ public int? StockInType { get; set; } = 1;
+
+ ///
+ /// 采购单号
+ ///
+ [SugarColumn(ColumnName = "F_PurchaseOrderNo")]
+ public string PurchaseOrderNo { get; set; }
+
+ ///
+ /// 采购单价
+ ///
+ [SugarColumn(ColumnName = "F_PurchaseUnitPrice")]
+ public decimal? PurchaseUnitPrice { get; set; } = 0;
+
+ ///
+ /// 采购总金额(采购单价 × 数量)
+ ///
+ [SugarColumn(ColumnName = "F_PurchaseAmount")]
+ public decimal? PurchaseAmount { get; set; } = 0;
+
+ ///
+ /// 产品最终金额(采购金额或其他成本)
+ ///
+ [SugarColumn(ColumnName = "F_FinalAmount")]
+ public decimal? FinalAmount { get; set; } = 0;
+
+ ///
/// 是否有效(1:有效 0:无效)
///
[SugarColumn(ColumnName = "F_IsEffective")]
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryService.cs
index 72eb8b1..f7e655f 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryService.cs
@@ -16,6 +16,7 @@ using NCC.Extend.Entitys.lq_product;
using NCC.Extend.Interfaces.LqInventory;
using NCC.FriendlyException;
using NCC.System.Entitys.Permission;
+using NCC.System.Interfaces.System;
using SqlSugar;
using Yitter.IdGenerator;
@@ -31,6 +32,7 @@ namespace NCC.Extend
private readonly IUserManager _userManager;
private readonly ILogger _logger;
private readonly ISqlSugarClient _db;
+ private readonly IBillRullService _billRuleService;
///
/// 构造函数
@@ -38,11 +40,13 @@ namespace NCC.Extend
/// 用户管理器
/// 日志记录器
/// 数据库客户端
- public LqInventoryService(IUserManager userManager, ILogger logger, ISqlSugarClient db)
+ /// 单据规则服务
+ public LqInventoryService(IUserManager userManager, ILogger logger, ISqlSugarClient db, IBillRullService billRuleService)
{
_userManager = userManager;
_logger = logger;
_db = db;
+ _billRuleService = billRuleService;
}
#region 添加库存信息
@@ -50,9 +54,22 @@ namespace NCC.Extend
/// 添加库存信息
///
///
- /// 针对某个产品添加库存记录
+ /// 针对某个产品添加库存记录,支持普通入库和采购入库
///
- /// 示例请求:
+ /// 示例请求(普通入库):
+ /// ```json
+ /// {
+ /// "productId": "产品ID",
+ /// "quantity": 100,
+ /// "stockInTime": "2024-01-01",
+ /// "productionDate": "2023-12-01",
+ /// "shelfLife": 365,
+ /// "batchNumber": "批次号001",
+ /// "stockInType": 1
+ /// }
+ /// ```
+ ///
+ /// 示例请求(采购入库):
/// ```json
/// {
/// "productId": "产品ID",
@@ -60,9 +77,21 @@ namespace NCC.Extend
/// "stockInTime": "2024-01-01",
/// "productionDate": "2023-12-01",
/// "shelfLife": 365,
- /// "batchNumber": "批次号001"
+ /// "batchNumber": "批次号001",
+ /// "stockInType": 2,
+ /// "purchaseUnitPrice": 50.00,
+ /// "finalAmount": 5000.00
/// }
/// ```
+ ///
+ /// 参数说明:
+ /// - productId: 产品ID(必填)
+ /// - quantity: 数量(必填,大于0)
+ /// - stockInType: 入库类型(1:普通入库 2:采购入库,默认1)
+ /// - purchaseUnitPrice: 采购单价(采购入库时必填)
+ /// - purchaseAmount: 采购总金额(系统自动计算:采购单价 × 数量)
+ /// - finalAmount: 产品最终金额(采购入库时建议填写)
+ /// - purchaseOrderNo: 采购单号(采购入库时自动生成)
///
/// 创建输入
/// 创建结果
@@ -84,6 +113,56 @@ namespace NCC.Extend
throw NCCException.Oh("产品不存在");
}
+ // 验证数量
+ if (input.Quantity <= 0)
+ {
+ throw NCCException.Oh("库存数量必须大于0");
+ }
+
+ // 入库类型,默认为普通入库
+ var stockInType = input.StockInType ?? 1;
+
+ // 如果是采购入库,验证采购金额相关字段
+ string purchaseOrderNo = null;
+ decimal? purchaseUnitPrice = null;
+ decimal? purchaseAmount = null;
+ decimal? finalAmount = null;
+
+ if (stockInType == 2) // 采购入库
+ {
+ // 验证采购单价
+ if (input.PurchaseUnitPrice == null || input.PurchaseUnitPrice <= 0)
+ {
+ throw NCCException.Oh("采购入库时,采购单价必须大于0");
+ }
+
+ purchaseUnitPrice = input.PurchaseUnitPrice;
+
+ // 计算采购总金额(采购单价 × 数量)
+ purchaseAmount = purchaseUnitPrice.Value * input.Quantity;
+
+ // 产品最终金额:如果用户提供了,使用用户提供的;否则使用采购总金额
+ finalAmount = input.FinalAmount ?? purchaseAmount;
+
+ // 生成采购单号(使用单据规则服务)
+ try
+ {
+ purchaseOrderNo = await _billRuleService.GetBillNumber("PurchaseOrder", false);
+ // 如果返回的是错误信息,也使用fallback
+ if (string.IsNullOrEmpty(purchaseOrderNo) || purchaseOrderNo == "单据规则不存在")
+ {
+ _logger.LogWarning("采购单号生成失败(单据规则不存在),使用时间戳作为单号");
+ purchaseOrderNo = $"CG{DateTime.Now:yyyyMMddHHmmss}";
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "生成采购单号失败,使用时间戳作为单号");
+ // 如果生成失败,使用时间戳作为单号
+ purchaseOrderNo = $"CG{DateTime.Now:yyyyMMddHHmmss}";
+ }
+ }
+
// 创建库存记录
var inventoryEntity = new LqInventoryEntity
{
@@ -94,6 +173,11 @@ namespace NCC.Extend
ProductionDate = input.ProductionDate,
ShelfLife = input.ShelfLife,
BatchNumber = input.BatchNumber,
+ StockInType = stockInType,
+ PurchaseOrderNo = purchaseOrderNo,
+ PurchaseUnitPrice = purchaseUnitPrice,
+ PurchaseAmount = purchaseAmount,
+ FinalAmount = finalAmount,
IsEffective = StatusEnum.有效.GetHashCode(),
CreateUser = _userManager.UserId,
CreateTime = DateTime.Now
@@ -114,8 +198,26 @@ namespace NCC.Extend
///
/// 更新库存信息
///
+ ///
+ /// 更新库存记录,支持普通入库和采购入库的金额更新
+ ///
+ /// 示例请求(采购入库更新):
+ /// ```json
+ /// {
+ /// "id": "库存ID",
+ /// "productId": "产品ID",
+ /// "quantity": 100,
+ /// "stockInType": 2,
+ /// "purchaseUnitPrice": 50.00,
+ /// "finalAmount": 5000.00
+ /// }
+ /// ```
+ ///
/// 更新输入
/// 更新结果
+ /// 更新成功
+ /// 库存记录不存在或参数错误
+ /// 服务器错误
[HttpPut("Update")]
public async Task UpdateAsync([FromBody] LqInventoryUpInput input)
{
@@ -140,6 +242,57 @@ namespace NCC.Extend
throw NCCException.Oh("产品不存在");
}
+ // 验证数量
+ if (input.Quantity <= 0)
+ {
+ throw NCCException.Oh("库存数量必须大于0");
+ }
+
+ // 入库类型,默认为普通入库
+ var stockInType = input.StockInType ?? 1;
+
+ // 如果是采购入库,验证和计算采购金额
+ decimal? purchaseUnitPrice = null;
+ decimal? purchaseAmount = null;
+ decimal? finalAmount = null;
+
+ if (stockInType == 2) // 采购入库
+ {
+ // 验证采购单价
+ if (input.PurchaseUnitPrice == null || input.PurchaseUnitPrice <= 0)
+ {
+ throw NCCException.Oh("采购入库时,采购单价必须大于0");
+ }
+
+ purchaseUnitPrice = input.PurchaseUnitPrice;
+
+ // 计算采购总金额(采购单价 × 数量)
+ purchaseAmount = purchaseUnitPrice.Value * input.Quantity;
+
+ // 产品最终金额:如果用户提供了,使用用户提供的;否则使用采购总金额
+ finalAmount = input.FinalAmount ?? purchaseAmount;
+
+ // 如果原来没有采购单号,生成新的采购单号
+ if (string.IsNullOrEmpty(existingInventory.PurchaseOrderNo) || existingInventory.PurchaseOrderNo == "单据规则不存在")
+ {
+ try
+ {
+ existingInventory.PurchaseOrderNo = await _billRuleService.GetBillNumber("PurchaseOrder", false);
+ // 如果返回的是错误信息,也使用fallback
+ if (string.IsNullOrEmpty(existingInventory.PurchaseOrderNo) || existingInventory.PurchaseOrderNo == "单据规则不存在")
+ {
+ _logger.LogWarning("采购单号生成失败(单据规则不存在),使用时间戳作为单号");
+ existingInventory.PurchaseOrderNo = $"CG{DateTime.Now:yyyyMMddHHmmss}";
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "生成采购单号失败,使用时间戳作为单号");
+ existingInventory.PurchaseOrderNo = $"CG{DateTime.Now:yyyyMMddHHmmss}";
+ }
+ }
+ }
+
// 更新库存记录
existingInventory.ProductId = input.ProductId;
existingInventory.Quantity = input.Quantity;
@@ -147,6 +300,10 @@ namespace NCC.Extend
existingInventory.ProductionDate = input.ProductionDate;
existingInventory.ShelfLife = input.ShelfLife;
existingInventory.BatchNumber = input.BatchNumber;
+ existingInventory.StockInType = stockInType;
+ existingInventory.PurchaseUnitPrice = purchaseUnitPrice;
+ existingInventory.PurchaseAmount = purchaseAmount;
+ existingInventory.FinalAmount = finalAmount;
existingInventory.UpdateUser = _userManager.UserId;
existingInventory.UpdateTime = DateTime.Now;
@@ -200,6 +357,11 @@ namespace NCC.Extend
productionDate = inv.ProductionDate,
shelfLife = inv.ShelfLife,
batchNumber = inv.BatchNumber,
+ stockInType = inv.StockInType,
+ purchaseOrderNo = inv.PurchaseOrderNo,
+ purchaseUnitPrice = inv.PurchaseUnitPrice,
+ purchaseAmount = inv.PurchaseAmount,
+ finalAmount = inv.FinalAmount,
createUser = inv.CreateUser,
createUserName = "",
createTime = inv.CreateTime,
@@ -309,6 +471,11 @@ namespace NCC.Extend
productionDate = inv.ProductionDate,
shelfLife = inv.ShelfLife,
batchNumber = inv.BatchNumber,
+ stockInType = inv.StockInType,
+ purchaseOrderNo = inv.PurchaseOrderNo,
+ purchaseUnitPrice = inv.PurchaseUnitPrice,
+ purchaseAmount = inv.PurchaseAmount,
+ finalAmount = inv.FinalAmount,
createUser = inv.CreateUser,
createUserName = "",
createTime = inv.CreateTime,
diff --git a/sql/添加采购入库金额字段.sql b/sql/添加采购入库金额字段.sql
new file mode 100644
index 0000000..c394d3b
--- /dev/null
+++ b/sql/添加采购入库金额字段.sql
@@ -0,0 +1,32 @@
+-- ============================================
+-- 在库存表中添加采购入库金额相关字段
+-- ============================================
+-- 说明:为采购入库功能添加金额记录字段
+-- ============================================
+
+-- 1. 添加入库类型字段(1:普通入库 2:采购入库)
+ALTER TABLE lq_inventory
+ADD COLUMN F_StockInType INT NULL DEFAULT 1 COMMENT '入库类型(1:普通入库 2:采购入库)' AFTER F_BatchNumber;
+
+-- 2. 添加采购单号字段
+ALTER TABLE lq_inventory
+ADD COLUMN F_PurchaseOrderNo VARCHAR(50) NULL COMMENT '采购单号' AFTER F_StockInType;
+
+-- 3. 添加采购单价字段
+ALTER TABLE lq_inventory
+ADD COLUMN F_PurchaseUnitPrice DECIMAL(18,2) NULL DEFAULT 0.00 COMMENT '采购单价' AFTER F_PurchaseOrderNo;
+
+-- 4. 添加采购总金额字段(采购单价 × 数量)
+ALTER TABLE lq_inventory
+ADD COLUMN F_PurchaseAmount DECIMAL(18,2) NULL DEFAULT 0.00 COMMENT '采购总金额(采购单价 × 数量)' AFTER F_PurchaseUnitPrice;
+
+-- 5. 添加产品最终金额字段(可能是采购金额,或者采购金额+其他成本)
+ALTER TABLE lq_inventory
+ADD COLUMN F_FinalAmount DECIMAL(18,2) NULL DEFAULT 0.00 COMMENT '产品最终金额(采购金额或其他成本)' AFTER F_PurchaseAmount;
+
+-- 6. 添加索引
+ALTER TABLE lq_inventory
+ADD INDEX idx_stock_in_type (F_StockInType) COMMENT '入库类型索引';
+
+ALTER TABLE lq_inventory
+ADD INDEX idx_purchase_order_no (F_PurchaseOrderNo) COMMENT '采购单号索引';
--
libgit2 0.21.4