using NewPdaSqlServer.DB;
|
using NewPdaSqlServer.Dto.service;
|
using NewPdaSqlServer.entity;
|
using NewPdaSqlServer.util;
|
using SqlSugar;
|
|
namespace NewPdaSqlServer.service.Wom;
|
|
public class MesWorkProdManager : Repository<MesWorkProd>
|
{
|
//当前类已经继承了 Repository 增、删、查、改的方法
|
|
/// <summary>
|
/// PDA扫描生产报工
|
/// </summary>
|
/// <param name="request">
|
/// 报工请求参数,包含:
|
/// - StaffNo: 员工工号,必填
|
/// - ItemBarcode: 物料条码,必填
|
/// - UserNo: 操作用户账号,必填
|
/// </param>
|
/// <returns>
|
/// 返回报工结果对象,包含:
|
/// - TaskNo: 工单号
|
/// - ItemNo: 物料编号
|
/// - PlanQty: 计划数量
|
/// - ReportedQty: 已报工数量
|
/// - CurrentQty: 本次报工数量
|
/// - BarcodeQty: 条码数量
|
/// - ItemName: 物料名称
|
/// - ItemModel: 物料型号
|
/// - Message: 处理结果消息
|
/// </returns>
|
/// <exception cref="Exception">
|
/// - 当员工不存在时抛出异常
|
/// - 当条码不存在时抛出异常
|
/// - 当物料不存在时抛出异常
|
/// - 当条码重复扫描时抛出异常
|
/// - 当工单不存在时抛出异常
|
/// - 当报工数量小于等于0时抛出异常
|
/// - 当报工总数量超过计划数量时抛出异常
|
/// </exception>
|
public ScanWorkResult ScanWorkAsync(ScanWorkRequest request)
|
{
|
// 1. 验证员工信息
|
var staff = Db.Queryable<MesStaff>()
|
.Where(x => x.StaffNo == request.StaffNo)
|
.First();
|
if (staff == null)
|
throw new Exception("请先选择人员");
|
|
// 2. 验证条码信息
|
var barcode = Db.Queryable<MesInvItemBarcodes>()
|
.Where(x => x.ItemBarcode == request.ItemBarcode)
|
.First();
|
if (barcode == null)
|
throw new Exception($"无此条码,请核对!{request.ItemBarcode}");
|
|
// 3. 验证物料信息
|
var item = Db.Queryable<MesItems>()
|
.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<MesWorkProd, MesWorkProdCDetails>(
|
(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<MesWorkProd, MesWorkProdCDetails>(
|
(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<Womdaa>()
|
.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<MesInvItemBarcodes>()
|
.SetColumns(x => new MesInvItemBarcodes
|
{
|
WorkFlg = true
|
//Quantity = reportQty
|
})
|
.Where(x => x.Guid == barcode.Guid)
|
.ExecuteCommand();
|
|
// 11. 获取或创建报工单
|
var workProd = db.Queryable<MesWorkProd>()
|
.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<Womdaa>()
|
.SetColumns(x => new Womdaa
|
{
|
Daa011 = (x.Daa011 ?? 0) + (int)barcode.Quantity
|
})
|
.Where(x => x.Daa001 == barcode.BillNo)
|
.ExecuteCommand();
|
|
// 14. 重新获取最新已报工数量
|
reportedQty = db.Queryable<MesWorkProd, MesWorkProdCDetails>(
|
(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 = "扫码成功!"
|
};
|
}
|
|
|
/// <summary>
|
/// PDA扫描生产报工 prc_rf_pda_scan_work_prod
|
/// </summary>
|
/// <param name="request">
|
/// 报工请求参数,包含:
|
/// - ItemBarcode: 物料条码,必填
|
/// - Quantity: 报工数量,必填且大于0
|
/// - UserNo: 操作用户账号,必填
|
/// </param>
|
/// <returns>返回布尔值,true表示报工成功,false表示报工失败</returns>
|
/// <exception cref="Exception">
|
/// - 当报工数量小于等于0时抛出异常
|
/// - 当条码不存在时抛出异常
|
/// - 当工单不存在时抛出异常
|
/// - 当报工总数量超过计划数量时抛出异常
|
/// </exception>
|
public bool ScanWorkProdAsync(ScanWorkRequest request)
|
{
|
// 1. 验证报工数量是否大于0
|
if (request.Quantity <= 0)
|
throw new Exception("报工数量不能小于等于 0,请核对!");
|
|
// 2. 查询条码信息,验证条码是否存在
|
var barcode = Db.Queryable<MesInvItemBarcodes>()
|
.Where(x => x.ItemBarcode == request.ItemBarcode)
|
.First();
|
if (barcode == null)
|
throw new Exception($"库存中无此条码,请核对!{request.ItemBarcode}");
|
|
// 3. 查询工单信息,验证工单是否存在
|
var womdaa = Db.Queryable<Womdaa>()
|
.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<MesWorkProd, MesWorkProdCDetails>((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<MesInvItemBarcodes>()
|
.SetColumns(x => x.WorkFlg == true)
|
.SetColumns(x => x.Quantity == request.Quantity)
|
.Where(x => x.Guid == barcode.Guid)
|
.ExecuteCommand();
|
|
// 6.2 获取或创建报工单
|
var workProd = db.Queryable<MesWorkProd>()
|
.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;
|
}
|
}
|