using NewPdaSqlServer.DB;
using NewPdaSqlServer.Dto.service;
using NewPdaSqlServer.entity;
using NewPdaSqlServer.util;
using SqlSugar;
namespace NewPdaSqlServer.service.Warehouse;
///
/// 调拨出库管理类
/// 负责处理调拨出库相关的业务逻辑
///
public class TransferOutManager : Repository
{
///
/// 获取未完成的调拨出库单号列表
///
/// 未完成的调拨出库单号列表
public List GetTransferOutNoList()
{
// 先从数据库获取Transfer_Out_ETAIL表的数据
var transferOutDetails = Db.Queryable().ToList();
// 使用LINQ对获取的数据进行分组和筛选
// 筛选条件:申请数量(sq)不等于已扫数量(ys)的记录
var result = transferOutDetails
.GroupBy(x => x.Pid)
.Select(g => new
{
pid = g.Key,
sq = g.Sum(x => x.ShNum), // 申请数量合计
ys = g.Sum(x => x.YsNum) // 已扫数量合计
})
.Where(x => (x.sq ?? 0) != (x.ys ?? 0))
.Select(x => x.pid)
.ToList();
// 根据pid查询对应的出库单号
var billNos = Db.Queryable()
.Where(x => result.Contains(x.Guid))
.Select(x => x.BillNo)
.ToList();
return billNos;
}
///
/// 根据单据号获取待处理的调拨出库明细列表
///
/// 查询参数,包含单据号
/// 待处理的调拨出库明细列表
public List GetTransferOutDetailListByBillNo(
WarehouseQuery query)
{
var p_bill_no = query.billNo;
// 根据SQL查询条件获取待处理的出库明细
// 关联查询TransferOutDetail、TransferOut和MesItems三张表
// 筛选条件:未完成数量大于0且单据已审核
var result = Db.Queryable(
(b, a, s) => new JoinQueryInfos(
JoinType.Left, b.Pid == a.Guid,
JoinType.Left, b.ItemId == s.Id))
.Where((b, a, s) =>
(b.ShNum ?? 0) - (b.YsNum ?? 0) > 0 // 未完成数量大于0
&& a.BillNo == p_bill_no // 匹配单据号
&& a.Status == 1) // 单据已审核
.OrderBy((b, a, s) => s.ItemNo)
.Select((b, a, s) => new TransferOutDetail
{
ItemNo = s.ItemNo,
ItemModel = s.ItemModel,
ShNum = b.ShNum, // 申请数量
YsNum = b.YsNum, // 已扫数量
// 保留其他必要字段...
Pid = b.Pid,
ItemId = b.ItemId,
Guid = b.Guid
})
.ToList();
return result;
}
///
/// 扫描条码进行调拨出库处理
///
/// 包含单据号、用户名和条码信息的查询参数
/// 处理后的表单和待处理明细列表
public (WarehouseQuery form, List items)
ScanMoveBarcode(WarehouseQuery query)
{
var p_bill_no = query.billNo;
var c_user = query.userName;
var p_item_barcode = query.barcode;
var p_bill_type_id = 300; // 单据类型ID
var p_transaction_no = 301; // 交易编号
// 验证单据号
if (string.IsNullOrEmpty(p_bill_no))
{
throw new Exception("请选取单据号!");
}
// 查询出库单并验证状态
var transferOut = Db.Queryable()
.Where(x => x.BillNo == p_bill_no && x.Status == 1)
.First();
if (transferOut == null)
{
throw new Exception("未找到调拨申请单或者调拨申请单没审核");
}
// 查询条码库存信息并验证
var stock = Db.Queryable()
.Where(x => x.ItemBarcode == p_item_barcode
&& x.Quantity > 0
&& !string.IsNullOrEmpty(x.DepotsCode))
.First();
if (stock == null)
{
throw new Exception($"库存中无此条码,请核对!{p_item_barcode}");
}
// 验证仓库一致性
if (stock.DepotsCode != transferOut.InvCode)
{
throw new Exception(
$"条码库存仓库{stock.DepotsCode}和申请仓库不一致{transferOut.InvCode}");
}
// 查询物料信息
var item = Db.Queryable()
.Where(x => x.Id == stock.ItemId)
.First();
if (item == null)
{
throw new Exception("未找到物料");
}
// 查询调拨明细并验证
var detail = Db.Queryable()
.Where(x => x.ItemId == stock.ItemId && x.Pid == transferOut.Guid)
.First();
if (detail == null)
{
throw new Exception("未找到条码物料相应的调拨申请");
}
// 验证数量是否超出未扫数量
if ((detail.ShNum ?? 0) - (detail.YsNum ?? 0) < stock.Quantity)
{
throw new Exception("条码数量大于申请未扫数量,请拆分了再扫码");
}
// 使用事务处理数据更新
UseTransaction(db =>
{
// 查询现有移库记录
var existingMove = db.Queryable()
.Where(x => x.TaskNo == p_bill_no
&& x.TransactionNo == p_transaction_no
&& (x.Status ?? 0) == 0)
.First();
var commit = 0; // 记录更新操作次数
var c_id = Guid.Empty;
// 处理移库主表记录
if (existingMove != null)
{
// 更新现有记录的最后修改信息
commit += db.Updateable()
.SetColumns(s => s.LastupdateDate == DateTime.Now)
.SetColumns(s => s.LastupdateBy == c_user)
.Where(s => s.Guid == existingMove.Guid)
.ExecuteCommand();
c_id = existingMove.Guid;
}
else
{
// 查询相关仓库信息
var mesDepots = db.Queryable()
.Where(s => s.DepotCode == transferOut.FromCode)
.First();
var invMesDepots = db.Queryable()
.Where(s => s.DepotCode == transferOut.InvCode)
.First();
c_id = Guid.NewGuid();
// 创建新的移库记录
var newMove = new MesInvItemMoves
{
Guid = c_id,
BillNo = BillNo.GetBillNo("DBCKD"),
CreateBy = c_user,
CreateDate = DateTime.Now,
BillTypeId = p_bill_type_id,
TransactionNo = p_transaction_no,
InvDepotSectionsId = mesDepots.DepotId,
// InvDepotSectionsCode = transferOut.FromCode,
// FromDepotsCode = transferOut.InvCode,
FromDepotsId = invMesDepots.DepotId.ToString(),
TaskNo = p_bill_no
};
commit += db.Insertable(newMove).IgnoreColumns(true)
.ExecuteCommand();
}
// 写入老条码交易明细
var business = new MesInvBusiness2
{
Guid = Guid.NewGuid(),
Status = 1,
BillTypeId = p_bill_type_id,
TransactionCode = p_transaction_no.ToString(),
BusinessType = -1,
ItemBarcode = p_item_barcode,
ItemNo = item.ItemNo,
LotNo = stock.LotNo,
EpFlag = true,
Quantity = stock.Quantity,
FromInvDepotsCode = stock.DepotsCode,
FromInvDepotSectionsCode = stock.DepotSectionsCode,
ToInvDepotsCode = transferOut.FromCode,
ToInvDepotSectionsCode = stock.DepotSectionsCode,
CreateBy = c_user,
CreateDate = DateTime.Now,
LastupdateBy = c_user,
LastupdateDate = DateTime.Now,
Factory = stock.Factory,
Company = stock.Company,
TaskNo = stock.TaskNo,
BillNo = p_bill_no,
WorkNo = stock.WorkNo,
WorkLine = stock.WorkLine,
SuppNo = stock.SuppNo,
ItemId = stock.ItemId,
EbelnK3id = stock.EbelnK3id,
LineK3id = stock.LineK3id,
// RkDepot = transferOut.RkDepot,
// CkDepot = transferOut.CkDepot
};
commit += db.Insertable(business).IgnoreColumns(true)
.ExecuteCommand();
// 写入新条码交易明细
var moveDetail = new MesInvItemMovesCDetails
{
Guid = Guid.NewGuid(),
ItemMoveGuid = c_id,
ItemBarcode = p_item_barcode,
CItemCode = stock.CItemCode,
ItemNo = item.ItemNo,
LotNo = stock.LotNo,
Quantity = stock.Quantity,
EpFlag = stock.EpFlag,
CreateBy = c_user,
CreateDate = DateTime.Now,
LastupdateBy = c_user,
LastupdateDate = DateTime.Now,
// CustomerNo = stock.CustomerNo,
TaskNo = stock.TaskNo,
FromDepotsCode = stock.DepotsCode,
FromDepotSectionsCode = stock.DepotSectionsCode,
Factory = stock.Factory,
Company = stock.Company,
InvDepotsCode = transferOut.FromCode,
// InvDepotSectionsCode = p_sectioncode,
IqcStatus = stock.IqcStatus,
Fcar = stock.Fcar,
IndepDate = stock.IndepDate,
VisableSubmit = stock.VisableSubmit,
VisableSubmitBy = stock.VisableSubmitBy,
VisableSubmitDate = stock.VisableSubmitDate,
BoardStyle = stock.BoardStyle,
WorkNo = stock.WorkNo,
WorkLine = stock.WorkLine,
SuppNo = stock.SuppNo,
ItemId = (int)stock.ItemId,
EbelnK3id = stock.EbelnK3id,
LineK3id = stock.LineK3id,
// RkDepot = transferOut.RkDepot,
// CkDepot = transferOut.CkDepot
};
commit += db.Insertable(moveDetail).IgnoreColumns(true)
.ExecuteCommand();
// 更新或插入出库明细记录
var outItem = db.Queryable()
.Where(x => x.ItemOutId == c_id && x.ItemId == stock.ItemId)
.First();
if (outItem != null)
{
// 更新现有记录的数量
outItem.Quantity += stock.Quantity;
commit += db.Updateable()
.SetColumns(x => x.Quantity == outItem.Quantity)
.Where(x => x.Guid == outItem.Guid)
.ExecuteCommand();
}
else
{
// 插入新记录
var newOutItem = new MesInvItemOutItems
{
Guid = Guid.NewGuid(),
ItemOutId = c_id,
ItemId = stock.ItemId,
CreateBy = c_user,
CreateDate = DateTime.Now,
TaskNo = stock.TaskNo,
WorkNo = stock.WorkNo,
WorkLine = stock.WorkLine,
EbelnK3id = (int)stock.EbelnK3id,
LineK3id = (int)stock.LineK3id,
Quantity = stock.Quantity,
// Unit = stock.ItemUnit
};
commit += db.Insertable(newOutItem).IgnoreColumns(true)
.ExecuteCommand();
}
// 更新调拨申请已扫数量
detail = db.Queryable()
.Where(x => x.Guid == detail.Guid)
.First();
if (detail != null)
{
detail.YsNum = (detail.YsNum ?? 0) + stock.Quantity as int?;
commit += db.Updateable()
.SetColumns(x => x.YsNum == detail.YsNum)
.Where(x => x.Guid == detail.Guid)
.ExecuteCommand();
}
// 检查是否所有明细都已完成
var totals = db.Queryable((b, a) =>
new JoinQueryInfos(JoinType.Left, b.Pid == a.Guid))
.Where((b, a) => a.BillNo == p_bill_no)
.Select((b, a) => new {
ShNum = SqlFunc.AggregateSum(b.ShNum), // 申请总数量
YsNum = SqlFunc.AggregateSum(b.YsNum) // 已扫总数量
})
.First();
// 如果申请数量等于已扫数量,更新单据完成状态
if (totals.ShNum == totals.YsNum)
{
commit += db.Updateable()
.SetColumns(x => x.IsWc == 1)
.Where(x => x.BillNo == p_bill_no)
.ExecuteCommand();
}
// 更新返回参数
query.itemNo = item.ItemNo;
query.Num = stock.Quantity;
// 验证更新操作是否全部成功
if (commit < 4)
{
throw new Exception("更新失败");
}
return commit;
});
// 返回更新后的表单和待处理明细
return (query, GetTransferOutDetailListByBillNo(query));
}
}