using MES.Service.DB;
|
using MES.Service.Dto.webApi;
|
using MES.Service.Modes;
|
using SqlSugar;
|
using Newtonsoft.Json;
|
using System.Text;
|
|
namespace MES.Service.service.Warehouse;
|
|
public class MesInvItemStocksManager : Repository<MesInvItemStocks>
|
{
|
/// <summary>
|
/// 查询可以退货的物料
|
/// </summary>
|
/// <returns>可退货物料库存列表</returns>
|
public List<ReturnableStockDto> GetReturnableStocks()
|
{
|
// 1. 查询XB_RACKING_TASK_SYXT_LOG中所有的条码并去重
|
var distinctBarcodes = Db.Queryable<XbRackingTaskSyxtLog>()
|
.Where(x => !string.IsNullOrEmpty(x.ItemBarcode))
|
.Select(x => x.ItemBarcode)
|
.Distinct()
|
.ToList();
|
|
if (distinctBarcodes == null || !distinctBarcodes.Any())
|
{
|
return new List<ReturnableStockDto>();
|
}
|
|
// 2. 使用条码查询MES_INV_ITEM_STOCKS中的数据,关联MES_ITEMS、MES_DEPOTS、ORGANIZE、MES_UNIT表
|
var queryResult = Db.Queryable<MesInvItemStocks>()
|
.LeftJoin<MesItems>((stock, item) => stock.ItemId == item.Id)
|
.LeftJoin<MesDepots>((stock, item, depot) =>
|
stock.DepotsCode == depot.DepotCode)
|
.LeftJoin<Organize>((stock, item, depot, org) =>
|
item.UseOrg == org.Id.ToString())
|
.LeftJoin<MesUnit>((stock, item, depot, org, unit) =>
|
item.ItemUnit == unit.Id.ToString())
|
.Where((stock, item, depot, org, unit) =>
|
distinctBarcodes.Contains(stock.ItemBarcode) &&
|
stock.Quantity > 0)
|
.Select((stock, item, depot, org, unit) => new
|
{
|
IqcStatus = stock.IqcStatus,
|
StackCode = stock.StackCode,
|
DepotCode = stock.DepotsCode,
|
DepotName = depot.DepotName,
|
DepotSectionsCode = stock.DepotSectionsCode,
|
ItemNo = item.ItemNo,
|
ItemName = item.ItemName,
|
ItemModel = item.ItemModel,
|
Quantity = stock.Quantity,
|
ItemUnit = item.ItemUnit,
|
ItemUnitName = unit.Fname,
|
IndepDate = stock.IndepDate,
|
OrgCode = org.Fnumber,
|
OrgName = org.Fname,
|
ItemBarcode = stock.ItemBarcode
|
})
|
.ToList();
|
|
// 3. 在内存中进行数据转换
|
var result = queryResult.Select(x => new ReturnableStockDto
|
{
|
IqcStatus = x.IqcStatus == "已检" ? "1" : "0",
|
ItemType = x.DepotName == "原材料仓" ? "0" : "1",
|
StackCode = x.StackCode,
|
DepotCode = x.DepotCode,
|
DepotName = x.DepotName,
|
DepotSectionsCode = x.DepotSectionsCode,
|
ItemNo = x.ItemNo,
|
ItemName = x.ItemName,
|
ItemModel = x.ItemModel,
|
Quantity = x.Quantity,
|
ItemUnit = x.ItemUnit,
|
ItemUnitName = x.ItemUnitName,
|
IndepDate = x.IndepDate,
|
OrgCode = x.OrgCode,
|
OrgName = x.OrgName,
|
ItemBarcode = x.ItemBarcode
|
}).ToList();
|
|
return result;
|
}
|
|
/// <summary>
|
/// 根据用户编码和字符串生成退料请求单
|
/// </summary>
|
/// <param name="dto">查询参数DTO</param>
|
/// <returns>是否成功</returns>
|
public bool CreateReturnMaterialRequest(ItemStockQueryDto dto)
|
{
|
// 请求地址: http://172.20.5.5:50080/Services/Wmcs/RetrieveTask
|
// 参数格式: [{"taskCode":"xxx", "taskType":"1", "palletCode":"xxx", "widthType":"180", "station":"3"}]
|
|
if (dto?.ItemBarcodes == null || !dto.ItemBarcodes.Any())
|
{
|
return false;
|
}
|
|
try
|
{
|
// 对每个条码单独处理
|
foreach (var barcode in dto.ItemBarcodes)
|
{
|
decimal messageId = 0;
|
string taskCode = "";
|
|
try
|
{
|
// 1. 查询该条码对应的库存信息,按物料和批号汇总
|
var stockItems = Db.Queryable<MesInvItemStocks>()
|
.LeftJoin<MesItems>((stock, item) =>
|
stock.ItemId == item.Id)
|
.Where((stock, item) =>
|
stock.ItemBarcode == barcode && stock.Quantity > 0)
|
.GroupBy((stock, item) =>
|
new { stock.ItemId, stock.LotNo })
|
.Select((stock, item) => new
|
{
|
ItemNo = SqlFunc.AggregateMax(item.ItemNo),
|
ItemName = SqlFunc.AggregateMax(item.ItemName),
|
LotNo = stock.LotNo ?? "",
|
Quantity = SqlFunc.AggregateSum(stock.Quantity),
|
StackCode = SqlFunc.AggregateMax(stock.DepotSectionsCode)
|
})
|
.ToList();
|
|
if (!stockItems.Any())
|
{
|
continue; // 跳过没有库存的条码
|
}
|
|
// 2. 生成任务号
|
taskCode =
|
Db.Ado.GetString(
|
"SELECT getbillcode1(1000, 1000, 'LKRK') FROM DUAL");
|
|
// 3. 获取第一条记录用于主表
|
var firstStock = stockItems.First();
|
|
// 4. 构建请求参数(数组格式)
|
var requestData = new
|
{
|
taskCode = taskCode,
|
taskType = "1",
|
palletCode = firstStock.StackCode ?? "",
|
widthType = "180",
|
station = "3"
|
};
|
var requestList = new[] { requestData };
|
var jsonRequest = JsonConvert.SerializeObject(requestList);
|
|
// 5. 记录到MessageCenter表(请求前)
|
|
var messageCenter = new MessageCenter
|
{
|
TableName = "XB_RACKING_TASK_SYXT_LOG",
|
Url =
|
"http://172.20.5.5:50080/Services/Wmcs/RetrieveTask",
|
Method = "POST",
|
Status = 1,
|
CreateBy = dto.UserCode,
|
CreateDate =
|
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
Title = "立库出库任务",
|
PageName = taskCode,
|
Data = jsonRequest,
|
DataInserted = jsonRequest
|
};
|
messageId = Db.Insertable(messageCenter).ExecuteReturnIdentity();
|
|
// 6. 调用HTTP接口
|
var apiUrl =
|
"http://172.20.5.5:50080/Services/Wmcs/RetrieveTask";
|
|
using var http = new HttpClient();
|
http.Timeout = TimeSpan.FromSeconds(30);
|
var content = new StringContent(jsonRequest, Encoding.UTF8,
|
"application/json");
|
var response = http.PostAsync(apiUrl, content).Result;
|
var responseStr =
|
response.Content.ReadAsStringAsync().Result;
|
|
//接口的响应是 {"Code":"200","JsonMessage":null,"CodeMessage":null,"Data":null}
|
|
//只有当Code为200时,才插入XbRackingTaskSyxtLog表 不然就是抛出异常,异常的内容为JsonMessage中的内容
|
|
// 6. 解析响应JSON
|
dynamic responseJson = null;
|
try
|
{
|
responseJson =
|
JsonConvert.DeserializeObject<dynamic>(responseStr);
|
}
|
catch
|
{
|
throw new Exception($"解析响应失败: {responseStr}");
|
}
|
|
var code = responseJson?.Code?.ToString();
|
var jsonMessage = responseJson?.JsonMessage?.ToString();
|
|
// 7. 根据Code判断成功或失败
|
if (code == "200")
|
{
|
// 成功:插入任务记录到XB_RACKING_TASK_SYXT_LOG表
|
var taskLog = new XbRackingTaskSyxtLog
|
{
|
CreateBy = dto.UserCode,
|
CreateDate = DateTime.Now,
|
TaskCode = taskCode,
|
TaskType = "立库出库请求",
|
PalletCode = firstStock.StackCode,
|
WidthType = 180,
|
MaterialName = firstStock.ItemName,
|
MaterialCode = firstStock.ItemNo,
|
BatchNo = firstStock.LotNo,
|
Quantity = firstStock.Quantity,
|
WarehousingJson = responseStr,
|
QcStatus = 2,
|
ItemBarcode = barcode,
|
Code = "200",
|
JsonMessage = jsonMessage ?? "成功"
|
};
|
Db.Insertable(taskLog).ExecuteCommand();
|
|
// 更新MessageCenter表为成功状态
|
var successMessage = "立库任务下发成功,任务号为" + taskCode;
|
Db.Updateable<MessageCenter>()
|
.SetColumns(it => it.Result == 1)
|
.SetColumns(it => it.ResultData == successMessage)
|
.SetColumns(it => it.DealWith == 1)
|
.Where(it => it.Id == messageId)
|
.ExecuteCommand();
|
}
|
else
|
{
|
// 失败:更新MessageCenter表为失败状态
|
var errorMessage = string.IsNullOrEmpty(jsonMessage)
|
? "任务请求失败"
|
: jsonMessage;
|
var failureMessage =
|
(string)("立库任务下发失败: " + errorMessage);
|
|
Db.Updateable<MessageCenter>()
|
.SetColumns(it => it.Result == 0)
|
.SetColumns(it => it.ResultData == failureMessage)
|
.SetColumns(it => it.DealWith == 0)
|
.Where(it => it.Id == messageId)
|
.ExecuteCommand();
|
|
// 抛出异常,异常内容为JsonMessage
|
throw new Exception(errorMessage);
|
}
|
}
|
catch (Exception ex)
|
{
|
// 异常时也要更新MessageCenter表
|
if (messageId > 0)
|
{
|
var exceptionMessage =
|
(string)("立库任务异常: " + ex.Message);
|
Db.Updateable<MessageCenter>()
|
.SetColumns(it => it.Result == 0)
|
.SetColumns(it =>
|
it.ResultData == exceptionMessage)
|
.SetColumns(it => it.DealWith == 0)
|
.Where(it => it.Id == messageId)
|
.ExecuteCommand();
|
}
|
|
// 继续抛出异常
|
throw;
|
}
|
}
|
|
return true;
|
}
|
catch (Exception ex)
|
{
|
// 记录日志并重新抛出异常,让Controller层获取具体错误信息
|
Console.WriteLine($"生成退料请求单失败: {ex.Message}");
|
throw;
|
}
|
}
|
}
|