Files
wcs/WCS.BLL/Services/Service/OutstoreService.cs
2024-07-31 15:25:42 +08:00

1515 lines
66 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Data.SqlClient;
using SqlSugar;
using WCS.BLL.Config;
using WCS.BLL.DbModels;
using WCS.BLL.Manager;
using WCS.BLL.Services.IService;
using WCS.BLL.Tool;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
using WCS.Model;
using WCS.Model.ApiModel.InOutRecord;
using WCS.Model.ApiModel.MatInventoryDetail;
using WCS.Model.ApiModel.OutStore;
namespace WCS.BLL.Services.Service
{
public class OutstoreService : IOutstoreService
{
public OutstoreService()
{
}
public async Task<ResponseCommon<List<MatInventorySummaryModel>>> importMat(List<OutImportMatModel> list)
{
//数据校验
if (list == null || list.Count == 0)
{
return new ResponseCommon<List<MatInventorySummaryModel>>()
{
Code = 201,
Message = "导入失败:导入文件中没有内容!"
};
}
//需求数量
var errorCount = list.Where(t => t. <= 0).ToList();
if (errorCount != null && errorCount.Count > 0)
{
return new ResponseCommon<List<MatInventorySummaryModel>>()
{
Code = 201,
Message = "导入失败需求数量需要大于0"
};
}
//每一个物料进行搜索库存
var returnList = new List<MatInventorySummaryModel>();
foreach (var item in list)
{
var inventoryCount = await DbHelp.db.Queryable<InventoryDetail>()
.Where(t => t.MatCode == item.)
.Where(t => t.MatBatch == item.)
.Where(t => t.IsLocked == false)
.SumAsync(t => t.MatQty);
var info = inventoryCount < item. ? "库存数量小于需求数量" : string.Empty;
returnList.Add(new MatInventorySummaryModel()
{
MatCode = item.,
MatName = item.,
MatBatch = item.,
NeedQty = item.,
TotalQty = inventoryCount,
Info = info
});
}
return new ResponseCommon<List<MatInventorySummaryModel>>()
{
Code = 200,
Data = returnList
};
}
public async Task<ResponseBase> SysOutOrderByMatCode(SysOutOrderByMatCodeRequest request)
{
//参数合法性校验
if (request.ItemList == null || request.ItemList.Count == 0)
{
return new ResponseBase()
{
Code = 201,
Message = "出库单据同步失败:缺少需要出库的物料类型!"
};
}
//补齐货架类型名称
if (string.IsNullOrEmpty(request.ShelfTypeName))
{
var shelfType = await DbHelp.db.Queryable<ShelfTypeInfo>()
.Where(t => t.Id == request.ShelfTypeId)
.FirstAsync();
if (shelfType == null)
{
return new ResponseBase()
{
Code = 201,
Message = $"出库单据同步失败缺少必要参数ShelfTypeId"
};
}
else
request.ShelfTypeName = shelfType.ShelfTypeName;
}
//保存数据
await DbHelp.db.BeginTranAsync();
try
{
var order = new OutOrder()
{
OrderNumber = request.OrderNumber,
OrderSource = request.OrderSource,
OrderType = request.OrderType,
ShelfTypeId = request.ShelfTypeId,
ShelfTypeName = request.ShelfTypeName,
SyncType = SyncTypeEnum.ByMatCode,
GroupName = LocalFile.Config.GroupName,
CreateUser = request.UserName,
};
order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync();
request.ItemList.ForEach(async item =>
{
var orderDetail = new OutOrderDetail()
{
OrderId = order.Id,
OrderNumber = order.OrderNumber,
MatCode = item.MatCode,
MatName = item.MatName,
MatBatch = item.MatBatch,
ReqQty = item.ReqQty,
OutQty = 0,
CreateUser = request.UserName
};
await DbHelp.db.Insertable(orderDetail).ExecuteCommandAsync();
});
await DbHelp.db.CommitTranAsync();
return new ResponseCommon()
{
Code = 200,
Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}",
Data = request.OrderNumber
}; ;
}
catch (Exception ex)
{
await DbHelp.db.RollbackTranAsync();
Console.WriteLine(ex.Message);
return new ResponseBase()
{
Code = 200,
Message = $"出库单据同步失败:{ex.Message}"
};
}
}
public async Task<ResponseBase> SysOutOrderByMatSn(SysOutOrderByMatSnRequest request)
{
//参数合法性校验
if (request.SnList == null || request.SnList.Count == 0)
{
return new ResponseBase()
{
Code = 201,
Message = "出库单据同步失败:缺少物料明细!"
};
}
//标准版逻辑-库存有无校验 & 库存已锁校验
if (!LocalFile.Config.IsMx)
{
try
{
await DbHelp.db.BeginTranAsync();
var inventoryDetails = await DbHelp.db.Queryable<InventoryDetail>()
.Where(t => request.SnList.Contains(t.MatSN))
.TranLock(DbLockType.Wait)
.ToListAsync();
if (inventoryDetails.Count < request.SnList.Count)//库存的物料少于需求的物料数量
{
var existsSns = inventoryDetails.Select(t => t.MatSN).ToList();
request.SnList.RemoveAll(t => existsSns.Contains(t));
await DbHelp.db.RollbackTranAsync();
//返回提示哪些物料库存不存在
return new ResponseCommon()
{
Code = 201,
Message = "出库单据同步失败:存在物料不在库存中!",
Data = request.SnList
};
}
else if (inventoryDetails.Where(t => t.IsLocked).Any())
{
await DbHelp.db.RollbackTranAsync();
//返回提示哪些物料库存已被锁定
return new ResponseCommon()
{
Code = 201,
Message = "出库单据同步失败:存在物料被锁定!",
Data = inventoryDetails.Where(t => t.IsLocked).Select(t => t.MatSN).ToList()
};
}
#region
//锁库存
inventoryDetails.ForEach(t =>
{
t.IsLocked = true;
});
var lockTask = DbHelp.db.Updateable(inventoryDetails).ExecuteCommandAsync();
//保存数据
var order = new OutOrder()
{
OrderNumber = request.OrderNumber,
OrderSource = request.OrderSource,
OrderType = request.OrderType,
SyncType = SyncTypeEnum.ByMatSn,
CreateUser = request.UserName,
GroupName = LocalFile.Config.GroupName,
};
order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync();
//通过库存数据保存出库物料明细表
var matDetailTasks = inventoryDetails.Select(async t =>
{
var orderMatDetail = new OutOrderMatDetail()
{
OrderId = order.Id,
OrderNumber = order.OrderNumber,
InventoryDetailId = t.Id,
StoreId = t.StoreId,
StoreCode = t.StoreCode,
MatSN = t.MatSN,
MatCode = t.MatCode,
MatName = t.MatName,
MatSpec = t.MatSpec,
MatBatch = t.MatBatch,
MatQty = t.MatQty,
MatSupplier = t.MatSupplier,
MatCustomer = t.MatCustomer,
CreateUser = request.UserName,
};
await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync();
}).ToList();
await lockTask;
await Task.WhenAll(matDetailTasks);
await DbHelp.db.CommitTranAsync();
return new ResponseCommon()
{
Code = 200,
Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}",
Data = order.Id
};
#endregion
}
catch (Exception ex)
{
await DbHelp.db.RollbackTranAsync();
return new ResponseBase()
{
Code = 201,
Message = $"出库单据同步失败:{ex.Message}"
};
}
}
//盟讯公司逻辑 不锁库存 直接保存数据/清除未发送的
else
{
try
{
DbHelp.db.BeginTran();
//1. 获取库存物料明细
var inventoryDetails = await DbHelp.db.Queryable<InventoryDetail>()
.Where(t => request.SnList.Contains(t.MatSN))
.ToListAsync();
if (inventoryDetails == null || inventoryDetails.Count == 0)
{
return new ResponseCommon()
{
Code = 201,
Message = "保存出库单失败!请重试!",
Data = request.SnList
};
}
//2. 先获取对应单号是否已经保存
var outOrder = DbHelp.db.Queryable<OutOrder>()
.Where(t => t.OrderNumber == request.OrderNumber)
.Where(t => t.GroupName == LocalFile.Config.GroupName)
.First();
//数据库中没有才添加
if (outOrder == null)
{
//OutOrder
outOrder = new OutOrder()
{
OrderNumber = request.OrderNumber,
OrderType = request.OrderType,
OutOrderExeStatus = OutOrderExeStatus.,
OrderSource = "WCS前端",
SyncType = SyncTypeEnum.ByMatSn,
ShelfTypeName = "智能货架",
ShelfTypeId = 0,
GroupName = LocalFile.Config.GroupName,
IsMXPD = request.IsMXPD,
};
outOrder.Id = await DbHelp.db.Insertable(outOrder).ExecuteReturnIdentityAsync();
outOrder = await DbHelp.db.Queryable<OutOrder>().Where(t => t.OrderNumber == request.OrderNumber)
.Where(t => t.Id == outOrder.Id)
.FirstAsync();
//保存单据失败了
if (outOrder == null)
return new ResponseCommon()
{
Code = 201,
Message = "保存出库单失败保存Order失败",
Data = request.SnList
};
//出库物料明细
foreach (var item in inventoryDetails)
{
var orderMatDetail = new OutOrderMatDetail()
{
OrderId = outOrder.Id,
OrderNumber = outOrder.OrderNumber,
InventoryDetailId = item.Id,
StoreId = item.StoreId,
StoreCode = item.StoreCode,
MatSN = item.MatSN,
MatCode = item.MatCode,
MatName = item.MatName,
MatSpec = item.MatSpec,
MatBatch = item.MatBatch,
MatQty = item.MatQty,
MatSupplier = item.MatSupplier,
MatCustomer = item.MatCustomer,
CreateUser = request.UserName,
IsMXPD = request.IsMXPD,
};
await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync();
}
DbHelp.db.CommitTran();
}
//数据库已有该Order
else
{
outOrder.CreateTime = DateTime.Now;
DbHelp.db.Updateable(outOrder).ExecuteCommand();
//删除未出库的
var outOrderDetails = DbHelp.db.Deleteable<OutOrderMatDetail>()
.Where(t => t.OrderId == outOrder.Id)
.Where(t => t.IsSended == false)
.ExecuteCommand();
//当前已出库的 //已出库的也不在库存中了 应该查询不到了
//避免影响效率 就不查重了
foreach (var item in inventoryDetails)
{
var orderMatDetail = new OutOrderMatDetail()
{
OrderId = outOrder.Id,
OrderNumber = outOrder.OrderNumber,
InventoryDetailId = item.Id,
StoreId = item.StoreId,
StoreCode = item.StoreCode,
MatSN = item.MatSN,
MatCode = item.MatCode,
MatName = item.MatName,
MatSpec = item.MatSpec,
MatBatch = item.MatBatch,
MatQty = item.MatQty,
MatSupplier = item.MatSupplier,
MatCustomer = item.MatCustomer,
CreateUser = request.UserName,
IsMXPD = request.IsMXPD,
};
await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync();
}
DbHelp.db.CommitTran();
//更新订单状态
Task.Run(() =>
{
if (outOrder != null)
{
#region
var orderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == outOrder.Id)
.ToList();
var isExistNoSendMat = orderMatDetails.Where(t => t.IsSended == false)
.Any();
if (isExistNoSendMat)
{
outOrder.OrderStatus = OutOrderStatus.;
}
else
{
outOrder.OrderStatus = OutOrderStatus.;
outOrder.OutOrderExeStatus = OutOrderExeStatus.;
}
#endregion
DbHelp.db.Updateable(outOrder).ExecuteCommand();
}
});
}
return new ResponseCommon()
{
Code = 200,
Message = outOrder.OrderNumber,
Data = request.SnList
};
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
Logs.Write($"同步出库单据发生异常{ex.Message}", LogsType.Info);
return new ResponseCommon()
{
Code = 201,
Message = $"保存出库单失败!{ex.Message}",
Data = request.SnList
};
}
}
}
public async Task<ResponseBase> GetOutOrderList(GetOutOrderListRequest request)
{
//直接查询
var recordsQueryable = DbHelp.db.Queryable<OutOrder>()
.WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber.Contains(request.OrderNumber))
.WhereIF(!string.IsNullOrEmpty(request.OrderSource), t => t.OrderSource.Contains(request.OrderSource))
.WhereIF(!string.IsNullOrEmpty(request.OrderType), t => t.OrderType.Contains(request.OrderType))
.WhereIF(request.ShelfTypeId != 0, t => t.ShelfTypeId == request.ShelfTypeId);
var totalCount = await recordsQueryable.CountAsync();
var records = await recordsQueryable
.OrderByDescending(t => t.Id)
.Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize)
.ToListAsync();
//生成序号
for (int i = 0; i < records.Count; i++)
{
records[i].RowNumber = (request.PageNumber - 1) * request.PageSize + i + 1;
}
return new PageQueryResponse<OutOrder>()
{
Code = 200,
Message = $"success",
Data = new PageQueryResponseData<OutOrder>()
{
TotalCount = totalCount,
MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize),
Count = records.Count,
Lists = records.ToList()
}
};
}
public async Task<ResponseBase> GetOutOrderListByStatus(GetOutOrderListByStatusRequest request)
{
if (request.OrderExeStatus == null || request.OrderExeStatus.Count == 0)
{
//不传入状态不显示
return new PageQueryResponse<OutOrder>()
{
Code = 200,
Message = $"success",
Data = new PageQueryResponseData<OutOrder>()
{
Lists = new List<OutOrder>()
}
};
}
//直接查询
var recordsQueryable = DbHelp.db.Queryable<OutOrder>()
.Where(t => request.OrderExeStatus.Contains(t.OutOrderExeStatus))
.WhereIF(request.IsMXPD != null, t => t.IsMXPD == request.IsMXPD)
.WhereIF(LocalFile.Config.IsMx, t => t.CreateTime > DateTime.Now.AddDays(-3))
.WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName);
var totalCount = await recordsQueryable.CountAsync();
var records = await recordsQueryable
.OrderByDescending(t => t.CreateTime)
.ToListAsync();
//获取后台当前正在进行出库的订单 将出库状态反馈给前端
var outingOrderNumbers = ShelfManager.Shelves
.Where(t => t.CurrentMode == HardWare.Mode.)
.Select(t => t.OrderNumber)
.ToList();
foreach (var record in records)
{
if (outingOrderNumbers.Contains(record.OrderNumber))
record.IsOuting = true;
}
return new PageQueryResponse<OutOrder>()
{
Code = 200,
Message = $"success",
Data = new PageQueryResponseData<OutOrder>()
{
Lists = records.ToList()
}
};
}
public async Task<ResponseBase> GetOutOrderDetail(GetOutOrderDetailRequest request)
{
OutOrder outOrder = null;
#region
if (request.OrderId != 0)
{
outOrder = await DbHelp.db.Queryable<OutOrder>().Where(t => t.Id == request.OrderId).FirstAsync();
if (outOrder == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败不存在Id为{request.OrderId}的出库单!",
};
}
}
else if (!string.IsNullOrEmpty(request.OrderNumber))
{
outOrder = await DbHelp.db.Queryable<OutOrder>().Where(t => t.OrderNumber == request.OrderNumber)
.FirstAsync();
if (outOrder == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!",
};
}
}
else
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败:缺少必要参数!",
};
}
#endregion
#region
var orderDetailTask = DbHelp.db.Queryable<OutOrderDetail>()
.Where(t => t.OrderId == outOrder.Id)
.ToListAsync();
var orderDetail = await orderDetailTask;
//生成序号
for (int i = 0; i < orderDetail.Count; i++)
{
orderDetail[i].RowNumber = i + 1;
}
#endregion
return new ResponseCommon<List<OutOrderDetail>>()
{
Code = 200,
Message = "Success",
Data = orderDetail
};
}
/// <summary>
/// 单灯查询物料明细 PDA要求返回数据种data需要增加一层details
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<ResponseBase> GetOutOrderDetailSingleLight(GetOutOrderDetailRequest request)
{
OutOrder outOrder = null;
#region
if (request.OrderId != 0)
{
outOrder = await DbHelp.db.Queryable<OutOrder>().Where(t => t.Id == request.OrderId).FirstAsync();
if (outOrder == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败不存在Id为{request.OrderId}的出库单!",
};
}
}
else if (!string.IsNullOrEmpty(request.OrderNumber))
{
outOrder = await DbHelp.db.Queryable<OutOrder>().Where(t => t.OrderNumber == request.OrderNumber)
.FirstAsync();
if (outOrder == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!",
};
}
}
else
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败:缺少必要参数!",
};
}
#endregion
#region
var orderDetailTask = DbHelp.db.Queryable<OutOrderDetail>()
.Where(t => t.OrderId == outOrder.Id)
.ToListAsync();
var orderDetail = await orderDetailTask;
//生成序号
for (int i = 0; i < orderDetail.Count; i++)
{
orderDetail[i].RowNumber = i + 1;
}
#endregion
return new ResponseCommonModify<OutOrderDetail>()
{
Code = 200,
Message = "Success",
Data = new ResponseCommonDataDetail<OutOrderDetail>
{
Details = orderDetail
}
};
}
public async Task<ResponseBase> GetOutOrderMatDetail(GetOutOrderDetailRequest request)
{
OutOrder outOrder = null;
#region
if (request.OrderId != 0)
{
outOrder = await DbHelp.db.Queryable<OutOrder>().Where(t => t.Id == request.OrderId).FirstAsync();
if (outOrder == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败不存在Id为{request.OrderId}的出库单!",
};
}
}
else if (!string.IsNullOrEmpty(request.OrderNumber))
{
outOrder = await DbHelp.db.Queryable<OutOrder>().Where(t => t.OrderNumber == request.OrderNumber)
.FirstAsync();
if (outOrder == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!",
};
}
}
else
{
return new ResponseCommon()
{
Code = 201,
Message = $"查询失败:缺少必要参数!",
};
}
#endregion
#region
var orderMatDetailTask = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == outOrder.Id)
.ToListAsync();
var orderMatDetail = await orderMatDetailTask;
//生成序号
for (int i = 0; i < orderMatDetail.Count; i++)
{
orderMatDetail[i].RowNumber = i + 1;
}
#endregion
return new ResponseCommon<List<OutOrderMatDetail>>
{
Code = 200,
Message = outOrder.OrderStatus.ToString(),
Data = orderMatDetail
};
}
public async Task<ResponseBase> GoInOutstore(GetOutOrderDetailRequest request)
{
try
{
//获取出库单
var order = await DbHelp.db.Queryable<OutOrder>()
.WhereIF(request.OrderId != 0, t => t.Id == request.OrderId)
.WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber)
.FirstAsync();
if (order == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"不存在对应的出库单据{request.OrderNumber}",
Data = null
};
}
//如果是按物料编码出库 需要计算物料明细、并进行物料锁定
if (order.SyncType == SyncTypeEnum.ByMatCode)
{
var result = CaculateOutOrderMatDetails(order, request.UserName);
if (result.Code != 200)
{
return result;
}
}
//获取需要出库的物料明细
var outOrderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == order.Id)
.Where(t => t.IsSended == false)
.Includes(t => t.StoreInfo)
.ToList();
if (outOrderMatDetails == null || outOrderMatDetails.Count == 0)
{
return new ResponseCommon()
{
Code = 201,
Message = $"出库单据{request.OrderNumber}物料已全部完成出库!",
Data = null
};
}
if (request.IsStart)
{
order.OutOrderExeStatus = OutOrderExeStatus.;
DbHelp.db.Updateable(order).ExecuteCommand();
}
//按货架分组 按物料找到对应的货架
var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId)
.Distinct()
.ToList();
var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList(); ;
var outherModeShelfs = shelfs.Where(t => t.CurrentMode != HardWare.Mode.).Select(t => t.ShelfCode).ToList();
if (outherModeShelfs != null && outherModeShelfs.Count > 0)
{
return new ResponseCommon()
{
Code = 201,
Message = $"进入出库模式失败:货架{string.Join("", outherModeShelfs)}不在待机模式",
Data = null
};
}
//看是否是分批次出库的情况 分批次亮灯
if (LocalFile.Config.IsSameMatCodeOut)
{
//最先亮的颜色为绿色
LocalStatic.CurrentOutStoreColor = 0x02;
var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode)
.Select(o => new { count = o.Count(), bb = o })
.Where(o => o.count >= 2)
.OrderByDescending(o => o.count)
.ToList();
//相同物料存在盘数超过2的情况亮下一个盘数多的物料
if (outOrderDetailCount.Count > 0)
{
var matCode = outOrderDetailCount.First().bb.Key;
outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode)
.ToList();
Logs.Write($"出库单{order.OrderNumber},本次亮灯物料{matCode}", LogsType.Outstore);
//分批次亮灯再计算一次出哪些货架 以免亮大灯不亮小灯
shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId)
.Distinct()
.ToList();
shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList();
}
//相同物料不存在盘数超过n的情况剩余物料全部亮灯
else
{
//剩余物料全出
Logs.Write($"出库单{order.OrderNumber},剩余物料灯全亮!", LogsType.Outstore);
}
}
//对应的货架对应位置 进入出库模式 亮灯
shelfs.ForEach(shelf =>
{
var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode)
.Distinct()
.ToList();
shelf.GoInOutstore(matDetails, order, request.UserName);
shelf.OrderNumber = order.OrderNumber;
Logs.Write($"出库单{order.OrderNumber},货架{shelf.ShelfCode}进入出库模式!", LogsType.Outstore);
});
//返回
return new ResponseCommon()
{
Code = 200,
Message = "Success",
Data = null
};
}
catch (Exception ex)
{
Logs.Write($"本次发料发生异常!{ex.Message}", LogsType.Outstore);
await GoOutOutstore(request);
throw ex;
}
}
public async Task<ResponseBase> GoInOutstoreSingle(GetOutOrderDetailRequest request)
{
try
{
//获取出库单
var order = await DbHelp.db.Queryable<OutOrder>()
.WhereIF(request.OrderId != 0, t => t.Id == request.OrderId)
.WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber)
.FirstAsync();
if (order == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"不存在对应的出库单据{request.OrderNumber}",
Data = null
};
}
//如果是按物料编码出库 需要计算物料明细、并进行物料锁定
if (order.SyncType == SyncTypeEnum.ByMatCode)
{
var result = CaculateOutOrderMatDetails(order, request.UserName);
if (result.Code != 200)
{
return result;
}
}
//获取需要出库的物料明细
var outOrderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == order.Id)
.Where(t => t.IsSended == false)
.Includes(t => t.StoreInfo)
.ToList();
if (outOrderMatDetails == null || outOrderMatDetails.Count == 0)
{
return new ResponseCommon()
{
Code = 201,
Message = $"出库单据{request.OrderNumber}物料已全部完成出库!",
Data = null
};
}
if (request.IsStart)//&& order.OutOrderExeStatus != OutOrderExeStatus.发料完成
{
order.OutOrderExeStatus = OutOrderExeStatus.;
DbHelp.db.Updateable(order).ExecuteCommand();
}
//获取亮灯颜色
List<string> UsedColor = new List<string>();
string LightColor = "";
List<OrderLight> ol = DbHelp.db.Queryable<OrderLight>().OrderBy(it => it.Id, OrderByType.Asc).ToList();
foreach (OrderLight orderLight in ol)
{
UsedColor.Add(orderLight.LightColor);
if (orderLight.OrderNumber == request.OrderNumber)
{
LightColor = orderLight.LightColor;
break;
}
}
if (LightColor == "")
{
foreach (OrderLight orderLight in ol)
{
if (orderLight.OrderNumber == null)
{
LightColor = orderLight.LightColor;
DbHelp.db.Updateable<OrderLight>().SetColumns(it => it.OrderNumber, request.OrderNumber).Where(it => it.LightColor == LightColor).ExecuteCommand();
break;
}
}
}
//获取出库需求
List<OutOrderDetail> outorderdetal = DbHelp.db.Queryable<OutOrderDetail>()
.WhereIF(request.OrderId != 0, t => t.OrderId == request.OrderId)
.WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber)
.ToList();
OutResponseCommonSingle orcs = new OutResponseCommonSingle();
orcs.Data = new List<OutDetail>();
foreach (OutOrderDetail outdetail in outorderdetal)
{
OutDetail od = new OutDetail();
od.OrderId = outdetail.OrderId;
od.OrderNumber = outdetail.OrderNumber;
od.MatCode = outdetail.MatCode;
od.MatBatch = outdetail.MatBatch;
od.ReqQty = outdetail.ReqQty;
od.CreateTime = outdetail.CreateTime;
od.CreateUser = outdetail.CreateUser;
od.MatName = outdetail.MatName;
od.OutQty = outdetail.OutQty;
od.LightColor = LightColor;
orcs.Data.Add(od);
}
//需要出库的货架名
List<string> StoreCode = new List<string>();
//库位灯亮灯
Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
foreach (OutOrderMatDetail oomd in outOrderMatDetails)
{
List<ModuleInfo> mi = DbHelp.db.Queryable<ModuleInfo>().Where(it => it.ModuleCode == oomd.StoreCode).ToList();
if (mi.Count != 0)
{
if (!StoreCode.Contains(oomd.StoreCode))
{
StoreCode.Add(oomd.StoreCode);
}
if (!dict.Keys.Contains(mi[0].CleintIp))
{
List<int> board_id = new List<int>();
board_id.Add(mi[0].BoardId);
dict.Add(mi[0].CleintIp, board_id);
}
else
{
foreach (var v in dict)
{
if (v.Key == mi[0].CleintIp)
{
if (!v.Value.Contains(mi[0].BoardId))
{
v.Value.Add(mi[0].BoardId);
}
}
}
}
}
}
foreach (var v in dict)
{
string sendIP = v.Key;
TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP);
byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor, 1);
tCPClient.Send(lightOn);
Logs.Write("出库,库位灯亮:" + BitConverter.ToString(lightOn));
Thread.Sleep(100);
}
//报警灯亮
List<string> WarnLightShelfCode = new List<string>();
foreach (string storecode in StoreCode)
{
List<ModuleInfo> mi = DbHelp.db.Queryable<ModuleInfo>().Where(it => it.ModuleCode == storecode).ToList();
if (mi.Count != 0)
{
if (!WarnLightShelfCode.Contains(mi[0].ShelfCode))
{
WarnLightShelfCode.Add(mi[0].ShelfCode);
}
}
}
//发送间隔
Thread.Sleep(300);
foreach (string shelfcode in WarnLightShelfCode)
{
List<ShelfInfo> si = DbHelp.db.Queryable<ShelfInfo>().Where(it => it.ShelfCode == shelfcode).ToList();
if (si.Count != 0)
{
for (int i = 0; i < si.Count; i++)
{
TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(si[i].ClientIp);
//byte[] warnlightOn = Helper.OutstoreWarnLight(si[i].LightId, LightColor, 1, 0);
byte[] warnlightOn = Helper.OutstoreWarnLight_1(si[i].LightId, LightColor, 1, 1);
tCPClient.Send(warnlightOn);
Logs.Write("出库,报警灯亮:" + BitConverter.ToString(warnlightOn));
Thread.Sleep(100);
}
}
}
//返回
return new OutResponseCommonSingle()
{
Code = 200,
Message = LightColor,
Data = orcs.Data
};
}
catch (Exception ex)
{
await GoOutOutstore(request);
throw ex;
}
}
//计算、加锁
private ResponseBase CaculateOutOrderMatDetails(OutOrder order, string createUser = "")
{
try
{
DbHelp.db.BeginTran();
//第一步 物料需求表
var outOrderDetails = DbHelp.db.Queryable<OutOrderDetail>()
.Where(t => t.OrderId == order.Id)
.ToList();
if (outOrderDetails == null || outOrderDetails.Count == 0)
{
return new ResponseCommon()
{
Code = 201,
Message = $"计算物料失败,{order.OrderNumber}没有出库单据明细!"
};
}
//第二步 开始计算物料
List<OutOrderMatDetail> outOrderMatDetails = new List<OutOrderMatDetail>();
foreach (var outOrderDetail in outOrderDetails)
{
//2.1筛选 满足 物料编码、批次的库存
var matInventoryDetails = DbHelp.db.Queryable<InventoryDetail>()
.Where(t => t.MatCode == outOrderDetail.MatCode)
.WhereIF(!string.IsNullOrEmpty(outOrderDetail.MatBatch), t => t.MatBatch == outOrderDetail.MatBatch)
.Where(t => t.IsLocked == false)//未锁定的物料
.Where(t => t.StoreInfo.ShelfTypeId == order.ShelfTypeId)
.OrderBy(t => t.MatBatch)//按批次先进先出
//(t => t.MatQty)//零散料先出
.ToList();
//2.2按照搜索出来的库存和当前未出的数量 计算需要出的SN
for (int i = 0; i < matInventoryDetails.Count && outOrderDetail.ReqQty - outOrderDetail.OutQty > 0; i++)
{
if (outOrderDetail.ReqQty - outOrderDetail.OutQty <= matInventoryDetails[i].MatQty)
{
outOrderMatDetails.Add(new OutOrderMatDetail()
{
OrderId = order.Id,
OrderNumber = order.OrderNumber,
OutOrderDetailId = outOrderDetail.Id,
InventoryDetailId = matInventoryDetails[i].Id,
StoreId = matInventoryDetails[i].StoreId,
StoreCode = matInventoryDetails[i].StoreCode,
MatSN = matInventoryDetails[i].MatSN,
MatCode = matInventoryDetails[i].MatCode,
MatName = matInventoryDetails[i].MatName,
MatSpec = matInventoryDetails[i].MatSpec,
MatBatch = matInventoryDetails[i].MatBatch,
MatQty = matInventoryDetails[i].MatQty,
MatSupplier = matInventoryDetails[i].MatSupplier,
MatCustomer = matInventoryDetails[i].MatCustomer,
IsSended = false,
CreateUser = createUser,
});
outOrderDetail.ReqQty = 0;
matInventoryDetails[i].IsLocked = true;
DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand();
}
else
{
outOrderDetail.ReqQty = outOrderDetail.ReqQty - matInventoryDetails[i].MatQty;
outOrderMatDetails.Add(new OutOrderMatDetail()
{
OrderId = order.Id,
OrderNumber = order.OrderNumber,
OutOrderDetailId = outOrderDetail.Id,
InventoryDetailId = matInventoryDetails[i].Id,
StoreId = matInventoryDetails[i].StoreId,
StoreCode = matInventoryDetails[i].StoreCode,
MatSN = matInventoryDetails[i].MatSN,
MatCode = matInventoryDetails[i].MatCode,
MatName = matInventoryDetails[i].MatName,
MatSpec = matInventoryDetails[i].MatSpec,
MatBatch = matInventoryDetails[i].MatBatch,
MatQty = matInventoryDetails[i].MatQty,
MatSupplier = matInventoryDetails[i].MatSupplier,
MatCustomer = matInventoryDetails[i].MatCustomer,
IsSended = false,
CreateUser = createUser,
});
matInventoryDetails[i].IsLocked = true;
DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand();
}
}
}
DbHelp.db.Insertable(outOrderMatDetails).ExecuteCommand();
DbHelp.db.CommitTran();
if (outOrderMatDetails.Count == 0)
{
return new ResponseCommon()
{
Code = 201,
Message = $"计算物料失败,没有满足条件的物料进行出库!(请检查对应物料是否已被锁定)"
};
}
else
return new ResponseCommon()
{
Code = 200,
Message = $"Success"
};
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
return new ResponseCommon()
{
Code = 300,
Message = $"发生异常:{ex.Message}"
};
}
}
//删除 解锁
private ResponseBase CancelOutOrderMatDetails(OutOrder order)
{
try
{
DbHelp.db.BeginTran();
var outOrderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == order.Id)
.Where(t => t.IsSended == false)
.ToList();
var inventoryIds = outOrderMatDetails.Select(t => t.InventoryDetailId).ToList();
var inventoryDetails = DbHelp.db.Queryable<InventoryDetail>()
.Where(t => inventoryIds.Contains(t.Id))
.ToList();
inventoryDetails.ForEach(t => { t.IsLocked = false; });
DbHelp.db.Deleteable(outOrderMatDetails).ExecuteCommand();
DbHelp.db.Updateable(inventoryDetails).ExecuteCommand();
DbHelp.db.CommitTran();
return new ResponseCommon()
{
Code = 200,
Message = $"Success"
};
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
return new ResponseCommon()
{
Code = 300,
Message = $"解锁物料时发生异常:{ex.Message}"
};
}
}
public async Task<ResponseBase> GoOutOutstore(GetOutOrderDetailRequest request)
{
//获取出库单
var order = await DbHelp.db.Queryable<OutOrder>()
.WhereIF(request.OrderId != 0, t => t.Id == request.OrderId)
.WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber)
.FirstAsync();
if (order == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"不存在对应的出库单据{request.OrderNumber}",
Data = null
};
}
//执行状态改为暂停
if (request.IsPause && order.OutOrderExeStatus != OutOrderExeStatus.)
{
order.OutOrderExeStatus = OutOrderExeStatus.;
DbHelp.db.Updateable(order).ExecuteCommand();
}
//解锁物料 删除物料明细
if (order.SyncType == SyncTypeEnum.ByMatCode)
CancelOutOrderMatDetails(order);
//找到正在出对应出库单的货架
var shelves = ShelfManager.Shelves.Where(t => t.OrderNumber == request.OrderNumber)
.Where(t => t.CurrentMode == HardWare.Mode.)
.ToList();
if (shelves == null || shelves.Count == 0)
{
return new ResponseCommon()
{
Code = 201,
Message = $"出库单据【{request.OrderNumber}】不在出库中!",
Data = null
};
}
//退出出库模式
shelves.ForEach(t =>
{
t.GoOutOutstore();
});
return new ResponseCommon()
{
Code = 200,
Message = "Success",
Data = null
};
}
public async Task<ResponseBase> GoOutOutstoreSingle(GetOutOrderDetailRequest request)
{
//获取出库单
var order = await DbHelp.db.Queryable<OutOrder>()
.WhereIF(request.OrderId != 0, t => t.Id == request.OrderId)
.WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber)
.FirstAsync();
if (order == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"不存在对应的出库单据{request.OrderNumber}",
Data = null
};
}
//判断出库状态
bool isComplete = true;
List<OutOrderDetail> ood = DbHelp.db.Queryable<OutOrderDetail>().Where(it => it.OrderNumber == request.OrderNumber).ToList();
foreach (OutOrderDetail detail in ood)
{
if (detail.ReqQty > detail.OutQty)
{
isComplete = false;
break;
}
}
if (isComplete == false)
{
order.OutOrderExeStatus = OutOrderExeStatus.;
DbHelp.db.Updateable(order).ExecuteCommand();
}
else
{
order.OutOrderExeStatus = OutOrderExeStatus.;
DbHelp.db.Updateable(order).ExecuteCommand();
}
//解锁物料
List<OutOrderMatDetail> List = DbHelp.db.Queryable<OutOrderMatDetail>().Where(it => it.OrderNumber == request.OrderNumber).ToList();
foreach (OutOrderMatDetail listdetail in List)
{
DbHelp.db.Updateable<InventoryDetail>().SetColumns(it => it.IsLocked == false).Where(it => it.MatSN == listdetail.MatSN).ExecuteCommand();
}
//灭灯
//获取需要出库的物料明细
var outOrderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderNumber == request.OrderNumber)
.ToList();
//需要出库的货架名
List<string> StoreCode = new List<string>();
//库位灯灭灯
string LightColor = "无";
try
{
List<OrderLight> ol = DbHelp.db.Queryable<OrderLight>().Where(it => it.OrderNumber == request.OrderNumber).ToList();
LightColor = ol[0].LightColor;
}
catch (Exception ee)
{
Logs.Write("查询出库单据:" + request.OrderNumber + "对应库位灯颜色失败," + ee.Message);
}
Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
foreach (OutOrderMatDetail oomd in outOrderMatDetails)
{
List<ModuleInfo> mi = DbHelp.db.Queryable<ModuleInfo>().Where(it => it.ModuleCode == oomd.StoreCode).ToList();
if (mi.Count != 0)
{
if (!StoreCode.Contains(oomd.StoreCode))
{
StoreCode.Add(oomd.StoreCode);
}
if (!dict.Keys.Contains(mi[0].CleintIp))
{
List<int> board_id = new List<int>();
board_id.Add(mi[0].BoardId);
dict.Add(mi[0].CleintIp, board_id);
}
else
{
foreach (var v in dict)
{
if (v.Key == mi[0].CleintIp)
{
if (!v.Value.Contains(mi[0].BoardId))
{
v.Value.Add(mi[0].BoardId);
}
}
}
}
}
}
foreach (var v in dict)
{
string sendIP = v.Key;
TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP);
byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor, 0);
tCPClient.Send(lightOn);
Logs.Write("出库,库位灯灭:" + BitConverter.ToString(lightOn));
Thread.Sleep(100);
}
//报警灯灭
List<string> WarnLightShelfCode = new List<string>();
foreach (string storecode in StoreCode)
{
List<ModuleInfo> mi = DbHelp.db.Queryable<ModuleInfo>().Where(it => it.ModuleCode == storecode).ToList();
if (mi.Count != 0)
{
if (!WarnLightShelfCode.Contains(mi[0].ShelfCode))
{
WarnLightShelfCode.Add(mi[0].ShelfCode);
}
}
}
//发送间隔
//Thread.Sleep(300);
foreach (string shelfcode in WarnLightShelfCode)
{
List<ShelfInfo> si = DbHelp.db.Queryable<ShelfInfo>().Where(it => it.ShelfCode == shelfcode).ToList();
if (si.Count != 0)
{
for (int i = 0; i < si.Count; i++)
{
Thread.Sleep(250);
TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(si[i].ClientIp);
byte[] warnlightOn = Helper.OutstoreWarnLight_1(si[i].LightId, LightColor, 0, 0);
tCPClient.Send(warnlightOn);
Logs.Write("出库,报警灯灭:" + BitConverter.ToString(warnlightOn));
}
}
}
if (isComplete == true)
{
DbHelp.db.Updateable<OrderLight>().SetColumns(it => it.OrderNumber == null).Where(it => it.OrderNumber == request.OrderNumber).ExecuteCommand();
}
return new ResponseCommon()
{
Code = 200,
Message = "Success",
Data = null
};
}
public async Task<ResponseBase> SingleLightConfirmOutstore(OutOrderMatDetailModelSingle request)
{
try
{
//单据校验
var order = await DbHelp.db.Queryable<OutOrder>()
.Where(it => it.Id == request.OrderId)
.Where(it => it.OrderNumber == request.OrderNumber)
.FirstAsync();
if (order == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"系统不存在单据[{request.OrderNumber}]!",
Data = null
};
}
//物料校验
var invetoryDetail = await DbHelp.db.Queryable<InventoryDetail>()
.Where(it => it.Id == request.MatId)
.Where(it => it.MatSN == request.MatSn)
.FirstAsync();
if (invetoryDetail == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"库存中不存在物料[{request.MatSn}]!",
Data = null
};
}
//获取库位是否是信息化货架的库位
var shelf = await DbHelp.db.Queryable<StoreInfo>()
.LeftJoin<ShelfTypeInfo>((si, sti) => si.ShelfTypeId == sti.Id)
.Where((si, sti) => si.Id == invetoryDetail.StoreId)
.Select((si, sti) => new
{
ShelfId = si.ShelfId,
ShelfTypeName = sti.ShelfTypeName
})
.FirstAsync();
if (shelf != null && shelf.ShelfTypeName != "信息化货架")
{
return new ResponseCommon()
{
Code = 201,
Message = $"该物料库存不在信息化货架上,不能进行出库!",
Data = null
};
}
//物料需求明细校验
var outOrderDetail = await DbHelp.db.Queryable<OutOrderDetail>().Where(it => it.OrderNumber == request.OrderNumber)
.Where(it => it.MatCode == invetoryDetail.MatCode)
.FirstAsync();
if (outOrderDetail == null)
{
return new ResponseCommon()
{
Code = 201,
Message = $"单据[{request.OrderNumber}]需求不包含物料[{invetoryDetail.MatCode}]!",
Data = null
};
}
var inOutRecord = new InOutRecord();
inOutRecord.StoreId = invetoryDetail.StoreId;
inOutRecord.StoreCode = invetoryDetail.StoreCode;
inOutRecord.MatSN = invetoryDetail.MatSN;
inOutRecord.MatCode = invetoryDetail.MatCode;
inOutRecord.MatName = invetoryDetail.MatName;
inOutRecord.MatSpec = invetoryDetail.MatSpec;
inOutRecord.MatBatch = invetoryDetail.MatBatch;
inOutRecord.MatQty = invetoryDetail.MatQty;
inOutRecord.MatSupplier = invetoryDetail.MatSupplier;
inOutRecord.MatCustomer = invetoryDetail.MatCustomer;
inOutRecord.OrderNumber = order.OrderNumber;
inOutRecord.Direction = DirectionEnum.;
inOutRecord.OperateUser = request.UserName;
inOutRecord.OperateTime = DateTime.Now;
inOutRecord.GroupName = invetoryDetail.GroupName;
//保存出库记录
int count = DbHelp.db.Insertable(inOutRecord).ExecuteCommand();
//删除库存
DbHelp.db.Deleteable<InventoryDetail>().Where(it => it.MatSN == request.MatSn).ExecuteCommand();
//更新需求表
outOrderDetail.OutQty += invetoryDetail.MatQty;
DbHelp.db.Updateable(outOrderDetail).ExecuteCommand();
//蜂鸣器提示
Task.Run(() =>
{
Logs.Write("【单灯出库蜂鸣器提示】开始");
if (shelf != null)
{
var Shelf = DbHelp.db.Queryable<ShelfInfo>().Where(t => t.Id == shelf.ShelfId).First();
if (Shelf != null)
{
TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(Shelf.ClientIp);
byte[] lightOn = Helper.CommitOutstoreBee(Shelf.LightId);
tCPClient.Send(lightOn);
Logs.Write($"【单灯出库蜂鸣器提示】已发送指令");
}
else
Logs.Write($"【单灯出库蜂鸣器提示】Shelf == null ID为{shelf.ShelfId}");
}
else
Logs.Write("【单灯出库蜂鸣器提示】shelf == null");
});
return new ResponseCommon()
{
Code = 200,
Message = $"出库成功",
Data = null
};
}
catch (Exception ex)
{
return new ResponseCommon()
{
Code = 300,
Message = $"出库发生异常!",
Data = null
};
}
}
}
}