南骏 池
2025-06-20 7b84eb64d11b12b6fb41ae7f7085452512ad5d3f
service/Wom/MesWorkProdManager.cs
@@ -11,53 +11,80 @@
    //当前类已经继承了 Repository 增、删、查、改的方法
    /// <summary>
    /// PDA扫描生产报工
    ///     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}");
        // 确定单据类型
        int billTypeId = 900;
        int transactionNo = 902;
        // 4. 根据条码备注确定单据类型和交易号
        var billTypeId = 900; // 默认单据类型
        var transactionNo = 902; // 默认交易号
        switch (barcode.Memo?.Trim() ?? "0")
        {
            case "丝印":
                transactionNo = 901;
                transactionNo = 901; // 丝印工序
                break;
            case "半成品":
                transactionNo = 902;
                transactionNo = 902; // 半成品工序
                break;
            case "包装":
            case "成品":
                transactionNo = 903;
                transactionNo = 903; // 成品/包装工序
                break;
        }
        // 检查条码是否重复扫描
        // 5. 检查条码是否重复扫描
        var exists = Db.Queryable<MesWorkProd, MesWorkProdCDetails>(
                (a, b) =>
                    new JoinQueryInfos(JoinType.Inner,
                        a.BillNo == b.BillNo))
                        a.Id == b.MesWorkProdId))
            .Where((a, b) => b.ItemBarcode == request.ItemBarcode
                             && a.BillTypeId == billTypeId
                             && a.TransactionNo == transactionNo)
@@ -66,7 +93,7 @@
        if (exists)
            throw new Exception("条码重复扫描,请核对!");
        // 获取已报工数量
        // 6. 获取已报工数量
        var reportedQty = Db.Queryable<MesWorkProd, MesWorkProdCDetails>(
                (a, b) =>
                    new JoinQueryInfos(JoinType.Inner,
@@ -76,7 +103,7 @@
                             && a.TaskNo == barcode.BillNo)
            .Sum((a, b) => b.Quantity);
        // 获取工单计划数量和型号
        // 7. 获取工单计划数量和型号
        var workOrder = Db.Queryable<Womdaa>()
            .Where(x => x.Daa001 == barcode.BillNo)
            .First();
@@ -86,9 +113,10 @@
        var planQty = workOrder.Daa008;
        var itemModel = workOrder.Daa004;
        // 8. 使用事务处理报工数据
        UseTransaction(db =>
        {
            // 有数量条码自动报工
            // 9. 处理有数量条码的自动报工
            if (barcode.Quantity > 0)
            {
                var reportQty = barcode.Quantity;
@@ -101,17 +129,17 @@
                    throw new Exception(
                        $"本次报工数量:{reportQty} 大于剩余报工数量:{workOrder.Daa008 - reportedQty ?? 0},请核对!");
                // 更新条码状态
                // 10. 更新条码状态
                db.Updateable<MesInvItemBarcodes>()
                    .SetColumns(x => new MesInvItemBarcodes
                    {
                        WorkFlg = true,
                        Quantity = reportQty
                        WorkFlg = true
                        //Quantity = reportQty
                    })
                    .Where(x => x.Guid == barcode.Guid)
                    .ExecuteCommandAsync();
                    .ExecuteCommand();
                // 获取或创建报工单
                // 11. 获取或创建报工单
                var workProd = db.Queryable<MesWorkProd>()
                    .Where(x => x.TaskNo == barcode.BillNo
                                && x.CreateDate.Value.Date.ToString(
@@ -119,13 +147,15 @@
                                DateTime.Now.Date.ToString("yyyy-MM-dd")
                                && x.BillTypeId == billTypeId
                                && x.TransactionNo == transactionNo
                                && x.Status == 0)
                                && x.ReportBy == request.StaffNo)
                    .First();
                var id = Guid.Empty;
                var billNo = "";
                if (workProd == null)
                {
                    var id = Guid.NewGuid();
                    var billNo = BillNo.GetBillNo("MES_WORK");
                    id = Guid.NewGuid();
                    billNo = BillNo.GetBillNo("BG(报工)");
                    workProd = new MesWorkProd
                    {
@@ -140,19 +170,27 @@
                        LastupdateDate = DateTime.Now,
                        BillTypeId = billTypeId,
                        TransactionNo = transactionNo,
                        TaskNo = barcode.BillNo
                        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,
                    BillNo = workProd.BillNo,
                    MesWorkProdId = id,
                    BillNo = billNo,
                    ItemBarcode = request.ItemBarcode,
                    Quantity = (int)reportQty,
                    Company = barcode.Company,
@@ -166,18 +204,19 @@
                    SilkPqty = barcode.SilkPqty,
                    SilkId = barcode.SilkId,
                    Silk = barcode.Silk,
                    BgYg = staff.Id
                    BgYg = request.StaffNo
                }).IgnoreColumns(true).ExecuteCommand();
                // 更新工单已报工数量
                // 13. 更新工单已报工数量
                db.Updateable<Womdaa>()
                    .SetColumns(x =>
                        x.Daa011 == (x.Daa011 ?? 0) + (int)barcode.Quantity
                    )
                    .Where(x => x.Daa001 == barcode.BillNo)
                    .ExecuteCommandAsync();
                        .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,
@@ -191,9 +230,10 @@
            return 1;
        });
        // 15. 返回处理结果
        return new ScanWorkResult
        {
            TaskNo = barcode.TaskNo,
            TaskNo = barcode.BillNo,
            ItemNo = item.ItemNo,
            PlanQty = planQty ?? 0,
            ReportedQty = reportedQty ?? 0,
@@ -207,45 +247,59 @@
    /// <summary>
    /// PDA扫描生产报工  prc_rf_pda_scan_work_prod
    ///     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}");
        // 确定单据类型
        int billTypeId = 900;
        int transactionNo = 902;
        // 4. 根据条码备注确定单据类型和交易号
        var billTypeId = 900; // 默认单据类型
        var transactionNo = 902; // 默认交易号(半成品工序)
        switch (barcode.Memo?.Trim() ?? "0")
        {
            case "丝印":
                transactionNo = 901;
                transactionNo = 901; // 丝印工序
                break;
            case "半成品":
                transactionNo = 902;
                transactionNo = 902; // 半成品工序
                break;
            case "成品":
            case "包装":
                transactionNo = 903;
                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
@@ -260,16 +314,17 @@
            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") ==
@@ -279,12 +334,13 @@
                            && x.Status == 0)
                .First();
            // 6.3 如果报工单不存在则创建新的报工单
            if (workProd == null)
            {
                var billNo = BillNo.GetBillNo("MES_WORK");
                var billNo = BillNo.GetBillNo("BG(报工编号)");
                workProd = new MesWorkProd
                {
                    Id = Guid.NewGuid(),
                    Id = Guid.NewGuid(),
                    BillNo = billNo,
                    LineNo = barcode.LineNo,
                    Company = barcode.Company,
@@ -293,7 +349,7 @@
                    CreateDate = DateTime.Now,
                    LastupdateBy = request.UserNo,
                    LastupdateDate = DateTime.Now,
                    PbillNo = barcode.BillNo, // Added PbillNo field
                    PbillNo = barcode.BillNo,
                    BillTypeId = billTypeId,
                    TransactionNo = transactionNo,
                    TaskNo = barcode.BillNo
@@ -302,10 +358,10 @@
                db.Insertable(workProd).IgnoreColumns(true).ExecuteCommand();
            }
            // 插入报工明细
            // 6.4 插入报工明细记录
            var detail = new MesWorkProdCDetails
            {
                Id = Guid.NewGuid(),
                Id = Guid.NewGuid(),
                BillNo = workProd.BillNo,
                ItemBarcode = request.ItemBarcode,
                Quantity = (int)request.Quantity,
@@ -316,7 +372,7 @@
                LastupdateBy = request.UserNo,
                LastupdateDate = DateTime.Now,
                ItemNo = barcode.ItemNo,
                PbillNo = barcode.BillNo, // Added PbillNo from barcode
                PbillNo = barcode.BillNo,
                WorkLast = barcode.WorkLast,
                SilkPqty = barcode.SilkPqty,
                SilkId = barcode.SilkId,