using MES.Service.DB;
using MES.Service.Dto.webApi;
using MES.Service.Modes;
using MES.Service.util;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MES.Service.service;
///
/// 收料单数据管理类(处理ERP收料单数据同步到MES收料单表)
/// 关联主表:MesInvItemArn,明细表:MesInvItemArnDetail
/// 关联ERP DTO:ErpSltz(聚合类)、ErpSltza(ERP主表)、ErpSltzBList(ERP明细)
///
public class MesInvItemArnManager : Repository
{
///
/// 批量保存收料单(主表+明细)- 事务保证批量操作一致性
///
/// ERP收料单列表(含主表+明细)
/// 全部成功返回true,否则false
public bool SaveList(List erpSltzList)
{
if (erpSltzList == null || !erpSltzList.Any())
throw new ArgumentNullException(nameof(erpSltzList), "待保存的收料单列表不能为空");
// 修复:用事务包裹批量操作,确保数据一致性
return UseTransaction(db =>
{
foreach (var erpSltz in erpSltzList)
{
// 修复:调用事务内的Save方法,传入db实例
if (!Save(db, erpSltz))
{
return 0; // 单条失败,事务回滚
}
}
return 1; // 全部成功
}) > 0;
}
///
/// 单条保存收料单(主表+明细)- 事务内调用(修正访问修饰符,确保事务内可用)
///
/// 事务内的SqlSugar实例
/// ERP收料单(含主表+明细)
/// 单条处理成功返回true
private bool Save(SqlSugarScope db, ErpSltz erpSltz)
{
// 1. 参数校验
if (erpSltz == null)
throw new ArgumentNullException(nameof(erpSltz), "收料单数据不能为空");
if (erpSltz.ErpSltza == null)
throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "收料单主表数据不能为空");
// 2. 提取ERP主表和明细数据
var erpMain = erpSltz.ErpSltza;
var erpDetails = erpSltz.ErpSltzBList ?? new List();
// 3. 修复:用事务内的db查询,确保数据一致性
Guid mainId = GetOrCreateMainId(db, erpMain);
// 4. 映射ERP数据到MES实体(修复字段注释,补充关键属性)
var mesMain = MapErpSltzaToMesInvItemArn(erpMain, mainId);
var mesDetails = MapErpSltzBListToMesInvItemArnDetail(erpDetails, mainId);
// 5. 根据操作类型处理数据
switch (erpMain.TYPE?.Trim())
{
case "1": // 新增
case "2": // 更新
return HandleSaveOrUpdate(db, mesMain, mesDetails, mainId);
case "3": // 删除
return HandleDelete(db, mesMain, mesDetails, mainId);
default:
throw new NotImplementedException($"未实现的收料单操作类型:{erpMain.TYPE}(支持类型:1-新增,2-更新,3-删除)");
}
}
///
/// 单条保存收料单(主表+明细)- 对外公开接口(供控制器调用)
///
/// ERP收料单数据(含主表+明细)
/// 保存成功返回true
public bool Save(ErpSltz erpSltz)
{
if (erpSltz == null)
throw new ArgumentNullException(nameof(erpSltz), "收料单数据不能为空");
if (erpSltz.ErpSltza == null)
throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "收料单主表数据不能为空");
// 事务内处理主从表保存
return UseTransaction(db =>
{
return Save(db, erpSltz) ? 1 : 0;
}) > 0;
}
///
/// 提前获取或生成MES主表ID(修复:用事务内db查询)
///
private Guid GetOrCreateMainId(SqlSugarScope db, ErpSltza erpMain)
{
if (string.IsNullOrEmpty(erpMain.billNo))
throw new ArgumentException("ERP收料单单据号不能为空,无法确定主表唯一性", nameof(erpMain.billNo));
// 修复:用事务内的db查询,而非Context
var existingMain = db.Queryable()
.Where(m => m.BillNo == erpMain.billNo)
.First();
return existingMain != null
? existingMain.Id
: Guid.NewGuid();
}
///
/// 处理收料单新增/更新(主表+明细)
///
private bool HandleSaveOrUpdate(SqlSugarScope db, MesInvItemArn mesMain, List mesDetails, Guid mainId)
{
mesMain.Id = mainId;
bool isMainExist = db.Queryable().Where(m => m.Id == mainId).Any();
int mainOperateResult;
if (isMainExist)
{
mainOperateResult = db.Updateable(mesMain)
.IgnoreColumns(m => new { m.CreateDate })
.Where(m => m.Id == mainId)
.ExecuteCommand();
}
else
{
mesMain.CreateDate = DateTime.Now;
mainOperateResult = db.Insertable(mesMain).ExecuteCommand();
}
// 处理明细
int deleteOldDetailResult = db.Deleteable()
.Where(d => d.Mid == mainId)
.ExecuteCommand();
int insertNewDetailResult = mesDetails.Count > 0
? db.Insertable(mesDetails).ExecuteCommand()
: 1;
return mainOperateResult > 0 && (deleteOldDetailResult >= 0 && insertNewDetailResult > 0);
}
///
/// 处理收料单删除(主表+明细)
///
private bool HandleDelete(SqlSugarScope db, MesInvItemArn mesMain, List mesDetails, Guid mainId)
{
db.Deleteable().Where(d => d.Mid == mainId).ExecuteCommand();
int mainDeleteResult = db.Deleteable().Where(m => m.Id == mainId).ExecuteCommand();
return mainDeleteResult >= 0;
}
///
/// ERP主表映射到MES主表(修复:取消关键字段注释,修正FType逻辑)
///
private MesInvItemArn MapErpSltzaToMesInvItemArn(ErpSltza erpMain, Guid mainId)
{
// 单据日期转换
DateTime.TryParse(erpMain.FDate, out DateTime parsedDate);
// 是否SRM转换(0-否,1-是)
int.TryParse(erpMain.F_ZJXF_sfgx, out int isSrm);
// 供应商ID转换(字符串直接赋值,匹配MES字段类型)
string suppId = string.IsNullOrEmpty(erpMain.SupplierId) ? null : erpMain.SupplierId.Trim();
// 修复:“是否委外”逻辑(假设ERP的fType是“1”=是,“0”=否,或bool字符串)
bool isOutsourcing = false;
if (!string.IsNullOrEmpty(erpMain.fType))
{
isOutsourcing = erpMain.fType.Trim() == "1" || erpMain.fType.Trim().Equals("true", StringComparison.OrdinalIgnoreCase);
}
return new MesInvItemArn
{
// 修复:取消关键字段注释,补充赋值
Id = mainId,
BillNo = erpMain.billNo?.Trim() ?? throw new ArgumentException("收料单单据号不能为空"),
SuppId = suppId,
CreateDate = parsedDate == DateTime.MinValue ? null : (DateTime?)parsedDate,
Remark = erpMain.Remark?.Trim(),
IsSrm = isSrm,
EbelnK3id = erpMain.erpId?.Trim(), // ERP主表ID(对应ebeln_k3id)
CreateBy = erpMain.createBy?.Trim() ?? "SYSTEM", // 默认为系统
FType = isOutsourcing, // 修复:正确的是否委外逻辑
ReceiveOrgId = erpMain.ReceiveOrgId?.Trim(),
// LastUpdateUser = erpMain.FCreatorId?.Trim() ?? "SYSTEM",
// LastUpdateTime = DateTime.Now,
// IsOut = false, // 初始未出库
// Status = false // 初始未审核
};
}
///
/// ERP明细映射到MES明细(修复:取消关键字段注释,修正EbelnK3id转换)
///
private List MapErpSltzBListToMesInvItemArnDetail(List erpDetails, Guid mainId)
{
return erpDetails.Select(erpDetail =>
{
// 数值类型安全转换
int.TryParse(erpDetail.LineNo, out int lineNo); // 明细主键
int.TryParse(erpDetail.ProductCode, out int itemId); // 物料编码
decimal.TryParse(erpDetail.PurchaseQty, out decimal purchaseQty); // 采购订单数量
decimal.TryParse(erpDetail.DeliveryQty, out decimal deliveryQty); // 本次应收数量
decimal.TryParse(erpDetail.IncludeQty, out decimal includeQty); // 本次实收数量
// 修复:用采购单ID字段(ebeln_k3id)转int,而非源单单号
int.TryParse(erpDetail.FSrcBillNo, out int ebelnK3id);
int.TryParse(erpDetail.FSrcBillLine, out int lineK3id); // 采购单行ID
bool.TryParse(erpDetail.urgentFlag, out bool urgentFlag); // 急料标识
return new MesInvItemArnDetail
{
// 修复:取消关键字段注释,补充赋值
// LineNo = lineNo, // 明细主键(必须赋值)
Mid = mainId, // 外键(关联主表ID,必须赋值)
Ebeln = erpDetail.FBillNo?.Trim(), // 采购单号
ItemId = itemId,
EbelnQty = purchaseQty,
SubQty = deliveryQty,
Quantity = includeQty,
// PurchaseUnit = erpDetail.PurchaseUnit?.Trim(), // 采购单位(补充赋值)
// InventoryUnit = erpDetail.InventoryUnit?.Trim(), // 库存单位(补充赋值)
Memo = erpDetail.Remark?.Trim(),
EbelnK3id = ebelnK3id, // 修复:正确的采购单ID转换
LineK3id = lineK3id,
// SalesOrderId = erpDetail.SalesOrderId?.Trim(), // 销售订单号(补充赋值)
// FMtoNo = erpDetail.FMtoNo?.Trim(), // 计划跟踪号(补充赋值)
// FLot = erpDetail.FLot?.Trim(), // 批号(补充赋值)
UrgentFlag = urgentFlag
//FStockId = erpDetail.DepotId?.Trim() // 收货仓库编号
};
}).ToList();
}
///
/// 按单据号查询MES收料单(主表+明细)
///
public (MesInvItemArn main, List details) GetByBillNo(string billNo)
{
if (string.IsNullOrEmpty(billNo))
throw new ArgumentNullException(nameof(billNo), "查询条件单据号不能为空");
var main = Context.Queryable()
.Where(m => m.BillNo == billNo)
.First();
var details = main != null
? Context.Queryable()
.Where(d => d.Mid == main.Id)
.ToList()
: new List();
return (main, details);
}
}