From d40c3f253a3d0e369403cc3f36ec842ecfbb0394 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Fri, 19 Apr 2024 08:47:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WCS.BLL/DbModels/InOutRecord.cs | 124 +++ WCS.BLL/DbModels/MatBaseInfo.cs | 16 +- WCS.BLL/DbModels/MatInfo.cs | 4 +- WCS.BLL/DbModels/OutOrder.cs | 1 + WCS.BLL/DbModels/StockTakingOrder.cs | 72 ++ WCS.BLL/DbModels/StockTakingOrderDetail.cs | 120 +++ WCS.BLL/DbModels/StoreInfo.cs | 7 +- WCS.BLL/HardWare/IShelfBase.cs | 4 +- WCS.BLL/HardWare/SingleLightShelf.cs | 4 +- WCS.BLL/HardWare/SmartShelf.cs | 10 +- WCS.BLL/Manager/ShelfManager.cs | 1 + WCS.BLL/Services/IService/IGenerateService.cs | 18 + WCS.BLL/Services/IService/IInstoreService.cs | 2 +- .../Services/IService/IStockTakingService.cs | 34 + WCS.BLL/Services/Service/GenerateService.cs | 129 ++++ WCS.BLL/Services/Service/InstoreService.cs | 57 +- .../Service/MatInventoryDetailService.cs | 1 + WCS.BLL/Services/Service/OutstoreService.cs | 13 +- .../Services/Service/StockTakingService.cs | 712 ++++++++++++++++++ WCS.BLL/Tool/PnHelp.cs | 389 ++++++++++ WCS.BLL/WCS.BLL.csproj | 5 +- .../ApiModel/InStore/QueryByMatSnResponse.cs | 4 +- .../MatBaseInfo/GenerateMatInfoRequest.cs | 22 + .../ApiModel/MatBaseInfo/MatInfoModel.cs | 36 + .../OutStore/SysOutOrderByMatCodeRequest.cs | 3 +- .../ComfirmStocktakingOrderRequest.cs | 14 + .../GetStockTakingOrderMatDetailRequest.cs | 12 + .../GetStockTakingOrdersRequest.cs | 21 + .../QueryMatInfoInStocktakingOrderRequest.cs | 11 + .../Stocktaking/SysStockTakingOrderRequest.cs | 19 + .../SysStockTakingOrderResponse.cs | 16 + WCS.WebApi/Controllers/InstoreController.cs | 2 +- .../Controllers/MatBaseInfoController.cs | 12 +- .../RequestResponseLoggingMiddleware.cs | 8 +- .../Controllers/StockTakingController.cs | 88 +++ WCS.WebApi/Program.cs | 6 +- .../PublishProfiles/FolderProfile1.pubxml | 17 + .../Resources/Interop.BarTender.dll | Bin 0 -> 171600 bytes 货架标准上位机/Resources/物料条码.btw | Bin 36560 -> 36558 bytes .../ViewModels/MatBaseInfoViewModel.cs | 26 +- .../Views/MainWindows/MainWindow1.xaml | 6 +- .../Views/MatBaseInoGenarateMatInfoView.xaml | 69 ++ .../Views/MatBaseInoGenarateMatInfoView.xaml.cs | 68 ++ 货架标准上位机/Views/MatInfoView.xaml | 283 +++++++ 货架标准上位机/Views/MatInfoView.xaml.cs | 88 +++ 货架标准上位机/货架标准上位机.csproj | 3 + 46 files changed, 2500 insertions(+), 57 deletions(-) create mode 100644 WCS.BLL/DbModels/InOutRecord.cs create mode 100644 WCS.BLL/DbModels/StockTakingOrder.cs create mode 100644 WCS.BLL/DbModels/StockTakingOrderDetail.cs create mode 100644 WCS.BLL/Services/IService/IGenerateService.cs create mode 100644 WCS.BLL/Services/IService/IStockTakingService.cs create mode 100644 WCS.BLL/Services/Service/GenerateService.cs create mode 100644 WCS.BLL/Services/Service/StockTakingService.cs create mode 100644 WCS.BLL/Tool/PnHelp.cs create mode 100644 WCS.Model/ApiModel/MatBaseInfo/GenerateMatInfoRequest.cs create mode 100644 WCS.Model/ApiModel/MatBaseInfo/MatInfoModel.cs create mode 100644 WCS.Model/ApiModel/Stocktaking/ComfirmStocktakingOrderRequest.cs create mode 100644 WCS.Model/ApiModel/Stocktaking/GetStockTakingOrderMatDetailRequest.cs create mode 100644 WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs create mode 100644 WCS.Model/ApiModel/Stocktaking/QueryMatInfoInStocktakingOrderRequest.cs create mode 100644 WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderRequest.cs create mode 100644 WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderResponse.cs create mode 100644 WCS.WebApi/Controllers/StockTakingController.cs create mode 100644 WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml create mode 100644 货架标准上位机/Resources/Interop.BarTender.dll create mode 100644 货架标准上位机/Views/MatBaseInoGenarateMatInfoView.xaml create mode 100644 货架标准上位机/Views/MatBaseInoGenarateMatInfoView.xaml.cs create mode 100644 货架标准上位机/Views/MatInfoView.xaml create mode 100644 货架标准上位机/Views/MatInfoView.xaml.cs diff --git a/WCS.BLL/DbModels/InOutRecord.cs b/WCS.BLL/DbModels/InOutRecord.cs new file mode 100644 index 0000000..715348b --- /dev/null +++ b/WCS.BLL/DbModels/InOutRecord.cs @@ -0,0 +1,124 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WCS.DAL.DbModels; + +namespace WCS.BLL.DbModels +{ + /// + /// 出入库记录 + /// + public class InOutRecord + { + /// + /// 主键 自增Id + /// + [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsNullable = false, IsIdentity = true)] + public int Id { get; set; } + + #region 库位属性 + /// + /// 入库的库位表ID + /// + [SugarColumn(ColumnName = "store_id", IsNullable = false, ColumnDescription = "库位ID")] + public int StoreId { get; set; } + /// + /// 入库的库位编码 + /// + [SugarColumn(ColumnName = "store_code", Length = 50, IsNullable = false, ColumnDescription = "库位编码")] + public string StoreCode { get; set; } + + [Navigate(NavigateType.OneToOne, nameof(StoreId))] + public StoreInfo StoreInfo { get; set; } + #endregion + + #region 物料属性 + /// + /// 物料编码(SN) + /// + [SugarColumn(ColumnName = "mat_sn", Length = 200, IsNullable = false, ColumnDescription = "物料SN")] + public string MatSN { get; set; } + /// + /// 物料编码 + /// + [SugarColumn(ColumnName = "mat_code", Length = 100, IsNullable = true, ColumnDescription = "物料编号")] + public string MatCode { get; set; } + /// + /// 物料名称 + /// + [SugarColumn(ColumnName = "mat_name", Length = 150, IsNullable = true, ColumnDescription = "物料名称")] + public string MatName { get; set; } + + /// + /// 物料规格 + /// + [SugarColumn(ColumnName = "mat_spec", Length = 150, IsNullable = true, ColumnDescription = "物料规格")] + public string MatSpec { get; set; } + + /// + /// 物料批次 + /// + [SugarColumn(ColumnName = "mat_batch", Length = 150, IsNullable = true, ColumnDescription = "物料批次")] + public string MatBatch { get; set; } + + /// + /// 物料数量 + /// + [SugarColumn(ColumnName = "mat_qty", IsNullable = false, ColumnDescription = "物料数量")] + public int MatQty { get; set; } + + /// + /// 物料供应商 + /// + [SugarColumn(ColumnName = "mat_supplier", Length = 150, IsNullable = true, ColumnDescription = "物料供应商")] + public string? MatSupplier { get; set; } + + /// + /// 物料客户 + /// + [SugarColumn(ColumnName = "mat_customer", Length = 150, IsNullable = true, ColumnDescription = "物料客户")] + public string? MatCustomer { get; set; } + #endregion + + /// + /// 出库单据号/盘点单据号 + /// + [SugarColumn(ColumnName = "order_number", Length = 50, IsNullable = false, ColumnDescription = "出库单据号/盘点单据号")] + public string? OrderNumber { get; set; } + + /// + /// 出入库方向 + /// + [SugarColumn(ColumnName = "direction", IsNullable = false, ColumnDescription = "出入库方向: 入库 = 0,\r\n 出库 = 1,\r\n 丢失 = 2")] + public DirectionEnum Direction { get; set; } + + /// + /// 是否已上传 + /// + [SugarColumn(ColumnName = "is_upload", IsNullable = false, ColumnDescription = "物料信息是否已上传")] + public bool IsUpload { get; set; } = false; + + /// + /// 创建时间 + /// + [SugarColumn(ColumnName = "operate_time", IsNullable = false, ColumnDescription = "创建时间")] + public DateTime OperateTime { get; set; } = DateTime.Now; + + /// + /// 创建人 + /// + [SugarColumn(ColumnName = "operate_user", Length = 100, IsNullable = true, ColumnDescription = "创建人")] + public string OperateUser { get; set; } + } + + public enum DirectionEnum + { + 入库 = 0, + 出库 = 1, + 丢失 = 2, + 盘点 = 3, + } +} diff --git a/WCS.BLL/DbModels/MatBaseInfo.cs b/WCS.BLL/DbModels/MatBaseInfo.cs index 5bc5ca8..a29ef42 100644 --- a/WCS.BLL/DbModels/MatBaseInfo.cs +++ b/WCS.BLL/DbModels/MatBaseInfo.cs @@ -65,11 +65,21 @@ namespace WCS.BLL.DbModels public string? MatCustomer { get; set; } /// - /// 物料数量 + /// 默认数量 /// - [SugarColumn(ColumnName = "mat_qty", IsNullable = false, ColumnDescription = "物料数量")] - public int MatQty { get; set; } = 100; + [SugarColumn(ColumnName = "default_qty", IsNullable = false, ColumnDescription = "默认数量")] + public int DefaultQty { get; set; } = 1000; + /// + /// 默认盘数 + /// + [SugarColumn(ColumnName = "default_count", IsNullable = false, ColumnDescription = "默认盘数")] + public int DefaultCount { get; set; } = 100; + /// + /// 当前序列号 + /// + [SugarColumn(ColumnName = "serial_number", IsNullable = false, DefaultValue = "0", ColumnDescription = "默认盘数")] + public int SerialNumber { get; set; } = 0; /// /// Desc:更新人 diff --git a/WCS.BLL/DbModels/MatInfo.cs b/WCS.BLL/DbModels/MatInfo.cs index 71fac64..506341e 100644 --- a/WCS.BLL/DbModels/MatInfo.cs +++ b/WCS.BLL/DbModels/MatInfo.cs @@ -71,10 +71,10 @@ namespace WCS.BLL.DbModels public int MatQty { get; set; } /// - /// 是否启用 + /// 是否已打印 /// [SugarColumn(ColumnName = "is_printed", ColumnDescription = "是否已打印")] - public bool IsPrinted { get; set; } = true; + public bool IsPrinted { get; set; } = false; /// /// Desc:更新人 /// Default: diff --git a/WCS.BLL/DbModels/OutOrder.cs b/WCS.BLL/DbModels/OutOrder.cs index d924566..c3b6971 100644 --- a/WCS.BLL/DbModels/OutOrder.cs +++ b/WCS.BLL/DbModels/OutOrder.cs @@ -58,4 +58,5 @@ namespace WCS.BLL.DbModels 部分出库 = 1, 全部出库 = 2 } + } diff --git a/WCS.BLL/DbModels/StockTakingOrder.cs b/WCS.BLL/DbModels/StockTakingOrder.cs new file mode 100644 index 0000000..cd36466 --- /dev/null +++ b/WCS.BLL/DbModels/StockTakingOrder.cs @@ -0,0 +1,72 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WCS.BLL.DbModels +{ + /// + /// 盘点单据 + /// + [SugarTable("stock_taking_order")] + public class StockTakingOrder + { + /// + /// 主键 自增Id + /// + [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsNullable = false, IsIdentity = true)] + public int Id { get; set; } + + /// + /// 盘点单据号 + /// + [SugarColumn(ColumnName = "stocktaking_order_number", Length = 50, IsNullable = false, ColumnDescription = "盘点单据号")] + public string StocktakingOrderNumber { get; set; } + + /// + /// 盘点单据状态 + /// + [SugarColumn(ColumnName = "stocktaking_order_status", IsNullable = false, ColumnDescription = "盘点单据状态")] + public StocktakingOrderStatus StocktakingOrderStatus { get; set; } = StocktakingOrderStatus.未盘点; + + /// + /// 盘点单据来源 + /// + [SugarColumn(ColumnName = "StocktakingOrderSource", Length = 50, IsNullable = true, ColumnDescription = "单据来源")] + public string? StocktakingOrderSource { get; set; } + + /// + /// 创建时间 + /// + [SugarColumn(ColumnName = "create_time", IsNullable = false, ColumnDescription = "创建时间")] + public DateTime CreateTime { get; set; } = DateTime.Now; + + /// + /// 创建人 + /// + [SugarColumn(ColumnName = "create_user", Length = 100, IsNullable = true, ColumnDescription = "创建人")] + public string CreateUser { get; set; } + + /// + /// 序号 + /// + [SugarColumn(IsIgnore = true)] + public int RowNumber { get; set; } + /// + /// 是否已经选择 + /// + [SugarColumn(IsIgnore = true)] + public bool IsSelected { get; set; } + + } + + public enum StocktakingOrderStatus + { + 未盘点 = 0, + 部分盘点 = 1, + 盘点完成 = 2, + 已提交 = 3 + } +} diff --git a/WCS.BLL/DbModels/StockTakingOrderDetail.cs b/WCS.BLL/DbModels/StockTakingOrderDetail.cs new file mode 100644 index 0000000..31f9b19 --- /dev/null +++ b/WCS.BLL/DbModels/StockTakingOrderDetail.cs @@ -0,0 +1,120 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WCS.DAL.DbModels; + +namespace WCS.BLL.DbModels +{ + /// + /// 盘点单据物料明细 + /// + [SugarTable("stock_taking_order_matdetail")] + public class StockTakingOrderMatDetail + { + /// + /// 主键 自增Id + /// + [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsNullable = false, IsIdentity = true)] + public int Id { get; set; } + /// + /// 盘点单据的主键ID + /// + [SugarColumn(ColumnName = "stocktaking_order_id", IsNullable = false)] + public int StocktakingOrderId { get; set; } + /// + /// 盘点单据号 + /// + [SugarColumn(ColumnName = "stocktaking_order_number", Length = 50, IsNullable = false, ColumnDescription = "盘点单据号")] + public string StocktakingOrderNumber { get; set; } + + #region 库位属性 + /// + /// 入库的库位表ID + /// + [SugarColumn(ColumnName = "store_id", IsNullable = false, ColumnDescription = "库位ID")] + public int StoreId { get; set; } + + /// + /// 入库的库位编码 + /// + [SugarColumn(ColumnName = "store_code", Length = 50, IsNullable = false, ColumnDescription = "库位编码")] + public string StoreCode { get; set; } + + [Navigate(NavigateType.OneToOne, nameof(StoreId))] + public StoreInfo StoreInfo { get; set; } + #endregion + + #region 物料属性 + /// + /// 物料编码(SN) + /// + [SugarColumn(ColumnName = "mat_sn", Length = 200, IsNullable = false, ColumnDescription = "物料SN")] + public string MatSN { get; set; } + /// + /// 物料编码 + /// + [SugarColumn(ColumnName = "mat_code", Length = 100, IsNullable = true, ColumnDescription = "物料编号")] + public string MatCode { get; set; } + /// + /// 物料名称 + /// + [SugarColumn(ColumnName = "mat_name", Length = 150, IsNullable = true, ColumnDescription = "物料名称")] + public string MatName { get; set; } + + /// + /// 物料规格 + /// + [SugarColumn(ColumnName = "mat_spec", Length = 150, IsNullable = true, ColumnDescription = "物料规格")] + public string MatSpec { get; set; } + + /// + /// 物料批次 + /// + [SugarColumn(ColumnName = "mat_batch", Length = 150, IsNullable = true, ColumnDescription = "物料批次")] + public string MatBatch { get; set; } + + /// + /// 物料数量 + /// + [SugarColumn(ColumnName = "mat_qty", IsNullable = false, ColumnDescription = "物料数量")] + public int MatQty { get; set; } + + /// + /// 物料供应商 + /// + [SugarColumn(ColumnName = "mat_supplier", Length = 150, IsNullable = true, ColumnDescription = "物料供应商")] + public string? MatSupplier { get; set; } + + /// + /// 物料客户 + /// + [SugarColumn(ColumnName = "mat_customer", Length = 150, IsNullable = true, ColumnDescription = "物料客户")] + public string? MatCustomer { get; set; } + #endregion + + /// + /// 该物料是否已盘点 + /// + [SugarColumn(ColumnName = "is_stocktaking", IsNullable = false, ColumnDescription = "该物料是否已盘点")] + public bool IsStocktaking { get; set; } = false; + + /// + /// 盘点数量 + /// + [SugarColumn(ColumnName = "stocktaking_qty", IsNullable = false, ColumnDescription = "盘点数量")] + public int StocktakingQty { get; set; } + /// + /// 创建时间 + /// + [SugarColumn(ColumnName = "create_time", IsNullable = false, ColumnDescription = "最后更新时间")] + public DateTime UpdateTime { get; set; } = DateTime.Now; + /// + /// 创建人 + /// + [SugarColumn(ColumnName = "create_user", Length = 100, IsNullable = true, ColumnDescription = "最后更新人")] + public string UpdateUser { get; set; } + } +} diff --git a/WCS.BLL/DbModels/StoreInfo.cs b/WCS.BLL/DbModels/StoreInfo.cs index f061e30..834b7c2 100644 --- a/WCS.BLL/DbModels/StoreInfo.cs +++ b/WCS.BLL/DbModels/StoreInfo.cs @@ -1,4 +1,5 @@ -using System; +using SqlSugar; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -12,6 +13,10 @@ namespace WCS.DAL.DbModels /// /// 库位Id /// + /// + /// 主键 自增Id + /// + //[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsNullable = false, IsIdentity = true)] public int Id { get; set; } /// diff --git a/WCS.BLL/HardWare/IShelfBase.cs b/WCS.BLL/HardWare/IShelfBase.cs index 6089ff1..6b57d8c 100644 --- a/WCS.BLL/HardWare/IShelfBase.cs +++ b/WCS.BLL/HardWare/IShelfBase.cs @@ -37,9 +37,9 @@ namespace WCS.BLL.HardWare /// public Mode CurentMode { get; set; } - public MatInfoModel InStoreData { get; set; } + public MatInfoResponse InStoreData { get; set; } - public string OutOrderNumber { get; set; }//出库模式中的单据 + public string OrderNumber { get; set; }//出库/盘点模式中的单据号 public string ModulesStr { get; set; } diff --git a/WCS.BLL/HardWare/SingleLightShelf.cs b/WCS.BLL/HardWare/SingleLightShelf.cs index 35ec74a..e63dcfb 100644 --- a/WCS.BLL/HardWare/SingleLightShelf.cs +++ b/WCS.BLL/HardWare/SingleLightShelf.cs @@ -16,9 +16,9 @@ namespace WCS.BLL.HardWare public Mode CurentMode { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string ModulesStr { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string GroupName { get; set; } - public MatInfoModel InStoreData { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public MatInfoResponse InStoreData { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public string OutOrderNumber { get; set; } + public string OrderNumber { get; set; } public void GoInInstore(string IPAdress) { diff --git a/WCS.BLL/HardWare/SmartShelf.cs b/WCS.BLL/HardWare/SmartShelf.cs index ad04c17..d737a46 100644 --- a/WCS.BLL/HardWare/SmartShelf.cs +++ b/WCS.BLL/HardWare/SmartShelf.cs @@ -96,9 +96,9 @@ namespace WCS.BLL.HardWare public string? InstoreIpAddress { get; set; } = string.Empty; - public MatInfoModel InStoreData { get; set; } + public MatInfoResponse InStoreData { get; set; } - public string OutOrderNumber { get; set; } + public string OrderNumber { get; set; } public void GoInInstore(string? IPAddress) { @@ -178,18 +178,18 @@ namespace WCS.BLL.HardWare public void GoInStocktaking() { - throw new NotImplementedException(); + this.CurentMode = Mode.盘点模式; } public void GoOutOutstore() { - throw new NotImplementedException(); + this.CurentMode = Mode.待机模式; } public void GoOutStocktaking() { - throw new NotImplementedException(); + this.CurentMode = Mode.待机模式; } void IShelfBase.Reset() diff --git a/WCS.BLL/Manager/ShelfManager.cs b/WCS.BLL/Manager/ShelfManager.cs index aba6b95..c5e15eb 100644 --- a/WCS.BLL/Manager/ShelfManager.cs +++ b/WCS.BLL/Manager/ShelfManager.cs @@ -23,6 +23,7 @@ namespace WCS.BLL.Manager DbHelp.db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo) , typeof(InventoryDetail), typeof(OutOrder), typeof(OutOrderDetail), typeof(OutOrderMatDetail) , typeof(ShelfTypeInfo), typeof(MatBaseInfo), typeof(MatInfo) + , typeof(StockTakingOrder), typeof(StockTakingOrderMatDetail), typeof(InOutRecord) ); DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord)); diff --git a/WCS.BLL/Services/IService/IGenerateService.cs b/WCS.BLL/Services/IService/IGenerateService.cs new file mode 100644 index 0000000..c2f5e61 --- /dev/null +++ b/WCS.BLL/Services/IService/IGenerateService.cs @@ -0,0 +1,18 @@ + +using WCS.BLL.DbModels; +using WCS.DAL.AuthDbModel; +using WCS.Model; +using WCS.Model.ApiModel; +using WCS.Model.ApiModel.MatBaseInfo; +using WCS.Model.ApiModel.User; + +namespace WCS.BLL.Services.IService +{ + + public interface IGenerateService + { + public Task>> generateMatInfo(GenerateMatInfoRequest request); + + public Task generateStockTakingNumber(); + } +} diff --git a/WCS.BLL/Services/IService/IInstoreService.cs b/WCS.BLL/Services/IService/IInstoreService.cs index 779ac5c..4576a2d 100644 --- a/WCS.BLL/Services/IService/IInstoreService.cs +++ b/WCS.BLL/Services/IService/IInstoreService.cs @@ -11,7 +11,7 @@ namespace WCS.BLL.Services.IService { public ResponseBase shelfGoInInStore(ShelfGoInInstoreRequest request); public ResponseBase shelfGoOutInStore(ShelfGoOutInStoreRequest request); - public ResponseBase queryByMatSn(QueryByMatSnRequest request); + public Task queryByMatSn(QueryByMatSnRequest request); public Task queryInstoreStatus(QueryByMatSnRequest request); } } diff --git a/WCS.BLL/Services/IService/IStockTakingService.cs b/WCS.BLL/Services/IService/IStockTakingService.cs new file mode 100644 index 0000000..b35785f --- /dev/null +++ b/WCS.BLL/Services/IService/IStockTakingService.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WCS.BLL.DbModels; +using WCS.Model; +using WCS.Model.ApiModel.Stocktaking; + +namespace WCS.BLL.Services.IService +{ + /// + /// 盘点模式 + /// + public interface IStockTakingService + { + public Task SysStockTakingOrder(SysStockTakingOrderRequest request); + + public Task> getStockTakingOrders(GetStockTakingOrdersRequest request); + + public Task getStockTakingOrderMatDetail(GetStockTakingOrderMatDetailRequest request); + + public Task startStockTakingOrder(GetStockTakingOrderMatDetailRequest request); + + public Task endStockTakingOrder(GetStockTakingOrderMatDetailRequest request); + + public Task queryMatInfoInStocktakingOrder(QueryMatInfoInStocktakingOrderRequest request); + + + public Task comfirmStocktakingOrder(ComfirmStocktakingOrderRequest request); + + public Task commitStockTakingOrder(GetStockTakingOrderMatDetailRequest request); + } +} diff --git a/WCS.BLL/Services/Service/GenerateService.cs b/WCS.BLL/Services/Service/GenerateService.cs new file mode 100644 index 0000000..cffa305 --- /dev/null +++ b/WCS.BLL/Services/Service/GenerateService.cs @@ -0,0 +1,129 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using TouchSocket.Core; +using WCS.BLL.DbModels; +using WCS.BLL.Services.IService; +using WCS.DAL; +using WCS.DAL.AuthDbModel; +using WCS.DAL.Db; +using WCS.Model; +using WCS.Model.ApiModel; +using WCS.Model.ApiModel.MatBaseInfo; +using WCS.Model.ApiModel.User; + +namespace WCS.BLL.Services.Service +{ + + /// + /// 需要生成序列号保证不重复的方法 + /// + public class GenerateService : IGenerateService + { + public static object matFlag = new object(); + + public static object stockTakingFlag = new object(); + public async Task>> generateMatInfo(GenerateMatInfoRequest request) + { + //校验是否被禁用 + var matBaseInfo = await DbHelp.db.Queryable() + .Where(t => t.Id == request.MatBaseInfo.Id) + .FirstAsync(); + if (matBaseInfo == null) + { + return new ResponseCommon>() + { + Code = 201, + Message = $"生成失败:该物料基础信息不存在", + Data = null + }; + } + else if (matBaseInfo.IsEnable == false) + { + return new ResponseCommon>() + { + Code = 201, + Message = $"生成失败:该物料已被禁用", + Data = null + }; + } + + //生成条码 + lock (matFlag) + { + try + { + DbHelp.db.BeginTran(); + var startNumber = matBaseInfo.SerialNumber++; + var matInfoList = new List(); + for (var i = 0; i < request.TotalCount; i++) + { + var matInfo = new MatInfo() + { + MatSn = GetMatSn(matBaseInfo, startNumber + i), + MatCode = matBaseInfo.MatCode, + MatName = matBaseInfo.MatName, + MatBatch = matBaseInfo.MatBatch, + MatSpec = matBaseInfo.MatSpec, + MatUnit = matBaseInfo.MatUnit, + MatSupplier = matBaseInfo.MatSupplier, + + MatCustomer = matBaseInfo.MatCustomer, + MatQty = request.MatQty, + ModifyUser = request.UserName + }; + matInfoList.Add(matInfo); + } + DbHelp.db.Insertable(matInfoList).ExecuteCommand(); + matBaseInfo.SerialNumber = startNumber + request.TotalCount; + DbHelp.db.Updateable(matBaseInfo).ExecuteCommand(); + DbHelp.db.CommitTran(); + return new ResponseCommon>() + { + Code = 200, + Message = "success", + Data = matInfoList + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon>() + { + Code = 201, + Message = $"生成失败:{ex.Message}", + Data = null + }; + } + } + } + + private string GetMatSn(MatBaseInfo matBaseInfo, int serialNumber) + { + var gongshi = "=A1&\"-\"&A2&A3"; + + //var matSn = matBaseInfo.MatCode + matBaseInfo.MatBatch + serialNumber.ToString().PadLeft(6, '0'); + Dictionary keyValuePairs = new Dictionary(); + keyValuePairs.Add("A1", matBaseInfo.MatCode); + keyValuePairs.Add("A2", matBaseInfo.MatName); + keyValuePairs.Add("A3", serialNumber.ToString().PadLeft(6, '0')); + var matSn = PnHelp.Jx(gongshi, keyValuePairs); + return matSn; + } + + public async Task generateStockTakingNumber() + { + lock (stockTakingFlag) + { + Thread.Sleep(1); + return "PD" + DateTime.Now.ToString("yyMMddHHmmssfff"); + } + } + } +} diff --git a/WCS.BLL/Services/Service/InstoreService.cs b/WCS.BLL/Services/Service/InstoreService.cs index 5858294..0d215fc 100644 --- a/WCS.BLL/Services/Service/InstoreService.cs +++ b/WCS.BLL/Services/Service/InstoreService.cs @@ -6,6 +6,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using WCS.BLL.Config; +using WCS.BLL.DbModels; using WCS.BLL.HardWare; using WCS.BLL.Manager; using WCS.BLL.Services.IService; @@ -79,7 +80,7 @@ namespace WCS.BLL.Services.Service }; } - public ResponseBase queryByMatSn(QueryByMatSnRequest request) + public async Task queryByMatSn(QueryByMatSnRequest request) { //获取货架 var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); @@ -100,22 +101,58 @@ namespace WCS.BLL.Services.Service Message = $"操作失败:货架[{request.ShelfCode}]不在入库模式!\r\n当前为{shelf.CurentMode}", }; } + //判断物料是否已入库 + var inventory = await DbHelp.db.Queryable().Where(t => t.MatSN == request.MatSn).FirstAsync(); + if (inventory != null) + { + return new QueryByMatSnResponse() + { + Code = 201, + Message = $"操作失败:物料{inventory.MatSN}已入库,库位为{inventory.StoreCode}", + }; + } + #region 获取物料数据 //调用接口或者直接查询数据库 - if (1 == 1) + if (1 != 1) { } //查询数据库 else { + var matInfo = await DbHelp.db.Queryable().Where(t => t.MatSn == request.MatSn).FirstAsync(); + if (matInfo != null) + { + shelf.InStoreData = new MatInfoResponse() + { + materialBar = matInfo.MatSn, + materialCode = matInfo.MatCode, + materialName = matInfo.MatName, + materialQty = matInfo.MatQty, + materialSpec = matInfo.MatSpec, + batchNo = matInfo.MatBatch, + supplier = matInfo.MatSupplier, + customer = matInfo.MatCustomer, + }; + + return new QueryByMatSnResponse() + { + Code = 200, + Data = shelf.InStoreData, + Message = "success" + }; + } + else + return new QueryByMatSnResponse() + { + Code = 201, + Data = null, + Message = $"不存在物料{request.MatSn}" + }; } - return new QueryByMatSnResponse() - { - Code = 200, - Data = new MatInfoModel(), - Message = "success" - }; + + #endregion } public async Task queryInstoreStatus(QueryByMatSnRequest request) @@ -127,7 +164,7 @@ namespace WCS.BLL.Services.Service return new ResponseCommon() { Code = 201, - Message = $"操作失败:货架[{request.ShelfCode}]不存在!", + Message = $"货架[{request.ShelfCode}]不存在!", }; } //判断当前是否是入库模式 @@ -136,7 +173,7 @@ namespace WCS.BLL.Services.Service return new ResponseCommon() { Code = 201, - Message = $"操作失败:货架[{request.ShelfCode}]不在入库模式!\r\n当前为{shelf.CurentMode}", + Message = $"货架[{request.ShelfCode}]已退出入库模式!\r\n当前为{shelf.CurentMode}", }; } //这个时间相当于需要入库扫码后需要等待的时间 diff --git a/WCS.BLL/Services/Service/MatInventoryDetailService.cs b/WCS.BLL/Services/Service/MatInventoryDetailService.cs index 2c1ca14..7c3573a 100644 --- a/WCS.BLL/Services/Service/MatInventoryDetailService.cs +++ b/WCS.BLL/Services/Service/MatInventoryDetailService.cs @@ -122,5 +122,6 @@ namespace WCS.BLL.Services.Service }; } } + } } diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index 6258029..d5a4a1b 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -32,7 +32,7 @@ namespace WCS.BLL.Services.Service //判断是否有单据号 没有单据号系统自动生成一个 if (string.IsNullOrEmpty(request.OrderNumber)) { - request.OrderNumber = GetOrderNumber(); + request.OrderNumber = GenerateOrderNumber(); } Console.WriteLine(DateTime.Now); //保存数据 @@ -128,7 +128,7 @@ namespace WCS.BLL.Services.Service //判断是否有单据号 没有单据号系统自动生成一个 if (string.IsNullOrEmpty(request.OrderNumber)) { - request.OrderNumber = GetOrderNumber(); + request.OrderNumber = GenerateOrderNumber(); } #region 保存数据 @@ -267,6 +267,7 @@ namespace WCS.BLL.Services.Service .Where(t => t.OrderId == outOrder.Id) .ToListAsync(); #endregion + var orderDetail = await orderDetailTask; var orderMatDetail = await orderMatDetailTask; return new ResponseCommon() @@ -282,8 +283,7 @@ namespace WCS.BLL.Services.Service } - - private string GetOrderNumber() + private string GenerateOrderNumber() { var orderNumber = "PD" + DateTime.Now.ToString("yyyyMMddHHmmss"); return orderNumber; @@ -291,6 +291,7 @@ namespace WCS.BLL.Services.Service public async Task GoInOutstore(GetOutOrderDetailRequest request) { + //先找到所有物料 //分组 按物料找到对应得货架编码 @@ -308,8 +309,8 @@ namespace WCS.BLL.Services.Service public async Task GoOutOutstore(GetOutOrderDetailRequest request) { - //找到出库单号一致的货架列表 - var shelves = ShelfManager.Shelves.Where(t => t.OutOrderNumber == request.OrderNumber) + //找到正在出对应出库单的货架 + var shelves = ShelfManager.Shelves.Where(t => t.OrderNumber == request.OrderNumber) .ToList(); //退出出库模式 shelves.ForEach(t => diff --git a/WCS.BLL/Services/Service/StockTakingService.cs b/WCS.BLL/Services/Service/StockTakingService.cs new file mode 100644 index 0000000..65283cb --- /dev/null +++ b/WCS.BLL/Services/Service/StockTakingService.cs @@ -0,0 +1,712 @@ +using Microsoft.Data.SqlClient; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WCS.BLL.DbModels; +using WCS.BLL.Manager; +using WCS.BLL.Services.IService; +using WCS.DAL.Db; +using WCS.DAL.DbModels; +using WCS.Model; +using WCS.Model.ApiModel.Stocktaking; + +namespace WCS.BLL.Services.Service +{ + public class StockTakingService : IStockTakingService + { + #region SysStockTakingOrder + public async Task SysStockTakingOrder(SysStockTakingOrderRequest request) + { + //先判断盘点单据号是否已存在(避免前端多次提交后生成多个的情况) + var stocktakingOrder = await DbHelp.db.Queryable() + .Where(t => t.StocktakingOrderNumber == request.StocktakingOrderNumber) + .FirstAsync(); + if (stocktakingOrder != null) + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:盘点单据{stocktakingOrder.StocktakingOrderNumber}已存在!" + }; + else + { + //分成三类 + switch (request.StocktakingOrderType) + { + case "shelfCodes": + return await SysStockTakingOrderByShelfCodes(request); + case "matCodes": + return await SysStockTakingOrderByMatCodes(request); + case "snList": + return await SysStockTakingOrderSnList(request); + default: + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:[{request.StocktakingOrderType}]不支持的操作!!" + }; + } + } + } + + public async Task SysStockTakingOrderByShelfCodes(SysStockTakingOrderRequest request) + { + //校验参数 + if (request.List == null || request.List.Count == 0) + return new SysStockTakingOrderResponse() + { + + Code = 201, + Message = $"操作失败:缺少必要参数" + }; + //先判断是否有这些货架 + var shelfs = ShelfManager.Shelves + .Where(t => request.List.Contains(t.ShelfCode)) + .ToList(); + if (shelfs.Count < request.List.Count) + { + foreach (var shelf in shelfs) + { + request.List.RemoveAll(t => t == shelf.ShelfCode); + } + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:货架[{string.Join(",", request.List)}]不存在!" + }; + } + try + { + //获取库存数据 生成盘点单据 + var inventoryDetails = await DbHelp.db.Queryable() + .Includes(t => t.StoreInfo) + .Where(t => request.List.Contains(t.StoreInfo.ShelfCode)) + .ToListAsync(); + if (inventoryDetails == null || inventoryDetails.Count == 0) + { + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:未找到需要盘点的库存数据!" + }; + } + + await DbHelp.db.BeginTranAsync(); + + //盘点单据保存 + var stockTakingOrder = new StockTakingOrder() + { + StocktakingOrderNumber = request.StocktakingOrderNumber, + StocktakingOrderSource = request.StocktakingOrderSource, + CreateUser = request.UserName + }; + var stockTakingOrderId = await DbHelp.db.Insertable(stockTakingOrder).ExecuteReturnIdentityAsync(); + stockTakingOrder.Id = stockTakingOrderId; + //盘点物料明细保存 + foreach (var inventoryDetail in inventoryDetails) + { + var stockTakingOrderMatDetail = new StockTakingOrderMatDetail() + { + StocktakingOrderId = stockTakingOrderId, + StocktakingOrderNumber = request.StocktakingOrderNumber, + + StoreId = inventoryDetail.StoreId, + StoreCode = inventoryDetail.StoreCode, + + MatSN = inventoryDetail.MatSN, + MatCode = inventoryDetail.MatCode, + MatName = inventoryDetail.MatName, + MatBatch = inventoryDetail.MatBatch, + MatSpec = inventoryDetail.MatSpec, + MatQty = inventoryDetail.MatQty, + MatCustomer = inventoryDetail.MatCustomer, + MatSupplier = inventoryDetail.MatSupplier, + + IsStocktaking = false, + StocktakingQty = inventoryDetail.MatQty, + UpdateUser = request.UserName + }; + await DbHelp.db.Insertable(stockTakingOrderMatDetail).ExecuteReturnIdentityAsync(); + } + await DbHelp.db.CommitTranAsync(); + return new SysStockTakingOrderResponse() + { + Data = new SysStockTakingOrderData() { StocktakingOrderNumber = request.StocktakingOrderNumber }, + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:{ex.Message}" + }; + } + } + + public async Task SysStockTakingOrderByMatCodes(SysStockTakingOrderRequest request) + { + //校验参数 + if (request.List == null || request.List.Count == 0) + return new SysStockTakingOrderResponse() + { + + Code = 201, + Message = $"操作失败:缺少必要参数" + }; + //获取库存数据 生成盘点单据 + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.List.Contains(t.MatCode)) + .ToListAsync(); + if (inventoryDetails == null || inventoryDetails.Count == 0) + { + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:未找到需要盘点的库存数据!" + }; + } + try + { + await DbHelp.db.BeginTranAsync(); + + //盘点单据保存 + var stockTakingOrder = new StockTakingOrder() + { + StocktakingOrderNumber = request.StocktakingOrderNumber, + StocktakingOrderSource = request.StocktakingOrderSource, + CreateUser = request.UserName + }; + var stockTakingOrderId = await DbHelp.db.Insertable(stockTakingOrder).ExecuteReturnIdentityAsync(); + stockTakingOrder.Id = stockTakingOrderId; + //盘点物料明细保存 + foreach (var inventoryDetail in inventoryDetails) + { + var stockTakingOrderMatDetail = new StockTakingOrderMatDetail() + { + StocktakingOrderId = stockTakingOrderId, + StocktakingOrderNumber = request.StocktakingOrderNumber, + + StoreId = inventoryDetail.StoreId, + StoreCode = inventoryDetail.StoreCode, + + MatSN = inventoryDetail.MatSN, + MatCode = inventoryDetail.MatCode, + MatName = inventoryDetail.MatName, + MatBatch = inventoryDetail.MatBatch, + MatSpec = inventoryDetail.MatSpec, + MatQty = inventoryDetail.MatQty, + MatCustomer = inventoryDetail.MatCustomer, + MatSupplier = inventoryDetail.MatSupplier, + + IsStocktaking = false, + StocktakingQty = inventoryDetail.MatQty, + UpdateUser = request.UserName + }; + await DbHelp.db.Insertable(stockTakingOrderMatDetail).ExecuteReturnIdentityAsync(); + } + await DbHelp.db.CommitTranAsync(); + return new SysStockTakingOrderResponse() + { + Data = new SysStockTakingOrderData() { StocktakingOrderNumber = request.StocktakingOrderNumber }, + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:{ex.Message}" + }; + } + } + + public async Task SysStockTakingOrderSnList(SysStockTakingOrderRequest request) + { + //校验参数 + if (request.List == null || request.List.Count == 0) + return new SysStockTakingOrderResponse() + { + + Code = 201, + Message = $"操作失败:缺少必要参数" + }; + //获取库存数据 生成盘点单据 + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.List.Contains(t.MatSN)) + .ToListAsync(); + if (inventoryDetails == null || inventoryDetails.Count == 0) + { + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:未找到需要盘点的库存数据!" + }; + } + try + { + await DbHelp.db.BeginTranAsync(); + + //盘点单据保存 + var stockTakingOrder = new StockTakingOrder() + { + StocktakingOrderNumber = request.StocktakingOrderNumber, + StocktakingOrderSource = request.StocktakingOrderSource, + CreateUser = request.UserName + }; + var stockTakingOrderId = await DbHelp.db.Insertable(stockTakingOrder).ExecuteReturnIdentityAsync(); + stockTakingOrder.Id = stockTakingOrderId; + //盘点物料明细保存 + foreach (var inventoryDetail in inventoryDetails) + { + var stockTakingOrderMatDetail = new StockTakingOrderMatDetail() + { + StocktakingOrderId = stockTakingOrderId, + StocktakingOrderNumber = request.StocktakingOrderNumber, + + StoreId = inventoryDetail.StoreId, + StoreCode = inventoryDetail.StoreCode, + + MatSN = inventoryDetail.MatSN, + MatCode = inventoryDetail.MatCode, + MatName = inventoryDetail.MatName, + MatBatch = inventoryDetail.MatBatch, + MatSpec = inventoryDetail.MatSpec, + MatQty = inventoryDetail.MatQty, + MatCustomer = inventoryDetail.MatCustomer, + MatSupplier = inventoryDetail.MatSupplier, + + IsStocktaking = false, + StocktakingQty = inventoryDetail.MatQty, + UpdateUser = request.UserName + }; + await DbHelp.db.Insertable(stockTakingOrderMatDetail).ExecuteReturnIdentityAsync(); + } + await DbHelp.db.CommitTranAsync(); + return new SysStockTakingOrderResponse() + { + Data = new SysStockTakingOrderData() { StocktakingOrderNumber = request.StocktakingOrderNumber }, + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + return new SysStockTakingOrderResponse() + { + Code = 201, + Message = $"操作失败:{ex.Message}" + }; + } + } + #endregion + + public async Task> getStockTakingOrders(GetStockTakingOrdersRequest request) + { + try + { + + var recordsQueryable = DbHelp.db.Queryable() + .WhereIF(!string.IsNullOrEmpty(request.StocktakingOrderNumber), t => t.StocktakingOrderNumber.Contains(request.StocktakingOrderNumber)); + + switch (request.StocktakingOrderStatus) + { + case Model.ApiModel.Stocktaking.StocktakingOrderStatus.未盘点: + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.未盘点); + break; + case Model.ApiModel.Stocktaking.StocktakingOrderStatus.部分盘点: + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.部分盘点); + break; + case Model.ApiModel.Stocktaking.StocktakingOrderStatus.已提交: + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.已提交); + break; + case Model.ApiModel.Stocktaking.StocktakingOrderStatus.盘点完成: + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.盘点完成); + break; + default: + break; + } + + var totalCount = await recordsQueryable.CountAsync(); + var records = await recordsQueryable + .Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize) + .Select() + .ToListAsync(); + //生成序号 + for (int i = 0; i < records.Count; i++) + { + records[i].RowNumber = (request.PageNumber - 1) * 10 + i + 1; + } + + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + TotalCount = totalCount, + MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize), + Count = records.Count, + Lists = records.ToList() + } + }; + + } + catch (Exception ex) + { + return new PageQueryResponse() + { + Code = 300, + Message = $"操作失败:{ex.Message}", + }; + } + } + + public async Task getStockTakingOrderMatDetail(GetStockTakingOrderMatDetailRequest request) + { + #region 查询盘点单 + StockTakingOrder order = null; + if (request.StockTakingOrderId != 0) + { + order = await DbHelp.db.Queryable().Where(t => t.Id == request.StockTakingOrderId).FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在Id为{request.StockTakingOrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.StockTakingOrderNumber)) + { + order = await DbHelp.db.Queryable().Where(t => t.StocktakingOrderNumber == request.StockTakingOrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在单据号为{request.StockTakingOrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:缺少必要参数!", + }; + } + #endregion + + //查询物料明细 + var stockTakingOrderMatDetail = await DbHelp.db.Queryable() + .Where(t => t.StocktakingOrderId == order.Id) + .ToListAsync(); + + return new ResponseCommon>() + { + Code = 200, + Message = "success", + Data = stockTakingOrderMatDetail + }; + } + + public async Task startStockTakingOrder(GetStockTakingOrderMatDetailRequest request) + { + try + { + #region 查询盘点单 + StockTakingOrder order = null; + if (request.StockTakingOrderId != 0) + { + order = await DbHelp.db.Queryable().Where(t => t.Id == request.StockTakingOrderId).FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:不存在Id为{request.StockTakingOrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.StockTakingOrderNumber)) + { + order = await DbHelp.db.Queryable().Where(t => t.StocktakingOrderNumber == request.StockTakingOrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:不存在单据号为{request.StockTakingOrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:缺少必要参数!", + }; + } + #endregion + + #region 查询物料明细 + //查询物料明细 + var stockTakingOrderMatDetail = await DbHelp.db.Queryable() + .Where(t => t.StocktakingOrderId == order.Id) + .ToListAsync(); + //TO DO 货架按物料进入盘点模式 + var shelf = ShelfManager.Shelves.First(); + shelf.GoInStocktaking(); + shelf.OrderNumber = order.StocktakingOrderNumber; + #endregion + + return new ResponseCommon() + { + Code = 200, + Message = $"success", + Data = shelf.ShelfCode + }; + } + catch (Exception ex) + { + return new ResponseCommon() + { + Code = 300, + Message = $"操作失败,{ex.Message}", + }; + } + } + + public async Task endStockTakingOrder(GetStockTakingOrderMatDetailRequest request) + { + try + { + #region 查询盘点单 + StockTakingOrder order = null; + if (request.StockTakingOrderId != 0) + { + order = await DbHelp.db.Queryable().Where(t => t.Id == request.StockTakingOrderId).FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:不存在Id为{request.StockTakingOrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.StockTakingOrderNumber)) + { + order = await DbHelp.db.Queryable().Where(t => t.StocktakingOrderNumber == request.StockTakingOrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:不存在单据号为{request.StockTakingOrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:缺少必要参数!", + }; + } + #endregion + + #region 查询当前盘点盘已启动的货架 + var shelfs = ShelfManager.Shelves.Where(t => t.CurentMode == HardWare.Mode.盘点模式 && t.OrderNumber == order.StocktakingOrderNumber).ToList(); + shelfs.ForEach(t => + { + t.GoOutStocktaking(); + }); + #endregion + + return new ResponseCommon() + { + Code = 200, + Message = $"success", + Data = shelfs.Select(t => t.ShelfCode).ToList(), + }; + } + catch (Exception ex) + { + return new ResponseCommon() + { + Code = 300, + Message = $"操作失败,{ex.Message}", + }; + } + } + + public async Task queryMatInfoInStocktakingOrder(QueryMatInfoInStocktakingOrderRequest request) + { + //判断是否有这个物料 + var storeInfo = await DbHelp.db.Queryable() + .LeftJoin((id,si)=>id.StoreId == si.Id) + .Where((id, si) => id.MatSN == request.MatSN) + .Select((id, si) => si) + .FirstAsync(); + if (storeInfo == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在物料[{request.MatSN}]", + }; + } + //判断货架是否进入入库模式 + var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == storeInfo.ShelfCode).FirstOrDefault(); + if (shelf == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"物料[{request.MatSN}不是本次需要盘点的物料!!!]", + }; + } + //进入入库模式的那个单据是否有对应的单据明细 + var stockTakingOrder = await DbHelp.db.Queryable() + .Where(t => t.StocktakingOrderNumber == shelf.OrderNumber) + .FirstAsync(); + if (stockTakingOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"未找到对应盘点单据{shelf.OrderNumber}", + }; + } + //返回具体的单据信息 + var stockTakinbgOrder = await DbHelp.db.Queryable() + .Where(t => t.StocktakingOrderId == stockTakingOrder.Id) + .Where(t => t.MatSN == request.MatSN) + .FirstAsync(); + return new ResponseCommon() + { + Code = 200, + Message = "success", + Data = stockTakinbgOrder + }; + + } + + public async Task comfirmStocktakingOrder(ComfirmStocktakingOrderRequest request) + { + //获取盘点物料明细 + var stockTakingMatDetail =await DbHelp.db.Queryable() + .Where(t => t.Id == request.Id) + .FirstAsync(); + if (stockTakingMatDetail == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在的盘点明细", + }; + } + + //修改盘点吗明细数量 + stockTakingMatDetail.StocktakingQty = request.Qty; + stockTakingMatDetail.IsStocktaking = true; + await DbHelp.db.Updateable(stockTakingMatDetail).ExecuteCommandAsync(); + return new ResponseCommon() + { + Code = 200, + Message = $"success", + }; + } + + public async Task commitStockTakingOrder(GetStockTakingOrderMatDetailRequest request) + { + try + { + #region 查询盘点单 + StockTakingOrder order = null; + if (request.StockTakingOrderId != 0) + { + order = await DbHelp.db.Queryable().Where(t => t.Id == request.StockTakingOrderId).FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:不存在Id为{request.StockTakingOrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.StockTakingOrderNumber)) + { + order = await DbHelp.db.Queryable().Where(t => t.StocktakingOrderNumber == request.StockTakingOrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:不存在单据号为{request.StockTakingOrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:缺少必要参数!", + }; + } + #endregion + + #region 判断单据状态 + if (order.StocktakingOrderStatus != DbModels.StocktakingOrderStatus.已提交) + { + return new ResponseCommon() + { + Code = 201, + Message = $"单据已提交,请勿重复提交!", + }; + } + else if (order.StocktakingOrderStatus != DbModels.StocktakingOrderStatus.盘点完成) + { + return new ResponseCommon() + { + Code = 201, + Message = $"单据未盘点完成!!!", + }; + } + #endregion + //To do 进行提交! + + return new ResponseCommon() + { + Code = 200, + Message = $"success", + }; + } + catch (Exception ex) + { + return new ResponseCommon() + { + Code = 300, + Message = $"操作失败,{ex.Message}", + }; + } + } + } +} diff --git a/WCS.BLL/Tool/PnHelp.cs b/WCS.BLL/Tool/PnHelp.cs new file mode 100644 index 0000000..c371d0b --- /dev/null +++ b/WCS.BLL/Tool/PnHelp.cs @@ -0,0 +1,389 @@ + +using Irony.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using XLParser; + +namespace WCS.BLL +{ + public static class PnHelp + { + public static string Jx(string text, string th_A1 = null) + { + var aaa = new Dictionary(); + if (!string.IsNullOrWhiteSpace(th_A1)) + aaa.Add("A1", th_A1); + + return Jx(text, aaa); + } + + public static string Jx(string text, Dictionary th = null) + { + if (!text.StartsWith("=")) + return text; + + var par = ExcelFormulaParser.Parse(text.Substring(1)); + var aaa1 = Jx(par, th); + return aaa1.AllNodes().LastOrDefault()?.Token.ValueString ?? ""; + } + + public static ParseTreeNode Jx(ParseTreeNode treeNode, Dictionary th = null) + { + var nodes = treeNode.ChildNodes; + foreach (var node in nodes) + { + //var p1 = node.Print(); + if (node.IsFunction()) + { + //函数 + var hs = node.GetFunction(); + //参数 + var csList = node.GetFunctionArguments(); + //参数 + List csa = new List(); + foreach (var cs in csList) + { + var p12 = cs.Print(); + var cs4 = cs.AllNodes().ElementAtOrDefault(3); + if (cs4 != null && (cs4.Is(GrammarNames.TokenText) || cs4.Is(GrammarNames.TokenNumber) || cs4.Is(GrammarNames.TokenBool))) + { + csa.Add(cs4.Token.ValueString); + } + else if (cs4 != null && cs4.Is(GrammarNames.TokenCell)) + { + if (th != null && th.ContainsKey(cs4.Token.ValueString)) + csa.Add(th[cs4.Token.ValueString]); + else + csa.Add(cs4.Token.ValueString); + } + else + { + var csjg = Jx(cs, th); + var aaaaaa = csjg.AllNodes().LastOrDefault(); + csa.Add(aaaaaa.Token.ValueString); + } + } + + //执行 + var val = keyValuePairs[hs].Item1.Invoke(csa); + var newval = ExcelFormulaParser.Parse("\"" + val + "\""); + + treeNode.ChildNodes.Clear(); + treeNode.ChildNodes.Add(newval); + return newval; + } + else if (node.Is(GrammarNames.Reference)) + { + return Jx(node, th); + } + else if (node.Is(GrammarNames.Formula)) + { + return Jx(node, th); + } + //else if (node.Is(GrammarNames.Cell)) + //{ + // return Jx(node, th); + //} + } + return treeNode; + } + + public static Dictionary, string>, string)> keyValuePairs = new Dictionary, string>, string)>() + { + //excel自带 + { "+",(Jia,"加号")}, + { "-",(Jian,"减号、负数")}, + { "*",(Cen,"乘号")}, + { "/",(Chu,"除号")}, + { "%",(BaiFenBi,"百分号")}, + { "^",(CenMu,"乘幂")}, + { "&",(HeBin,"和号,用于连接两个或更多的文本字符串,或者是文本与数值之间的连接。")}, + { "=",(DengYu,"等于")}, + { "<>",(BuDengYu,"不等于")}, + { ">",(DaYu,"大于")}, + { "<",(XiaoYu,"小于")}, + { ">=",(DaYuDengYu,"大于等于")}, + { "<=",(XiaoYuDengYu,"小于等于")}, + { "IF",(IF,"条件判断。IF(TRUE|FALSE,值_true,值_false)")}, + { "IFS",(IFS,"多条件判断并执行。IFS(TRUE|FALSE,值1,TRUE|FALSE,值2,...)")}, + { "AND",(AND,"多个条件判断,需要所有满足。AND(TRUE|FALSE,TRUE|FALSE,...)")}, + { "OR",(OR,"多个条件判断,需要一个满足。OR(TRUE|FALSE,TRUE|FALSE,...)")}, + { "ABS",(ABS,"绝对值。ABS(值)")}, + { "LOG",(LOG,"对数。LOG(值,[底,默认10])")}, + { "REPLACE",(REPLACE,"替换字符串。REPLACE(值,开始位置,个数,新值)")}, + { "SUBSTITUTE",(SUBSTITUTE,"替换字符串。SUBSTITUTE(值,原值,新值,[替换序号|未实现])")}, + { "MID",(MID,"截取字符串。MID(值,开始位置|负数倒取,字符个数)")}, + { "SEARCH",(SEARCH,"查找字符串,没有找到为0。SEARCH(查找值,值,[开始位置])")}, + { "TRIM",(TRIM,"清除前后空格。TRIM(值)")}, + { "LEN",(LEN,"获取长度。LEN(值)")}, + //自定义函数 + { "REVERSE",(REVERSE,"反转字符串。REVERSE(值)")}, + { "REPLACES",(REPLACES,"替换多个字符串。REPLACES(值,新值,旧值1,旧值2,...)")}, + { "CONTAINS",(CONTAINS,"字符串中是否存在。CONTAINS(值,值1,值2,...)")}, + { "WHERENUM",(WHERENUM,"只保留数字。WHERENUM(值)")}, + { "WHEREAZ",(WHEREAZ,"只保留字母。WHEREAZ(值)")}, + { "WHERENUMAZ",(WHERENUMAZ,"只保留数字和字母。WHERENUMAZ(值)")}, + { "SPLIT",(SPLIT,"分隔字符串。SPLIT(值,分隔值,取的位置|负数倒取)")}, + { "PADLEFT",(PADLEFT,"字符串左侧填充字符,实现右对齐。PADLEFT(值,长度,对齐字符)")}, + { "PADRIGHT",(PADRIGHT,"字符串右侧填充字符,实现左对齐。PADRIGHT(值,长度,对齐字符)")}, + { "MIDLOG10",(MIDLOG10,"截取后计算10底的对数(如:1000=102)。MIDLOG10(值,截取长度,1输出截取|2不输出截取)")}, + { "MIDLOG10R",(MIDLOG10R,"尾位当做10底的对数转为整数(如:102=1000)。MIDLOG10R(值,[尾位长度])")}, + { "KILO4",(KILO4,"千值转为4长度字符串(如:1000=001K)。KILO4(值,从小到大的3个长度的字符单位)")}, + { "KILO4R",(KILO4R,"4长度字符串转为千值(如:001K=1000)。KILO4R(值,从小到大的3个长度的字符单位)")}, + }; + + static string Jia(List data) + { + return (Convert.ToDecimal(data[0]) + Convert.ToDecimal(data[1])).ToString(); + } + static string Jian(List data) + { + if (data.Count() == 1) + return (0m - Convert.ToDecimal(data[0])).ToString(); + else + return (Convert.ToDecimal(data[0]) - Convert.ToDecimal(data[1])).ToString(); + } + static string Cen(List data) + { + return (Convert.ToDecimal(data[0]) * Convert.ToDecimal(data[1])).ToString(); + } + static string Chu(List data) + { + return (Convert.ToDecimal(data[0]) / Convert.ToDecimal(data[1])).ToString(); + } + static string BaiFenBi(List data) + { + return (Convert.ToDecimal(data[0]) / 100m).ToString(); + } + static string CenMu(List data) + { + return (Math.Pow(Convert.ToDouble(data[0]), Convert.ToDouble(data[1]))).ToString(); + } + static string HeBin(List data) + { + return string.Join("", data); + } + static string DengYu(List data) + { + return (data[0] == data[1]).ToString().ToUpper(); + } + static string BuDengYu(List data) + { + return (data[0] != data[1]).ToString().ToUpper(); + } + static string DaYu(List data) + { + return (Convert.ToDecimal(data[0]) > Convert.ToDecimal(data[1])).ToString().ToUpper(); + } + static string XiaoYu(List data) + { + return (Convert.ToDecimal(data[0]) < Convert.ToDecimal(data[1])).ToString().ToUpper(); + } + static string DaYuDengYu(List data) + { + return (Convert.ToDecimal(data[0]) >= Convert.ToDecimal(data[1])).ToString().ToUpper(); + } + static string XiaoYuDengYu(List data) + { + return (Convert.ToDecimal(data[0]) <= Convert.ToDecimal(data[1])).ToString().ToUpper(); + } + static string IF(List data) + { + return (data[0] == "TRUE" ? data[1] : data[2]).ToString(); + } + static string IFS(List data) + { + int i = 0; + while (true) + { + if (data[i * 2] == "TRUE") + return data[(i * 2) + 1]; + i++; + } + } + static string AND(List data) + { + return (data.All(o => o == "TRUE")).ToString().ToUpper(); + } + static string OR(List data) + { + return (data.Any(o => o == "TRUE")).ToString().ToUpper(); + } + static string ABS(List data) + { + return Math.Abs(Convert.ToDecimal(data[0])).ToString(); + } + static string LOG(List data) + { + return Math.Log(Convert.ToDouble(data[0]), data.Count() == 1 ? 10 : Convert.ToDouble(data[1])).ToString(); + } + static string REPLACE(List data) + { + return $"{data[0].Substring(0, Convert.ToInt32(data[1]) - 1)}{data[3]}{data[0].Substring(Convert.ToInt32(data[1]) + Convert.ToInt32(data[2]) - 1)}"; + } + static string SUBSTITUTE(List data) + { + return data.Count == 3 ? data[0].Replace(data[1], data[2]) : data[0].Replace(data[1], data[2]); + } + static string MID(List data) + { + return Convert.ToInt32(data[1]) > 0 ? new string(data[0].Skip(Convert.ToInt32(data[1]) - 1).Take(Convert.ToInt32(data[2])).ToArray()) : new string(data[0].Reverse().Skip(Math.Abs(Convert.ToInt32(data[1])) - 1).Take(Convert.ToInt32(data[2])).Reverse().ToArray()); + } + static string SEARCH(List data) + { + var v1 = (data.Count() == 2 ? data[1].IndexOf(data[0]) + 1 : data[1].Substring(Convert.ToInt32(data[2])).IndexOf(data[0]) + 1); + return (v1 == 0 ? 0 : data.Count() == 2 ? v1 : v1 + Convert.ToInt32(data[2])).ToString(); + } + static string TRIM(List data) + { + return data[0].Trim(); + } + static string LEN(List data) + { + return data[0].Length.ToString(); + } + static string REVERSE(List data) + { + return new string(data[0].Reverse().ToArray()); + } + static string REPLACES(List data) + { + var va = data[0]; + foreach (var v in data.Skip(2)) + { + va = va.Replace(v, data[1]); + } + return va; + } + static string CONTAINS(List data) + { + foreach (var item in data.Skip(1)) + { + if (data[0].Contains(item)) + return "TRUE"; + } + return "FALSE"; + } + static string WHERENUM(List data) + { + var sb = new StringBuilder(); + foreach (var item in data[0]) + if (Char.IsDigit(item)) + sb.Append(item); + + return sb.ToString(); + } + static string WHEREAZ(List data) + { + var sb = new StringBuilder(); + foreach (var item in data[0]) + if (Char.IsLetter(item)) + sb.Append(item); + + return sb.ToString(); + } + static string WHERENUMAZ(List data) + { + var sb = new StringBuilder(); + foreach (var item in data[0]) + if (Char.IsLetterOrDigit(item)) + sb.Append(item); + + return sb.ToString(); + } + static string SPLIT(List data) + { + return Convert.ToInt32(data[2]) > 0 ? data[0].Split(new string[] { data[1] }, StringSplitOptions.None).ElementAtOrDefault(Convert.ToInt32(data[2]) - 1) : data[0].Split(new string[] { data[1] }, StringSplitOptions.None).Reverse().ElementAtOrDefault(Math.Abs(Convert.ToInt32(data[2])) - 1); + } + static string PADLEFT(List data) + { + return data[0].PadLeft(Convert.ToInt32(data[1]), data[2].First()); + } + static string PADRIGHT(List data) + { + return data[0].PadRight(Convert.ToInt32(data[1]), data[2].First()); + } + static string MIDLOG10R(List data) + { + var cc = data[0].Length - (data.Count > 1 ? Convert.ToInt32(data[1]) : 1); + var v1 = Convert.ToInt32(data[0].Substring(0, cc)); + var v2 = Convert.ToInt32(data[0].Substring(cc)); + return (v1 * Math.Pow(10, v2)).ToString(); + } + static string MIDLOG10(List data) + { + var d1 = (Int32)Convert.ToDecimal(data[0]); + var d2 = Convert.ToInt32(data[1]); + var d3 = Convert.ToInt32(data[2]); + var ws = Convert.ToInt32(new string(d1.ToString().Take(d2).ToArray())); + var log = ws == 0 ? 0 : Math.Log10(d1 / ws); + if (double.IsNaN(log) || double.IsInfinity(log)) + log = 0; + + return d3 == 1 ? (ws.ToString() + log).PadLeft(d2, '0') : log.ToString(); + } + static string KILO4(List data) + { + var d1 = Convert.ToDecimal(data[0]); + var d2 = data[1].Skip(0).First(); + var d3 = data[1].Skip(1).First(); + var d4 = data[1].Skip(2).First(); + if (d1 <= 0) + { + return "000" + d2; + } + else if (d1 < 1) + { + return d1.ToString().Replace('.', d2).Trim('0').PadLeft(4, '0').Substring(0, 4); + } + else if (d1 < 1000) + { + var aa = d1.ToString().Replace('.', d2); + return (aa.IndexOf(d2) == -1 ? (aa + d2) : aa).PadLeft(4, '0').Substring(0, 4); + } + else if (d1 < 1000 * 1000) + { + d1 = d1 / 1000m; + var aa = d1.ToString().Replace('.', d3); + return (aa.IndexOf(d3) == -1 ? (aa + d3) : aa).PadLeft(4, '0').Substring(0, 4); + } + else if (d1 < 1000 * 1000 * 1000) + { + d1 = d1 / (1000m * 1000m); + var aa = d1.ToString().Replace('.', d4); + return (aa.IndexOf(d4) == -1 ? (aa + d4) : aa).PadLeft(4, '0').Substring(0, 4); + } + else + { + return "999" + d4; + } + } + static string KILO4R(List data) + { + var d2 = data[1].Skip(0).First(); + var d3 = data[1].Skip(1).First(); + var d4 = data[1].Skip(2).First(); + + if (data[0].Contains(d2)) + { + return Convert.ToDecimal(data[0].Replace(d2, '.')).ToString(); + } + else if (data[0].Contains(d3)) + { + return (Convert.ToDecimal(data[0].Replace(d3, '.')) * 1000m).ToString(); + } + else if (data[0].Contains(d4)) + { + return (Convert.ToDecimal(data[0].Replace(d4, '.')) * 1000m * 1000m).ToString(); + } + else + { + return Convert.ToDecimal(data[0]).ToString(); + } + } + } +} diff --git a/WCS.BLL/WCS.BLL.csproj b/WCS.BLL/WCS.BLL.csproj index 6c0a955..efc647d 100644 --- a/WCS.BLL/WCS.BLL.csproj +++ b/WCS.BLL/WCS.BLL.csproj @@ -8,11 +8,12 @@ + - + - + diff --git a/WCS.Model/ApiModel/InStore/QueryByMatSnResponse.cs b/WCS.Model/ApiModel/InStore/QueryByMatSnResponse.cs index 8f32c3f..478e753 100644 --- a/WCS.Model/ApiModel/InStore/QueryByMatSnResponse.cs +++ b/WCS.Model/ApiModel/InStore/QueryByMatSnResponse.cs @@ -8,10 +8,10 @@ namespace WCS.Model { public class QueryByMatSnResponse : ResponseBase { - public MatInfoModel Data { get; set; } + public MatInfoResponse Data { get; set; } } - public class MatInfoModel + public class MatInfoResponse { public string materialBar { get; set; } diff --git a/WCS.Model/ApiModel/MatBaseInfo/GenerateMatInfoRequest.cs b/WCS.Model/ApiModel/MatBaseInfo/GenerateMatInfoRequest.cs new file mode 100644 index 0000000..889f238 --- /dev/null +++ b/WCS.Model/ApiModel/MatBaseInfo/GenerateMatInfoRequest.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; +using WCS.BLL.DbModels; + +namespace WCS.Model.ApiModel.MatBaseInfo +{ + public class GenerateMatInfoRequest:RequestBase + { + public MatBaseInfoModel MatBaseInfo { get; set; } + + /// + /// 每盘数量 + /// + public int MatQty { get; set; } + + /// + /// 本次生成的盘数 + /// + public int TotalCount { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MatBaseInfo/MatInfoModel.cs b/WCS.Model/ApiModel/MatBaseInfo/MatInfoModel.cs new file mode 100644 index 0000000..6a61f84 --- /dev/null +++ b/WCS.Model/ApiModel/MatBaseInfo/MatInfoModel.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MatBaseInfo +{ + public class MatInfoModel + { + + public int Id { get; set; } + + public string MatSn { get; set; } + + public string MatCode { get; set; } + + public string MatName { get; set; } + + public string? MatSpec { get; set; } + + public string? MatUnit { get; set; } + + public string? MatBatch { get; set; } + + public string? MatSupplier { get; set; } + + public string? MatCustomer { get; set; } + + public int MatQty { get; set; } + + public bool IsPrinted { get; set; } + + public string? ModifyUser { get; set; } + + public DateTime? ModifyTime { get; set; } = DateTime.Now; + } +} diff --git a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs index 5d64e8a..d729437 100644 --- a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs +++ b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs @@ -18,13 +18,12 @@ namespace WCS.Model public string OrderType { get; set; } public List ItemList { get; set; } - } + public class MatCodeItemList { public string MatCode { get; set; } public string MatBatch { get; set; } public int ReqQty { get; set; } - } } diff --git a/WCS.Model/ApiModel/Stocktaking/ComfirmStocktakingOrderRequest.cs b/WCS.Model/ApiModel/Stocktaking/ComfirmStocktakingOrderRequest.cs new file mode 100644 index 0000000..20ce1c9 --- /dev/null +++ b/WCS.Model/ApiModel/Stocktaking/ComfirmStocktakingOrderRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Stocktaking +{ + public class ComfirmStocktakingOrderRequest + { + public int Id { get; set; } + public string StocktakingOrderNumber { get; set; } + public string MatSN { get; set; } + public int Qty { get; set; } + } +} diff --git a/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrderMatDetailRequest.cs b/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrderMatDetailRequest.cs new file mode 100644 index 0000000..18eeea9 --- /dev/null +++ b/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrderMatDetailRequest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Stocktaking +{ + public class GetStockTakingOrderMatDetailRequest + { + public int StockTakingOrderId { get; set; } + public string StockTakingOrderNumber { get; set; } + } +} diff --git a/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs b/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs new file mode 100644 index 0000000..498ec26 --- /dev/null +++ b/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Stocktaking +{ + public class GetStockTakingOrdersRequest : PageQueryRequestBase + { + public string StocktakingOrderNumber { get; set; } + + public StocktakingOrderStatus? StocktakingOrderStatus { get; set; } + } + + public enum StocktakingOrderStatus + { + 未盘点 = 0, + 部分盘点 = 1, + 盘点完成 = 2, + 已提交 = 3 + } +} diff --git a/WCS.Model/ApiModel/Stocktaking/QueryMatInfoInStocktakingOrderRequest.cs b/WCS.Model/ApiModel/Stocktaking/QueryMatInfoInStocktakingOrderRequest.cs new file mode 100644 index 0000000..0e46f23 --- /dev/null +++ b/WCS.Model/ApiModel/Stocktaking/QueryMatInfoInStocktakingOrderRequest.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Stocktaking +{ + public class QueryMatInfoInStocktakingOrderRequest:RequestBase + { + public string MatSN { get; set; } + } +} diff --git a/WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderRequest.cs b/WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderRequest.cs new file mode 100644 index 0000000..d37823d --- /dev/null +++ b/WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderRequest.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Stocktaking +{ + public class SysStockTakingOrderRequest : RequestBase + { + + public string StocktakingOrderNumber { get; set; } + + public string StocktakingOrderSource { get; set; } + + public string StocktakingOrderType { get; set; } + + public List List { get; set; } + } + +} diff --git a/WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderResponse.cs b/WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderResponse.cs new file mode 100644 index 0000000..4b66ac5 --- /dev/null +++ b/WCS.Model/ApiModel/Stocktaking/SysStockTakingOrderResponse.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Stocktaking +{ + public class SysStockTakingOrderResponse : ResponseBase + { + + } + + public class SysStockTakingOrderData + { + public string StocktakingOrderNumber { get; set; } + } +} diff --git a/WCS.WebApi/Controllers/InstoreController.cs b/WCS.WebApi/Controllers/InstoreController.cs index d0ea3ab..736251e 100644 --- a/WCS.WebApi/Controllers/InstoreController.cs +++ b/WCS.WebApi/Controllers/InstoreController.cs @@ -88,7 +88,7 @@ namespace WebApi.Controllers [HttpPost(Name = "queryByMatSn")] public async Task queryByMatSn(QueryByMatSnRequest request) { - return _instoreService.queryByMatSn(request); + return await _instoreService.queryByMatSn(request); } /// diff --git a/WCS.WebApi/Controllers/MatBaseInfoController.cs b/WCS.WebApi/Controllers/MatBaseInfoController.cs index 70834ad..85b2eca 100644 --- a/WCS.WebApi/Controllers/MatBaseInfoController.cs +++ b/WCS.WebApi/Controllers/MatBaseInfoController.cs @@ -24,9 +24,12 @@ namespace WCS.WebApi.Controllers { public IMatBaseInfoService _matBaseInfoService { get; set; } - public MatBaseInfoController(IMatBaseInfoService matBaseInfoService) + public IGenerateService _generateMatInfoService { get; set; } + + public MatBaseInfoController(IMatBaseInfoService matBaseInfoService, IGenerateService generateMatInfoService) { _matBaseInfoService = matBaseInfoService; + _generateMatInfoService = generateMatInfoService; } [Route("getMatBaseInfo")] @@ -100,5 +103,12 @@ namespace WCS.WebApi.Controllers { return await _matBaseInfoService.getMatCodeList(request); } + + + [HttpPost("generateMatInfo")] + public async Task>> generateMatInfo(GenerateMatInfoRequest request) + { + return await _generateMatInfoService.generateMatInfo(request); + } } } diff --git a/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs b/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs index 8456dda..7376953 100644 --- a/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs +++ b/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs @@ -3,6 +3,7 @@ using System.Text; using WCS.BLL; using WCS.BLL.DbModels; using WCS.DAL.Db; +using WCS.Model; namespace WCS.WebApi.Controllers { @@ -61,7 +62,12 @@ namespace WCS.WebApi.Controllers } catch (Exception e) { - //Logs.Write(e.Message); + + //return new ResponseCommon() + //{ + // Code = 300, + // Message = $"操作失败:{e.Message}" + //}; } finally diff --git a/WCS.WebApi/Controllers/StockTakingController.cs b/WCS.WebApi/Controllers/StockTakingController.cs new file mode 100644 index 0000000..9687d65 --- /dev/null +++ b/WCS.WebApi/Controllers/StockTakingController.cs @@ -0,0 +1,88 @@ +using Microsoft.AspNetCore.Mvc; +using WCS.BLL.Services.IService; +using WCS.Model; +using WCS.Model.ApiModel; +using WCS.Model.ApiModel.MatInventoryDetail; +using WCS.Model.ApiModel.Stocktaking; +using WCS.Model.ApiModel.User; + +namespace WCS.WebApi.Controllers +{ + /// + /// 权限/用户界面的接口 + /// + [ApiController] + [Route("[controller]")] + public class StockTakingController : ControllerBase + { + public IStockTakingService _stockTakingService { get; set; } + + public IGenerateService _generateService { get; set; } + + public StockTakingController(IStockTakingService stockTakingService, IGenerateService generateService) + { + _stockTakingService = stockTakingService; + _generateService = generateService; + } + + [Route("SysStockTakingOrder")] + [HttpPost(Name = "SysStockTakingOrder")] + public async Task SysStockTakingOrder(SysStockTakingOrderRequest request) + { + //判断盘点单号是否已输入 + if (string.IsNullOrEmpty(request.StocktakingOrderNumber)) + request.StocktakingOrderNumber = await _generateService.generateStockTakingNumber(); + return await _stockTakingService.SysStockTakingOrder(request); + } + + [Route("getStockTakingOrders")] + [HttpPost(Name = "getStockTakingOrders")] + public async Task getStockTakingOrders(GetStockTakingOrdersRequest request) + { + return await _stockTakingService.getStockTakingOrders(request); + } + + [Route("getStockTakingOrderMatDetail")] + [HttpPost(Name = "getStockTakingOrderMatDetail")] + public async Task getStockTakingOrderMatDetail(GetStockTakingOrderMatDetailRequest request) + { + return await _stockTakingService.getStockTakingOrderMatDetail(request); + } + + [Route("startStockTakingOrder")] + [HttpPost(Name = "startStockTakingOrder")] + public async Task startStockTakingOrder(GetStockTakingOrderMatDetailRequest request) + { + return await _stockTakingService.startStockTakingOrder(request); + } + + [Route("endStockTakingOrder")] + [HttpPost(Name = "endStockTakingOrder")] + public async Task endStockTakingOrder(GetStockTakingOrderMatDetailRequest request) + { + return await _stockTakingService.endStockTakingOrder(request); + } + + + [Route("queryMatInfoInStocktakingOrder")] + [HttpPost(Name = "queryMatInfoInStocktakingOrder")] + public async Task queryMatInfoInStocktakingOrder(QueryMatInfoInStocktakingOrderRequest request) + { + return await _stockTakingService.queryMatInfoInStocktakingOrder(request); + } + + [Route("comfirmStocktakingOrder")] + [HttpPost(Name = "comfirmStocktakingOrder")] + public async Task comfirmStocktakingOrder(ComfirmStocktakingOrderRequest request) + { + return await _stockTakingService.comfirmStocktakingOrder(request); + } + + [Route("commitStocktakingOrder")] + [HttpPost(Name = "commitStocktakingOrder")] + public async Task commitStocktakingOrder(GetStockTakingOrderMatDetailRequest request) + { + return await _stockTakingService.commitStockTakingOrder(request); + } + } +} diff --git a/WCS.WebApi/Program.cs b/WCS.WebApi/Program.cs index e531e97..756372a 100644 --- a/WCS.WebApi/Program.cs +++ b/WCS.WebApi/Program.cs @@ -5,8 +5,6 @@ using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Text; -using TouchSocket.Core; -using TouchSocket.Sockets; using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.BLL.Services.Service; @@ -14,7 +12,6 @@ using WCS.DAL; using WCS.DAL.Db; using WCS.WebApi; using WCS.WebApi.Controllers; -using TcpClient = TouchSocket.Sockets.TcpClient; namespace WebApi { @@ -62,6 +59,9 @@ namespace WebApi builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); + //롢ɵõģʽ + builder.Services.AddSingleton(); var app = builder.Build(); diff --git a/WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml b/WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml new file mode 100644 index 0000000..36847ea --- /dev/null +++ b/WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml @@ -0,0 +1,17 @@ + + + + + false + false + true + Release + Any CPU + FileSystem + bin\Release\net6.0\publish\ + FileSystem + <_TargetId>Folder + + \ No newline at end of file diff --git a/货架标准上位机/Resources/Interop.BarTender.dll b/货架标准上位机/Resources/Interop.BarTender.dll new file mode 100644 index 0000000000000000000000000000000000000000..4f88a5d7480635046e0acb12abec1584cbaf117e GIT binary patch literal 171600 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 0QB=Bg_mw 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℞q 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 literal 0 HcmV?d00001 diff --git a/货架标准上位机/Resources/物料条码.btw b/货架标准上位机/Resources/物料条码.btw index 0e5676fa80fcb6a5e1517f99b118cb04b956574e..fc66a03145012ba298cb7d4ed165232eb9a3d325 100644 GIT binary patch delta 3087 zcmV+q4Dj>NodV9C0fe0VN3~M~*@}qM4wijX@Z=x?QG5cNl0Iy8J zy3v>U0IHF$KVbd~xm0lp9U`aeT<5y8-F5kYBp+Q5U1*N?FuF~LFbJFrpqJ568bMu) zl8-RVcm*XtxjnNa#>ZqbnM!tU^o_3)NU0E3*I>J0sN^<9ZI~ie&`)k%mWv@@!QG$; znebPZC529%VpIC4d`=yzu0|L{<&}b7pkEOTMbQsJ66uLTH!3>JIgQdnrqqxz{alfM z-i9$9SX=BQ^44REG0fYQHZMC#)*LAOcXlF`x>=P6P%=dnFERL1^dANR{^A$hkgQxW zMUpmB8KwI3XbsQ_8<0F2szF`}v|vX%nfL?}Z6e;t?7)`h(!of_K%}aB|49E9W1Ctt zY7g%=rxDXyxOQ51+=}h>bC}o`XL<~OgJn{flDQUNB~8sPGL5YyImI$W;HqW#_qB(n8w;vb%p@e3 z19K54=EDM52#c`&rHB!=*u`bo)#Y#*1%f0 zNoSoht|SyccqF!RAlBdMz(zfPO$QOlK2oxheR`?Fnpw#AFdya0H4Im?Z)ce+#VZ|@ zPlU>qYdcK0(jn@enw|wT5bc601so+a=7n{h%U&k5o+oc73wj(wgga55&V)vTDAq}q zi2{;|-htGzO|kwI7MxK6i`JJ8-oI(2x!_JI{3SBy;kG|V4nKNLtba>?>5W|*d~0_! zzZW@wZ3w0!=!`Ud*7QomJM0Nh#ox^Csm<7ofcj39=_DR?41Q7Y4-?BvU@Lo^o2hGn3FVyDt}P!btXWK2OAj?Yxvv= zJ>VU7iZyn_Rncdoie~+H=IP`I#?i^McGUI0uwhTr4{v_^uAdeTKaw}>YT+!%_hF(hd^IUo?K3D12f35;5nIJLVjX1SP^Q<$|o|I(d%K6twN>AhRa zAG@sL5*M@JRDWUC`+*>>vy|(^Fw661|JKKJgz^hCil8(wIvIYeopO=MMW!-+&&x6u?kqiFe;u>TFuAMVSxx*}H%qr)*OqxZDp^8^# zRmh8ZJgz61m8+d1R%{rS0=zR2De%ltd>3=ZtRiX@qY$H<$HJvLHo$;<18Gn%( z?MBNd8CYmRD@s`$rK|!7_maHEOR&ss$(?b7D-)}94w10horf=%af6~-4Lvf`d4({K1#X;^S`1mk!5 zZGR->Ppk`O2GhKu4~#amG441ftE_jlDsx`f|}CA(Q_BjE}OwQ;8lP z1By>!ILabz%uhNm!S?JTU%yte1J_U?#($R{WgKJJdW^?4i71h^Z<@B>-gx_H>&%81 zUQe!`9o~Mit{?M!u73PV`tdE)i};vPK1qb29z&TRD@NtjLPaTDuYF+PMCZo zAPD%BDE`EwQK&G};wb)zMORYEnWDa7QNe)G_ObUjNBY)PDE41 z#GFcy;#iopR+$fM->XH8C71H4FzfZJHH>B0t20_uL{i8cSK0m~4&8CdR{5lm=h1kl zIafd1IqB+WS3jSwZ(WlfiYI@^du_4J{K3+o50vif4r`kI|G8(i>kwxVA=#x5crv^< zy_j;?j9Tm(5nx$RTqkeQG85~WX<4-F6LmgtS{E&9=ny8oVIlC8tO`!zTcpLq!x%c6 zbT|UfCgGHCRv0WJuU+W;RYp!VaER3A@{8D;vs0!ieI8zT1+8 z&M9f>6jC;SY$=<`Qf4<%$POuMz+lSK-PZ+V-1)A~&Q4B3oLTPwJ_!qpWfQe2b2j2VAGj_Zn+T^fw#sIDNX zU#{syTQS^ox@H|!sFR(p1Lkhps@n6TqQnO+_tk7Gxbp3*r@XyNw$w)?jKABu*g3bZ zH@Y$2J;p60?xil~ejGRK4zV={J;)#=aWW@K&(9@2MeWY~T<|r3j`PJM`4cBjFjC;W zC&(x0@7cO4qEvrOG)Gh;o8sbhZB6j220N|s*0D@ql#w~hRJ50vQsu-hHN{oWxuTxi zHuM!#KL7HHdm`_rK78hiS}IWtO@nY)`s-}=|z zH9q^|XKQRXIXc^2#5^+)Qw6CCK9}*iiqBWk*;9+WAi<%n8RjDgiBh6bnJylK_kwB> z?h};;>)C#+k7btr4Tg$fe83oADU5Dd-u3^&A?c;1`2hb-QBp05UGk~9i|jJq#bpM$ z28R;)x-om>82M1d)GjLG=G;kzb1k*_+G`!kNRr7(Vt6SM(#IX?<;j@fW~s~TkO?%I z2l>6G_+Vol*#Fva9hg}mtn&MmPe@YC5^El7jtUGXFcoQBovkz)1wo~k2yV+(f>r!g diIv1ZElHA&lA2Cao(%*Ph|=$~{|7UTc5QT@1C9Uy delta 3090 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 diff --git a/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs b/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs index a81e5d5..5c5d6ae 100644 --- a/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs +++ b/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs @@ -300,7 +300,6 @@ namespace 货架标准上位机.ViewModel } } - /// /// 物料修改操作 /// @@ -389,20 +388,27 @@ namespace 货架标准上位机.ViewModel } - public ICommand BtnPrintCommand { get => new DelegateCommand(BtnPrint); } public async void BtnPrint() { - PrintTender.PrintTag(new PrintClass() + var matBaseInfo = DataGridItemSource?.Where(t => t.IsSelected == true).FirstOrDefault(); + if (matBaseInfo == null) { - MatQty = "123", - MatCode = "123", - MatBatch = "123", - MatName = "123", - MatSn = "123", - MatSpec = "123", + Growl.Warning("请勾选数据!"); + } + var generateWindow = new MatBaseInoGenarateMatInfoView(matBaseInfo); + var result = generateWindow.ShowDialog(); - }); + //PrintTender.PrintTag(new PrintClass() + //{ + // MatQty = "123", + // MatCode = "123", + // MatBatch = "123", + // MatName = "123", + // MatSn = "123", + // MatSpec = "123", + + //}); } #endregion diff --git a/货架标准上位机/Views/MainWindows/MainWindow1.xaml b/货架标准上位机/Views/MainWindows/MainWindow1.xaml index 1c4f449..75293fd 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow1.xaml +++ b/货架标准上位机/Views/MainWindows/MainWindow1.xaml @@ -178,7 +178,7 @@ - 物料管理 + 物料维护 @@ -190,11 +190,11 @@ - 条码打印 + 物料明细 - + diff --git a/货架标准上位机/Views/MatBaseInoGenarateMatInfoView.xaml b/货架标准上位机/Views/MatBaseInoGenarateMatInfoView.xaml new file mode 100644 index 0000000..74f5992 --- /dev/null +++ b/货架标准上位机/Views/MatBaseInoGenarateMatInfoView.xaml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +