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