using NewPdaSqlServer.DB; using NewPdaSqlServer.Dto.service; using NewPdaSqlServer.entity; using NewPdaSqlServer.util; using SqlSugar; namespace NewPdaSqlServer.service.Wom; public class MesWorkProdManager : Repository { //当前类已经继承了 Repository 增、删、查、改的方法 /// /// PDA扫描生产报工 /// /// /// 报工请求参数,包含: /// - StaffNo: 员工工号,必填 /// - ItemBarcode: 物料条码,必填 /// - UserNo: 操作用户账号,必填 /// /// /// 返回报工结果对象,包含: /// - TaskNo: 工单号 /// - ItemNo: 物料编号 /// - PlanQty: 计划数量 /// - ReportedQty: 已报工数量 /// - CurrentQty: 本次报工数量 /// - BarcodeQty: 条码数量 /// - ItemName: 物料名称 /// - ItemModel: 物料型号 /// - Message: 处理结果消息 /// /// /// - 当员工不存在时抛出异常 /// - 当条码不存在时抛出异常 /// - 当物料不存在时抛出异常 /// - 当条码重复扫描时抛出异常 /// - 当工单不存在时抛出异常 /// - 当报工数量小于等于0时抛出异常 /// - 当报工总数量超过计划数量时抛出异常 /// public ScanWorkResult ScanWorkAsync(ScanWorkRequest request) { // 1. 验证员工信息 var staff = Db.Queryable() .Where(x => x.StaffNo == request.StaffNo) .First(); if (staff == null) throw new Exception("请先选择人员"); // 2. 验证条码信息 var barcode = Db.Queryable() .Where(x => x.ItemBarcode == request.ItemBarcode) .First(); if (barcode == null) throw new Exception($"无此条码,请核对!{request.ItemBarcode}"); // 3. 验证物料信息 var item = Db.Queryable() .Where(x => x.Id == barcode.ItemId) .First(); if (item == null) throw new Exception($"无此物料,请核对!{request.ItemBarcode}"); // 4. 根据条码备注确定单据类型和交易号 var billTypeId = 900; // 默认单据类型 var transactionNo = 902; // 默认交易号 switch (barcode.Memo?.Trim() ?? "0") { case "丝印": transactionNo = 901; // 丝印工序 break; case "半成品": transactionNo = 902; // 半成品工序 break; case "包装": case "成品": transactionNo = 903; // 成品/包装工序 break; } // 5. 检查条码是否重复扫描 var exists = Db.Queryable( (a, b) => new JoinQueryInfos(JoinType.Inner, a.Id == b.MesWorkProdId)) .Where((a, b) => b.ItemBarcode == request.ItemBarcode && a.BillTypeId == billTypeId && a.TransactionNo == transactionNo) .Any(); if (exists) throw new Exception("条码重复扫描,请核对!"); // 6. 获取已报工数量 var reportedQty = Db.Queryable( (a, b) => new JoinQueryInfos(JoinType.Inner, a.BillNo == b.BillNo)) .Where((a, b) => a.BillTypeId == billTypeId && a.TransactionNo == transactionNo && a.TaskNo == barcode.BillNo) .Sum((a, b) => b.Quantity); // 7. 获取工单计划数量和型号 var workOrder = Db.Queryable() .Where(x => x.Daa001 == barcode.BillNo) .First(); if (workOrder == null) throw new Exception($"无工单明细,请核对!{request.ItemBarcode}"); var planQty = workOrder.Daa008; var itemModel = workOrder.Daa004; // 8. 使用事务处理报工数据 UseTransaction(db => { // 9. 处理有数量条码的自动报工 if (barcode.Quantity > 0) { var reportQty = barcode.Quantity; if (reportQty <= 0) throw new Exception( $"报工数量不能小于等于0,请核对!{request.ItemBarcode}"); var totalQty = (reportedQty ?? 0) + reportQty; if (totalQty > workOrder.Daa008) throw new Exception( $"本次报工数量:{reportQty} 大于剩余报工数量:{workOrder.Daa008 - reportedQty ?? 0},请核对!"); // 10. 更新条码状态 db.Updateable() .SetColumns(x => new MesInvItemBarcodes { WorkFlg = true //Quantity = reportQty }) .Where(x => x.Guid == barcode.Guid) .ExecuteCommand(); // 11. 获取或创建报工单 var workProd = db.Queryable() .Where(x => x.TaskNo == barcode.BillNo && x.CreateDate.Value.Date.ToString( "yyyy-MM-dd") == DateTime.Now.Date.ToString("yyyy-MM-dd") && x.BillTypeId == billTypeId && x.TransactionNo == transactionNo && x.ReportBy == request.StaffNo) .First(); var id = Guid.Empty; var billNo = ""; if (workProd == null) { id = Guid.NewGuid(); billNo = BillNo.GetBillNo("BG(报工)"); workProd = new MesWorkProd { Id = id, BillNo = billNo, LineNo = barcode.LineNo, Company = barcode.Company, Factory = barcode.Factory, CreateBy = request.UserNo, CreateDate = DateTime.Now, LastupdateBy = request.UserNo, LastupdateDate = DateTime.Now, BillTypeId = billTypeId, TransactionNo = transactionNo, TaskNo = barcode.BillNo, ReportBy = request.StaffNo, ReportDate = DateTime.Now }; db.Insertable(workProd).IgnoreColumns(true) .ExecuteCommand(); } else { id = workProd.Id; billNo = workProd.BillNo; } // 12. 插入报工明细 var detailId = Guid.NewGuid(); db.Insertable(new MesWorkProdCDetails { Id = detailId, MesWorkProdId = id, BillNo = billNo, ItemBarcode = request.ItemBarcode, Quantity = (int)reportQty, Company = barcode.Company, Factory = barcode.Factory, CreateBy = request.UserNo, CreateDate = DateTime.Now, LastupdateBy = request.UserNo, LastupdateDate = DateTime.Now, ItemNo = item.ItemNo, WorkLast = barcode.WorkLast, SilkPqty = barcode.SilkPqty, SilkId = barcode.SilkId, Silk = barcode.Silk, BgYg = request.StaffNo }).IgnoreColumns(true).ExecuteCommand(); // 13. 更新工单已报工数量 db.Updateable() .SetColumns(x => new Womdaa { Daa011 = (x.Daa011 ?? 0) + (int)barcode.Quantity }) .Where(x => x.Daa001 == barcode.BillNo) .ExecuteCommand(); // 14. 重新获取最新已报工数量 reportedQty = db.Queryable( (a, b) => new JoinQueryInfos(JoinType.Inner, a.BillNo == b.BillNo)) .Where((a, b) => a.BillTypeId == billTypeId && a.TransactionNo == transactionNo && a.TaskNo == barcode.BillNo) .Sum((a, b) => b.Quantity); } return 1; }); // 15. 返回处理结果 return new ScanWorkResult { TaskNo = barcode.BillNo, ItemNo = item.ItemNo, PlanQty = planQty ?? 0, ReportedQty = reportedQty ?? 0, CurrentQty = barcode.Quantity.Value, BarcodeQty = barcode.Quantity.Value, ItemName = item.ItemName, ItemModel = itemModel, Message = "扫码成功!" }; } /// /// PDA扫描生产报工 prc_rf_pda_scan_work_prod /// /// /// 报工请求参数,包含: /// - ItemBarcode: 物料条码,必填 /// - Quantity: 报工数量,必填且大于0 /// - UserNo: 操作用户账号,必填 /// /// 返回布尔值,true表示报工成功,false表示报工失败 /// /// - 当报工数量小于等于0时抛出异常 /// - 当条码不存在时抛出异常 /// - 当工单不存在时抛出异常 /// - 当报工总数量超过计划数量时抛出异常 /// public bool ScanWorkProdAsync(ScanWorkRequest request) { // 1. 验证报工数量是否大于0 if (request.Quantity <= 0) throw new Exception("报工数量不能小于等于 0,请核对!"); // 2. 查询条码信息,验证条码是否存在 var barcode = Db.Queryable() .Where(x => x.ItemBarcode == request.ItemBarcode) .First(); if (barcode == null) throw new Exception($"库存中无此条码,请核对!{request.ItemBarcode}"); // 3. 查询工单信息,验证工单是否存在 var womdaa = Db.Queryable() .Where(x => x.Daa001 == barcode.BillNo) .First(); if (womdaa == null) throw new Exception($"条码不是报工条码/无对应工单,请核对!{request.ItemBarcode}"); // 4. 根据条码备注确定单据类型和交易号 var billTypeId = 900; // 默认单据类型 var transactionNo = 902; // 默认交易号(半成品工序) switch (barcode.Memo?.Trim() ?? "0") { case "丝印": transactionNo = 901; // 丝印工序 break; case "半成品": transactionNo = 902; // 半成品工序 break; case "成品": case "包装": transactionNo = 903; // 成品/包装工序 break; } // 5. 汇总已扫条码数量,验证是否超出计划数量 var sumQty = Db.Queryable((a, b) => new JoinQueryInfos(JoinType.Inner, a.BillNo == b.BillNo)) .Where((a, b) => a.BillTypeId == billTypeId && a.TransactionNo == transactionNo && b.SilkId == barcode.SilkId && a.TaskNo == barcode.BillNo) .Sum((a, b) => b.Quantity); sumQty = (sumQty ?? 0) + (int)request.Quantity; if (sumQty > womdaa.Daa008) throw new Exception( $"本次报工数量:{request.Quantity} 大于剩余报工数量:{womdaa.Daa008 - (sumQty - request.Quantity)},请核对!"); // 6. 开启事务处理报工数据 return UseTransaction(db => { // 6.1 更新条码信息,设置已报工标记和数量 db.Updateable() .SetColumns(x => x.WorkFlg == true) .SetColumns(x => x.Quantity == request.Quantity) .Where(x => x.Guid == barcode.Guid) .ExecuteCommand(); // 6.2 获取或创建报工单 var workProd = db.Queryable() .Where(x => x.TaskNo == barcode.BillNo && x.CreateDate.Value.Date.ToString("yyyy-MM-dd") == DateTime.Now.Date.ToString("yyyy-MM-dd") && x.BillTypeId == billTypeId && x.TransactionNo == transactionNo && x.Status == 0) .First(); // 6.3 如果报工单不存在则创建新的报工单 if (workProd == null) { var billNo = BillNo.GetBillNo("BG(报工编号)"); workProd = new MesWorkProd { Id = Guid.NewGuid(), BillNo = billNo, LineNo = barcode.LineNo, Company = barcode.Company, Factory = barcode.Factory, CreateBy = request.UserNo, CreateDate = DateTime.Now, LastupdateBy = request.UserNo, LastupdateDate = DateTime.Now, PbillNo = barcode.BillNo, BillTypeId = billTypeId, TransactionNo = transactionNo, TaskNo = barcode.BillNo }; db.Insertable(workProd).IgnoreColumns(true).ExecuteCommand(); } // 6.4 插入报工明细记录 var detail = new MesWorkProdCDetails { Id = Guid.NewGuid(), BillNo = workProd.BillNo, ItemBarcode = request.ItemBarcode, Quantity = (int)request.Quantity, Company = barcode.Company, Factory = barcode.Factory, CreateBy = request.UserNo, CreateDate = DateTime.Now, LastupdateBy = request.UserNo, LastupdateDate = DateTime.Now, ItemNo = barcode.ItemNo, PbillNo = barcode.BillNo, WorkLast = barcode.WorkLast, SilkPqty = barcode.SilkPqty, SilkId = barcode.SilkId, Silk = barcode.Silk }; db.Insertable(detail).IgnoreColumns(true).ExecuteCommand(); return 1; }) > 0; } }