using System.Data;
using System.Dynamic;
using PadApplication.DB;
using PadApplication.Entites.DbModels;
using PadApplication.Entites.Dto;
using SqlSugar;
using DbType = System.Data.DbType;
namespace PadApplication.Services;
///
/// 物料条码管理服务类
/// 负责处理生产过程中的物料条码生成、更新、删除等操作
/// 主要功能包括:
/// 1. 生成物料条码并关联到工单
/// 2. 更新条码数量信息
/// 3. 删除条码记录
/// 4. 验证工单状态和数量限制
///
public class MesInvItemBarcodesManager : Repository
{
//当前类已经继承了 Repository 增、删、查、改的方法
private readonly WomdaaManager _womdaaManager = new();
// 物料分类数组,用于判断物料类型
private readonly string[] ItemSort = ["A1", "B1", "C1", "D1", "E1", "F2"];
private readonly MesQaItemsDetect02Manager qaItemsDetect02Manager = new();
// 工单状态数组
private readonly string[] statusArray = ["开工", "暂停", "完工"];
///
/// 添加物料条码
///
/// 工单机器信息DTO,包含工单号、打印数量等信息
/// 打印DTO列表,包含条码打印所需的所有信息
/// 当打印数量超过限制、工单不存在、工单未开工等情况下抛出异常
public List AddItemToBarcodes(OrderMachineDto query)
{
// 验证打印数量和总数是否有效
if (query.PrintQty is null or <= 0) return null;
if (query.Count is null or <= 0) return null;
// 幂等性检查 - 防重复提交
if (!string.IsNullOrWhiteSpace(query.RequestId))
{
// 检查是否已处理过此请求
var existsCount = Db.Queryable()
.Where(x => x.RequestId == query.RequestId)
.Count();
if (existsCount > 0)
{
throw new Exception("条码已生成,请勿重复提交");
}
}
// 执行工单验证
Execute(query);
// 获取工单打印信息
var query1 = new OrderMachineDto();
query1.OrderId = query.OrderId;
var womdaaPrintById = _womdaaManager.GetWomdaaPrintById(query1);
// 验证打印总数是否超过可打印总数
if (query.Count * query.PrintQty > womdaaPrintById.Bqty)
throw new Exception("打印总数超过可打印总数");
// 获取工单信息
var womdaa = Db.Queryable()
.Where(s => s.Daa001 == query.orderNo)
.First();
if (womdaa == null) throw new Exception("工单单号不存在");
// 验证工单状态是否允许打印
if (Array.IndexOf(statusArray, womdaa.Daa018) == -1)
throw new Exception("工单未开工,不能打印条码,请先开工!!!");
// 获取标准包装数
var mesItemsPackageQty = Db.Queryable()
.Where(a => a.ItemCode == womdaa.Daa002).First();
if (mesItemsPackageQty == null) throw new Exception("请维护标准包装数!");
// 检查工单状态
womdaa.State ??= "F";
if ("C".Equals(womdaa.State)) throw new Exception("工单已结案!");
// 获取首检信息
var findSjByOrderNo = qaItemsDetect02Manager.FindSJByOrderNo(query);
if (findSjByOrderNo == null) throw new Exception("没有查询到首检单");
//if (!"合格".Equals(findSjByOrderNo.FcheckResu) || !"特采使用".Equals(findSjByOrderNo.FcheckResu))
if ("不合格".Equals(findSjByOrderNo.FcheckResu))
throw new Exception("首检不合格,不允许报工");
// 计算已打印总数
var sum = Db.Queryable()
.Where(s => s.PbillNo == womdaa.Daa001)
.Sum(s => s.Quantity);
// 验证打印数量是否超出工单数量
var aa = query.Count * query.PrintQty;
if (aa + sum > womdaa.Daa008) throw new Exception("打印数量超出工单数量!");
// 初始化返回列表
var list = new List();
var barcodes = new List();
// 循环生成条码
for (var i = 0; i < query.Count; i++)
{
// 获取物料信息
var mesItems2 = Db.Queryable()
.Where(b => b.ItemNo == womdaa.Daa002 && b.AddressCode == "ALL")
.First();
if (mesItems2 == null) throw new Exception("物料信息不存在该物料编码,请维护!");
// 获取工序信息
var womcaa = Db.Queryable()
.Where(c => c.Caa001 == womdaa.Daa029).First();
womcaa.IsGy ??= 0;
// 验证是否是最后一道工序
if (womcaa.IsGy == 1)
{
var maxProc = Db.Queryable()
.Where(a => a.Daa029 == womdaa.Daa029)
.Select(a =>
SqlFunc.AggregateMax(SqlFunc.ToDecimal(a.ProcNum)))
.Single();
if (Convert.ToDecimal(womdaa.ProcNum) != maxProc)
throw new Exception("工序工单只有最后一道可以打印条码!");
}
// 设置批次号
var lotNo = "";
if (Array.IndexOf(ItemSort, mesItems2) > -1) lotNo = womdaa.LotNo;
// 设置条码类型
var typeCode = 25;
if (womdaa.Daa001.StartsWith("HSA") ||
womdaa.Daa001.StartsWith("HSB"))
typeCode = 16;
// 获取条码类型信息
var mesBarcodeType = Db.Queryable()
.Where(d =>
d.TypeCode == typeCode && d.Factory == "10000" &&
d.Company == "1000").First();
// 获取当前日期
var cIndate = DateTime.Now.ToString("yyyyMMdd");
// 获取部门信息
var sysDepartment = Db.Queryable()
.Where(e => e.Departmentcode == womdaa.DepartmentNo).First();
var Departmentname = womdaa.DepartmentNo;
if (sysDepartment != null)
Departmentname = sysDepartment.Departmentname;
var now = DateTime.Now.ToString("yyyy-MM-dd");
var print = query.PrintQty;
// 调用存储过程获取条码
var barcodeResult = SpGetBarcode2("1000", "1000", mesBarcodeType.Id,
womdaa.Daa002 + cIndate, womdaa.Daa002 + cIndate, 0);
string serial = barcodeResult.Value;
string poBarcodeComand = barcodeResult.Msg;
if (!string.IsNullOrEmpty(poBarcodeComand)) return null;
// 生成物料条码
var itemBarCode = womdaa.Daa002 + "-B" + cIndate + serial;
// 构建打印DTO
var printDto = new PrintDto
{
Out1 = Departmentname, //生产部门
Out2 = womdaa.Daa002, //物料编码
Out3 = womdaa.Daa003, //物料名称
Out4 = query.user, //报工人
Out5 = womdaa.Daa001.Substring(0, 3) == "XSG"
? womdaa.Daa029
: womdaa.LotNo, //批次号
Out6 = mesItems2.ItemName, //产品型号
Out7 = print + " " + womdaa.Daa005, //条码数量
Out8 = now, //日期
Out9 = "颜色:" + mesItems2.ColorName + ", 图号:" +
mesItems2.EngineeringNo
+ ", 材质:" + mesItems2.Material, //规格型号
Out10 = womcaa.Caa015, //销售单号
Out11 = womdaa.Daa001, //工单号
Out12 = itemBarCode //条码
};
// 验证条码是否已存在
var count = Db.Queryable()
.Where(f => f.ItemBarcode == itemBarCode).Count();
if (count != 0) return null;
// 分割用户信息
var strings = query.user.Split(':');
// 创建条码实体
var entity = new MesInvItemBarcodes
{
ItemBarcode = itemBarCode,
BillNo = womdaa.Daa001,
ItemNo = womdaa.Daa002,
Quantity = print,
EpFlag = 1,
TaskNo = womdaa.Daa021,
CreateBy = strings[0],
CreateDate = DateTime.Now,
LastupdateBy = strings[0],
LastupdateDate = DateTime.Now,
Mblnr = "",
Barcodestatus = 0,
Oldqty = print,
Unit = womdaa.Daa005,
LotDate = now,
Memo = "成品入库",
SuppNo = "",
ItemSname = womdaa.Daa003,
Factory = "1000",
Company = "1000",
TrLotno = cIndate,
UrgentFlag = 0,
WorkFlg = 1,
WorkLine = 1,
WorkNo = womdaa.Daa029,
ComeFlg = 1,
Hbdy = 0,
AddressCode = womdaa.AddressCode,
PbillNo = womdaa.Daa001,
LineNo = 1,
RequestId = query.RequestId // 保存请求唯一标识符,用于防重复提交
};
// 创建报工记录
var mesReporting = new MesReporting
{
CheckType = 0,
ItemNoCade = itemBarCode,
CreateBy = strings[0],
BgDate = DateTime.Now,
BgPerson = strings[0],
AddressCode = womdaa.AddressCode,
MachineNo = womdaa.MachineNo,
// BfQty = query.bf,
OkQty = print,
ItemNo = womdaa.Daa002,
BillNo = womdaa.Daa001
};
// 插入报工记录和条码记录
if (Db.Insertable(mesReporting)
.IgnoreColumns(true).ExecuteCommand() > 0)
{
Db.Insertable(entity).IgnoreColumns(true).ExecuteCommand();
UpdateAmount(mesReporting, query1);
}
list.Add(printDto);
barcodes.Add(entity);
}
// 更新条码数量
UpdateBarcodeAmount(barcodes);
return list;
}
///
/// 更新报工数量信息
///
/// 报工记录
/// 工单机器信息
public bool AddBFToBarcodes(OrderMachineDto query)
{
var womdaa = Db.Queryable()
.Where(s => s.Daa001 == query.orderNo)
.First();
if (womdaa == null) throw new Exception("工单单号不存在");
if (womdaa.Daa018 != "开工") throw new Exception("工单未开工");
var okQty = query.currentCjNum - query.initCjNum - query.bf;//良品数量
// 创建报工记录
var mesReporting = new MesReporting
{
CheckType = 1,
// ItemNoCade = itemBarCode,
// CreateBy = strings[0],
BgDate = DateTime.Now,
// BgPerson = strings[0],
AddressCode = womdaa.AddressCode,
MachineNo = womdaa.MachineNo,
BfQty = query.bf,//不良数量
OkQty = okQty,//良品数量
CsQty = query.initCjNum,//初始采集数
CjQty = query.currentCjNum,//报工时采集数
ItemNo = womdaa.Daa002,
BillNo = womdaa.Daa001,
BgPerson = query.staffNo // 新增:报工人编号
};
// 更新工单Daa011为原值加上本次良品数量,Daa012为原值加上本次不良品数量
Db.Updateable()
.SetColumns(x => x.Daa011 == (womdaa.Daa011 ?? 0) + (okQty ?? 0))
.SetColumns(x => x.Daa012 == (womdaa.Daa012 ?? 0) + (query.bf ?? 0))
.Where(x => x.Daa001 == womdaa.Daa001)
.ExecuteCommand();
// 判断是否全部完工,若是则写入实际完工日期
var womdaaAfter = Db.Queryable()
.Where(s => s.Daa001 == query.orderNo)
.First();
if (womdaaAfter != null && womdaaAfter.Daa011 >= womdaaAfter.Daa008)
{
var finishTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Db.Updateable()
.SetColumns(x => x.Daa017 == DateTime.Parse(finishTime))
.SetColumns(x => x.Daa018 == "完工")
.Where(x => x.Daa001 == womdaaAfter.Daa001)
.ExecuteCommand();
// 同步更新MES_ORDER_STA的END_TIME
Db.Updateable