using LogLibrary.Log;
|
using MailKit;
|
using MailKit.Search;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
|
using Org.BouncyCastle.Asn1.X509;
|
using SixLabors.ImageSharp;
|
using SqlSugar;
|
using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Data;
|
using System.Linq;
|
using System.Net;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEA_Common.AllocateEnum;
|
using WIDESEA_Common.CommonEnum;
|
using WIDESEA_Common.OrderEnum;
|
using WIDESEA_Common.StockEnum;
|
using WIDESEA_Core;
|
using WIDESEA_Core.BaseRepository;
|
using WIDESEA_Core.Helper;
|
using WIDESEA_Core.Util;
|
using WIDESEA_Core.Utilities;
|
using WIDESEA_DTO.Allocate;
|
using WIDESEA_DTO.Inbound;
|
using WIDESEA_DTO.Mes;
|
using WIDESEA_DTO.ReturnMES;
|
using WIDESEA_IBasicService;
|
using WIDESEA_IInboundService;
|
using WIDESEA_IStockService;
|
using WIDESEA_Model.Models;
|
using WIDESEA_Model.Models.Basic;
|
using WIDESEA_Model.Models.Check;
|
|
namespace WIDESEA_InboundService
|
{
|
public class InboundService : IInboundService
|
{
|
LogFactory LogFactory = new LogFactory();
|
private readonly IUnitOfWorkManage _unitOfWorkManage;
|
public IInboundOrderDetailService InboundOrderDetailService { get; }
|
|
public IInboundOrderService InbounOrderService { get; }
|
private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
|
private readonly IRepository<Dt_WarehouseArea> _warehouseAreaRepository;
|
private readonly IRepository<Dt_LocationType> _locationTypeRepository;
|
private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
|
private readonly IRepository<Dt_InboundOrderDetail> _inboundOrderDetailRepository;
|
private readonly IRepository<Dt_Task> _taskRepository;
|
private IStockService _stockService;
|
private readonly IRepository<Dt_AllocateMaterialInfo> _allocateMaterialInfo;
|
private readonly HttpClientHelper _httpClientHelper;
|
private readonly IRepository<Dt_MesReturnRecord> _mesReturnRecord;
|
private readonly ILocationInfoService _locationInfoService;
|
private readonly IRepository<Dt_TakeStockOrder> _takeStockOrder;
|
public InboundService(IUnitOfWorkManage unitOfWorkManage, IInboundOrderDetailService inboundOrderDetailService, IInboundOrderService inbounOrderService, IRepository<Dt_InboundOrder> inboundOrderRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IRepository<Dt_LocationType> locationTypeRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IStockService stockService, IRepository<Dt_Task> taskRepository,IRepository<Dt_AllocateMaterialInfo> allocateMaterialInfo, HttpClientHelper httpClientHelper, IRepository<Dt_MesReturnRecord> mesReturnRecord,ILocationInfoService locationInfoService,IRepository<Dt_TakeStockOrder> takeStockOrder)
|
{
|
_unitOfWorkManage = unitOfWorkManage;
|
InboundOrderDetailService = inboundOrderDetailService;
|
InbounOrderService = inbounOrderService;
|
_inboundOrderRepository = inboundOrderRepository;
|
_warehouseAreaRepository = warehouseAreaRepository;
|
_locationTypeRepository = locationTypeRepository;
|
_stockInfoRepository = stockInfoRepository;
|
_inboundOrderDetailRepository = inboundOrderDetailRepository;
|
_stockService = stockService;
|
_taskRepository = taskRepository;
|
_allocateMaterialInfo = allocateMaterialInfo;
|
_httpClientHelper = httpClientHelper;
|
_mesReturnRecord = mesReturnRecord;
|
_locationInfoService = locationInfoService;
|
_takeStockOrder = takeStockOrder;
|
}
|
|
public async Task<WebResponseContent> GroupPallet(GroupPalletDto palletDto)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
(bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto);
|
if (!result2.Item1) return content.Error(result2.Item2);
|
|
var code = _warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>().Where(x => x.Code == palletDto.WarehouseType).Select(x => x.Code).First();
|
if (string.IsNullOrEmpty(code))
|
{
|
return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。");
|
}
|
|
Dt_InboundOrder inboundOrder = new Dt_InboundOrder();
|
|
var details = _inboundOrderDetailRepository.QueryData(x => (x.OutBoxbarcodes == palletDto.Barcode|| x.Barcode == palletDto.Barcode) && x.OrderDetailStatus == (int)InOrderStatusEnum.未开始);
|
|
if (details.Count() <= 0)
|
{
|
return content.Error("请确认是否已经组盘");
|
}
|
inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().Includes(x=>x.Details).Where(x => x.Id == details.First().OrderId).First();
|
|
if (inboundOrder == null)
|
{
|
return content.Error("未找到该条码主单信息");
|
}
|
if(inboundOrder.OrderStatus == (int)InOrderStatusEnum.手动关闭)
|
{
|
return content.Error("该单据的状态不能组盘");
|
}
|
var warehouse =_warehouseAreaRepository.QueryFirst(x => x.Code == palletDto.WarehouseType);
|
if(inboundOrder.BusinessType=="11" && inboundOrder.FactoryArea != warehouse.FactoryArea)
|
{
|
return content.Error($"当前厂区不一致");
|
}
|
|
if(inboundOrder.BusinessType != "11"&& inboundOrder.Details.FirstOrDefault().WarehouseCode != palletDto.WarehouseType)
|
{
|
return content.Error($"该条码所属仓库为{inboundOrder.Details.FirstOrDefault().WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘");
|
}
|
|
Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync();
|
|
List<string?> materielCodes = details.GroupBy(x => x.Barcode).Select(x => x.Key).ToList();
|
|
(bool, string, object?) result = CheckMaterielGroupParam(palletDto, materielCodes, inboundOrder, stockInfo);
|
if (!result.Item1) return content = WebResponseContent.Instance.Error(result.Item2);
|
|
|
if (stockInfo == null)
|
{
|
stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = Convert.ToInt32(palletDto.locationType) };
|
stockInfo.Details = new List<Dt_StockInfoDetail>();
|
}
|
|
if (inboundOrder.BusinessType != MESDocumentType.PurchaseInbound.ToString() && stockInfo != null && stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType)
|
{
|
return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘");
|
}
|
|
if (!_locationInfoService.QueryLocationCount(Convert.ToInt32(palletDto.locationType)))
|
{
|
return content.Error($"该库区{palletDto.locationType}不存在空闲库位");
|
}
|
|
foreach (var item in details)
|
{
|
var datevaliDate = _inboundOrderRepository.Db.Queryable<Dt_MaterialExpirationDate>().Where(x => x.MaterialCode.Contains(item.MaterielCode.Substring(0, 6))).First();
|
if (datevaliDate == null)
|
{
|
return content.Error($"该物料{item.MaterielCode}未找到MES推送的有效期数据,请先添加该物料的有效期再组盘入库");
|
}
|
stockInfo.Details.Add(new Dt_StockInfoDetail
|
{
|
StockId = stockInfo == null ? 0 : stockInfo.Id,
|
Barcode = item.Barcode,
|
MaterielCode = item.MaterielCode,
|
MaterielName = item.MaterielName,
|
BatchNo = item.BatchNo,
|
Unit = item.Unit,
|
InboundOrderRowNo = item.lineNo,
|
SupplyCode = item.SupplyCode,
|
WarehouseCode = palletDto.WarehouseType,
|
StockQuantity = item.OrderQuantity,
|
BarcodeQty = item.BarcodeQty,
|
BarcodeUnit = item.BarcodeUnit,
|
FactoryArea = inboundOrder.FactoryArea,
|
Status = 0,
|
OrderNo = inboundOrder.InboundOrderNo,
|
BusinessType = inboundOrder.BusinessType,
|
ValidDate = inboundOrder.BusinessType == BusinessTypeEnum.外部仓库调智仓.ToString() ? item.ValidDate : datevaliDate == null ? null : Convert.ToDateTime(DateTime.Now).AddDays(Convert.ToDouble(datevaliDate.ValidityDays)),
|
});
|
|
item.ReceiptQuantity = item.BarcodeQty;
|
item.OrderDetailStatus = (int)OrderDetailStatusEnum.GroupAndInbound;
|
item.WarehouseCode = palletDto.WarehouseType;
|
item.ReturnToMESStatus = 0;
|
}
|
|
if (stockInfo.Id == 0)
|
{
|
stockInfo.PalletCode = palletDto.PalletCode;
|
stockInfo.StockStatus = (int)StockStatusEmun.组盘暂存;
|
}
|
stockInfo.PalletType = (int)PalletTypeEnum.None;
|
|
List<int> updateDetailIds = details.Select(x => x.Id).ToList();
|
if (inboundOrder.OrderStatus == (int)InOrderStatusEnum.未开始)
|
{
|
inboundOrder.OrderStatus = (int)InOrderStatusEnum.入库中;
|
}
|
inboundOrder.Operator = App.User.UserName;
|
content = MaterielGroupUpdateData(inboundOrder, details, stockInfo).Result;
|
if (content.Status)
|
{
|
Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync();
|
|
return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id));
|
}
|
else
|
{
|
content = WebResponseContent.Instance.Error(content.Message);
|
}
|
}
|
catch (Exception ex)
|
{
|
LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}");
|
return content.Error(ex.Message);
|
}
|
return content;
|
}
|
|
public async Task<WebResponseContent> AllcatedGroupPallet(GroupPalletDto palletDto)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
(bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto);
|
if (!result2.Item1) return content.Error(result2.Item2);
|
|
var code = _warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>().Where(x => x.Code == palletDto.WarehouseType).Select(x => x.Code).First();
|
if (string.IsNullOrEmpty(code))
|
{
|
return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。");
|
}
|
|
Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync();
|
|
if (_taskRepository.QueryFirst(x => x.PalletCode == palletDto.PalletCode) != null)
|
{
|
return content.Error($"该托盘已生成任务");
|
}
|
if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存)
|
{
|
return content.Error("已上架的托盘不能再次组盘");
|
}
|
|
if (_stockService.StockInfoDetailService.ExistBarcodes(palletDto.Barcode))
|
{
|
return content.Error($"{palletDto.Barcode} 条码在库存中已存在");
|
}
|
|
if (stockInfo == null)
|
{
|
stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = Convert.ToInt32(palletDto.locationType) };
|
stockInfo.Details = new List<Dt_StockInfoDetail>();
|
}
|
|
if (stockInfo != null && stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType)
|
{
|
return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘");
|
}
|
Dt_AllocateMaterialInfo allocateMaterialInfo = _allocateMaterialInfo.QueryFirst(x => x.Barcode == palletDto.Barcode);
|
if(allocateMaterialInfo == null)
|
{
|
return content.Error($"未找到该条码{palletDto.Barcode}需调入智仓的信息");
|
}
|
|
stockInfo.Details.Add(new Dt_StockInfoDetail
|
{
|
StockId = stockInfo == null ? 0 : stockInfo.Id,
|
Barcode = allocateMaterialInfo.Barcode,
|
MaterielCode = allocateMaterialInfo.MaterialCode,
|
BatchNo = allocateMaterialInfo.BatchNo,
|
Unit = allocateMaterialInfo.Unit,
|
SupplyCode = allocateMaterialInfo.SupplyCode,
|
WarehouseCode = palletDto.WarehouseType,
|
StockQuantity = allocateMaterialInfo.Quantity,
|
BarcodeQty = allocateMaterialInfo.Quantity,
|
BarcodeUnit = allocateMaterialInfo.Unit,
|
FactoryArea = allocateMaterialInfo.FactoryArea,
|
Status = 0,
|
OrderNo = allocateMaterialInfo.OrderNo,
|
BusinessType = "1",
|
|
});
|
|
if (stockInfo.Id == 0)
|
{
|
stockInfo.PalletCode = palletDto.PalletCode;
|
stockInfo.StockStatus = (int)StockStatusEmun.智仓入智仓组盘暂存;
|
}
|
stockInfo.PalletType = (int)PalletTypeEnum.None;
|
_unitOfWorkManage.BeginTran();
|
_stockService.StockInfoService.AddMaterielGroup(stockInfo);
|
_unitOfWorkManage.CommitTran();
|
|
Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync();
|
|
return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id));
|
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}");
|
return content.Error(ex.Message);
|
}
|
}
|
|
/// <summary>
|
/// 验证组盘数据
|
/// </summary>
|
/// <param name="materielGroupDTO">物料组盘DTO</param>
|
/// <param name="matSerialNumberDTOs">扫码序列号</param>
|
/// <param name="materielInfos">物料信息</param>
|
/// <param name="materielCodes">物料编号</param>
|
/// <param name="inboundOrder">入库单据</param>
|
/// <param name="stockInfo">组盘信息</param>
|
/// <returns></returns>
|
public (bool, string, object?) CheckMaterielGroupParam(GroupPalletDto materielGroupDTO, List<string> barcodeCodes, Dt_InboundOrder inboundOrder, Dt_StockInfo stockInfo)
|
{
|
(bool, string, object?) result = ModelValidate.ValidateModelData(materielGroupDTO);
|
if (!result.Item1) return result;
|
|
if (_taskRepository.QueryFirst(x => x.PalletCode == materielGroupDTO.PalletCode) != null)
|
{
|
return (false, "该托盘号已有任务", materielGroupDTO);
|
}
|
|
if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存)
|
{
|
return (false, "已上架的托盘不能再次组盘", materielGroupDTO);
|
}
|
|
if (_stockService.StockInfoDetailService.ExistBarcodes(barcodeCodes))
|
{
|
return (false, $"{barcodeCodes[0]} 条码在库存中已存在", materielGroupDTO);
|
}
|
|
if (inboundOrder == null)
|
{
|
return (false, "单据不存在", materielGroupDTO);
|
}
|
|
if (inboundOrder.Details == null || inboundOrder.Details.Count == 0)
|
{
|
return (false, "无单据明细信息", materielGroupDTO);
|
}
|
|
if (inboundOrder.OrderStatus != (int)InOrderStatusEnum.未开始 && inboundOrder.OrderStatus != (int)InOrderStatusEnum.入库中)
|
{
|
return (false, "该单据不可再组盘", materielGroupDTO);
|
}
|
|
List<Dt_InboundOrderDetail> inboundOrderDetails = inboundOrder.Details.Where(x => barcodeCodes.Contains(x.Barcode)).ToList();
|
|
if (inboundOrderDetails.GroupBy(x => x.Barcode).Count() != barcodeCodes.Count)
|
{
|
return (false, "有物料不在单据内", materielGroupDTO);
|
}
|
|
return (true, "成功", materielGroupDTO);
|
}
|
|
public async Task<WebResponseContent> MaterielGroupUpdateData(Dt_InboundOrder inboundOrder, List<Dt_InboundOrderDetail> inboundOrderDetails, Dt_StockInfo stockInfo)
|
{
|
try
|
{
|
_unitOfWorkManage.BeginTran();
|
//await _inboundOrderRepository.Db.UpdateNav(inboundOrder).Include(x=>x.Details).ExecuteCommandAsync();
|
_inboundOrderRepository.UpdateData(inboundOrder);
|
_inboundOrderDetailRepository.UpdateData(inboundOrderDetails);
|
_stockService.StockInfoService.AddMaterielGroup(stockInfo);
|
_unitOfWorkManage.CommitTran();
|
return WebResponseContent.Instance.OK();
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
return WebResponseContent.Instance.Error(ex.Message);
|
}
|
}
|
|
public WebResponseContent BatchInOrderFeedbackToMes(int id)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
var inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>()
|
.Where(x => x.Id == id)
|
.First();
|
|
List<Dt_MesReturnRecord> returnRecords = _mesReturnRecord.QueryData(x => x.OrderNo == inboundOrder.InboundOrderNo && x.OrderId == inboundOrder.Id && x.ReturnStatus == 2);
|
foreach (var item in returnRecords)
|
{
|
HttpResponseResult<MesResponseDTO> httpResponse = _httpClientHelper.Post<MesResponseDTO>(item.ApiUrl, item.RequestData);
|
item.ReturnCount += 1;
|
bool success = httpResponse.IsSuccess && httpResponse.Data.Code == "200";
|
item.ReturnStatus = success ? 1 : 2;
|
item.HttpStatusCode = httpResponse.StatusCode.ObjToInt();
|
item.LastReturnTime = DateTime.Now;
|
item.ResponseData = httpResponse.Content;
|
item.SuccessTime = httpResponse.IsSuccess ? DateTime.Now : null;
|
|
//List<Dt_InboundOrderDetail> details=new List<Dt_InboundOrderDetail>();
|
//foreach (var y in item.DetailsId.Split(','))
|
//{
|
// details.Add( _inboundOrderDetailRepository.QueryFirst(x => x.Id == Convert.ToInt32(y)));
|
//}
|
}
|
_mesReturnRecord.UpdateData(returnRecords);
|
|
var inboundOrderDetail = _inboundOrderRepository.Db.Queryable<Dt_InboundOrderDetail>()
|
.Where(x => x.OrderId == inboundOrder.Id && x.OrderDetailStatus==(int)OrderDetailStatusEnum.Over && x.ReturnToMESStatus == 0)
|
.ToList();
|
|
var stocks = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.StockStatus == (int)StockStatusEmun.入库完成)
|
.Where(it => SqlFunc.Subqueryable<Dt_StockInfoDetail>().Where(s => s.StockId == it.Id && s.OrderNo == inboundOrder.InboundOrderNo).Any())
|
.ToList();
|
|
var stockIds = stocks.Select(s => s.Id).ToList();
|
|
var allDetailsData = _stockInfoRepository.Db.Queryable<Dt_StockInfoDetail>()
|
.Where(x => stockIds.Contains(x.StockId))
|
.ToList();
|
|
var matchedData = inboundOrderDetail
|
.Join(allDetailsData,
|
inbound => inbound.Barcode,
|
stockdetail => stockdetail.Barcode,
|
(inbound, stockdetail) => inbound.Barcode)
|
.ToList();
|
|
var inbounddetailID = inboundOrderDetail
|
.Join(allDetailsData,
|
inbound => inbound.Barcode,
|
stockdetail => stockdetail.Barcode,
|
(inbound, stockdetail) => inbound.Id)
|
.ToList();
|
|
var detail = allDetailsData.Where(x => matchedData.Contains(x.Barcode)).ToList();
|
|
if (inboundOrder.OrderType == (int)InOrderTypeEnum.AllocatInbound)//调拨入库
|
{
|
var allocate = _inboundOrderRepository.Db.Queryable<Dt_AllocateOrder>().Where(x => x.OrderNo == inboundOrder.InboundOrderNo).First();
|
var allocatefeedmodel = new AllocateDto
|
{
|
ReqCode = Guid.NewGuid().ToString(),
|
ReqTime = DateTime.Now.ToString(),
|
BusinessType = "3",
|
FactoryArea = inboundOrder.FactoryArea,
|
OperationType = 1,
|
Operator = inboundOrder.Operator,
|
OrderNo = inboundOrder.UpperOrderNo,
|
fromWarehouse = allocate?.FromWarehouse ?? "",
|
toWarehouse = allocate?.ToWarehouse ?? "",
|
Details = GetAllocateDtoDetails(detail)
|
};
|
|
if (allocatefeedmodel.Details.Count <= 0)
|
{
|
if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 1))
|
{
|
inboundOrder.ReturnToMESStatus = 1;
|
}
|
else if (returnRecords.Count(x => x.ReturnStatus == 2) > 0)
|
{
|
inboundOrder.ReturnToMESStatus = 4;
|
}
|
else if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 2))
|
{
|
inboundOrder.ReturnToMESStatus = 2;
|
}
|
_inboundOrderRepository.UpdateData(inboundOrder);
|
return WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条");
|
}
|
|
var response = responseModel(inboundOrder, 3, null, allocatefeedmodel);
|
|
if (response != null && response.IsSuccess)
|
{
|
_inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
|
.Where(it => it.OrderId == inboundOrder.Id && inbounddetailID.Contains(it.Id)).ExecuteCommand();
|
}
|
else
|
{
|
_inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
|
.Where(it => inbounddetailID.Contains(it.Id)).ExecuteCommand();
|
return content.Error("回传MES失败");
|
}
|
}
|
else
|
{
|
var feedmodel = new FeedbackInboundRequestModel
|
{
|
reqCode = Guid.NewGuid().ToString(),
|
reqTime = DateTime.Now.ToString(),
|
business_type = inboundOrder.BusinessType,
|
factoryArea = inboundOrder.FactoryArea,
|
operationType = 1,
|
Operator = inboundOrder.Operator,
|
orderNo = inboundOrder.UpperOrderNo,
|
status = inboundOrder.OrderStatus,
|
details = FeedbackInboundDetailsModelDto(detail)
|
};
|
|
if (feedmodel.details.Count<=0)
|
{
|
if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 1))
|
{
|
inboundOrder.ReturnToMESStatus = 1;
|
}
|
else if (returnRecords.Count(x => x.ReturnStatus == 2) > 0)
|
{
|
inboundOrder.ReturnToMESStatus = 4;
|
}
|
else if (returnRecords.Count() == returnRecords.Count(x => x.ReturnStatus == 2))
|
{
|
inboundOrder.ReturnToMESStatus = 2;
|
}
|
_inboundOrderRepository.UpdateData(inboundOrder);
|
return WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条");
|
}
|
var response = responseModel(inboundOrder, 3, feedmodel);
|
|
if (response != null && response.IsSuccess)
|
{
|
_inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
|
.Where(it => inbounddetailID.Contains(it.Id)).ExecuteCommand();
|
}
|
else
|
{
|
_inboundOrderRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
|
.Where(it => inbounddetailID.Contains(it.Id)).ExecuteCommand();
|
return content.Error("回传MES失败");
|
}
|
}
|
|
return content.OK("回传MES成功");
|
}
|
catch (Exception ex)
|
{
|
return content.Error(ex.Message);
|
}
|
}
|
|
public List<AllocateDtoDetail> GetAllocateDtoDetails(List<Dt_StockInfoDetail> stockInfoDetails)
|
{
|
var groupedData = stockInfoDetails.GroupBy(item => new { item.MaterielCode, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode })
|
.Select(group => new AllocateDtoDetail
|
{
|
MaterialCode = group.Key.MaterielCode,
|
LineNo = group.Key.InboundOrderRowNo,
|
WarehouseCode = group.Key.WarehouseCode,
|
Qty = group.Sum(x => x.BarcodeQty),
|
Unit = group.Key.BarcodeUnit,
|
Barcodes = group.Select(row => new BarcodeInfo
|
{
|
Barcode = row.Barcode,
|
Qty = row.BarcodeQty,
|
BatchNo = row.BatchNo,
|
SupplyCode = row.SupplyCode,
|
Unit = row.BarcodeUnit
|
}).ToList()
|
}).ToList();
|
return groupedData;
|
}
|
public List<FeedbackInboundDetailsModel> FeedbackInboundDetailsModelDto(List<Dt_StockInfoDetail> stockInfoDetails)
|
{
|
var groupedData = stockInfoDetails.GroupBy(item => new { item.MaterielCode, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode })
|
.Select(group => new FeedbackInboundDetailsModel
|
{
|
materialCode = group.Key.MaterielCode,
|
lineNo = group.Key.InboundOrderRowNo,
|
warehouseCode = group.Key.WarehouseCode,
|
qty = group.Sum(x => x.BarcodeQty),
|
unit = group.Key.BarcodeUnit,
|
barcodes = group.Select(row => new FeedbackBarcodesModel
|
{
|
barcode = row.Barcode,
|
qty = row.BarcodeQty
|
}).ToList()
|
}).ToList();
|
return groupedData;
|
}
|
|
public HttpResponseResult<MesResponseDTO> responseModel(Dt_InboundOrder order, int InterfaceType, FeedbackInboundRequestModel model = null, AllocateDto allocateDto = null)
|
{
|
HttpResponseResult<MesResponseDTO> httpResponseResult = new HttpResponseResult<MesResponseDTO>();
|
string reqCode = Guid.NewGuid().ToString();
|
string reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
string requestData = string.Empty;
|
string apiUrl = string.Empty;
|
if (model != null)
|
{
|
apiUrl = AppSettings.GetValue("AldMaterialWarehousing");
|
httpResponseResult = _httpClientHelper.Post<MesResponseDTO>(apiUrl, model.Serialize());
|
requestData = model.Serialize();
|
}
|
else
|
{
|
apiUrl = AppSettings.GetValue("AldAllocationOperation");
|
httpResponseResult = _httpClientHelper.Post<MesResponseDTO>(apiUrl, allocateDto.Serialize());
|
requestData = allocateDto.Serialize();
|
}
|
httpResponseResult.ApiUrl = apiUrl;
|
bool isSuccess = httpResponseResult.IsSuccess && httpResponseResult.Data.Code == "200";
|
string message = "成功";
|
if (!isSuccess)
|
{
|
if (!httpResponseResult.IsSuccess)
|
{
|
message = $"MES接口返回错误,HTTP代码:{httpResponseResult.StatusCode},信息:{httpResponseResult.ErrorMessage}";
|
}
|
else if (httpResponseResult?.Data?.Code != "200")
|
{
|
message = $"调用MES接口失败,代码:{httpResponseResult?.Data?.Code},信息:{httpResponseResult?.Data?.Message}";
|
}
|
}
|
Dt_MesReturnRecord mesReturnRecord = new Dt_MesReturnRecord()
|
{
|
ApiUrl = httpResponseResult.ApiUrl,
|
InterfaceType = InterfaceType,
|
OrderId = order.Id,
|
OrderNo = order.InboundOrderNo,
|
RequestCode = reqCode,
|
RequestData = requestData,
|
FailureReason = message,
|
LastReturnTime = DateTime.Now,
|
HttpStatusCode = httpResponseResult.StatusCode.ObjToInt(),
|
ResponseData = httpResponseResult.Content,
|
ReturnType = 0,
|
ReturnCount = 1,
|
ReturnStatus = httpResponseResult.IsSuccess ? 1 : 2,
|
SuccessTime = httpResponseResult.IsSuccess ? DateTime.Now : null
|
};
|
_unitOfWorkManage.Db.Insertable(mesReturnRecord).ExecuteCommand();
|
|
return httpResponseResult;
|
}
|
|
public async Task<WebResponseContent> StockTakeGroupPallet(GroupPalletDto palletDto)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
(bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto);
|
if (!result2.Item1) return content.Error(result2.Item2);
|
|
// 验证仓库编号是否存在
|
var code = _warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>()
|
.Where(x => x.Code == palletDto.WarehouseType)
|
.Select(x => x.Code)
|
.First();
|
if (string.IsNullOrEmpty(code))
|
{
|
return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。");
|
}
|
|
// 查询当前托盘的库存信息
|
Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>()
|
.Includes(x => x.Details)
|
.Where(x => x.PalletCode == palletDto.PalletCode)
|
.FirstAsync();
|
|
// 验证托盘是否已生成任务
|
if (_taskRepository.QueryFirst(x => x.PalletCode == palletDto.PalletCode) != null)
|
{
|
return content.Error($"该托盘已生成任务");
|
}
|
|
// 验证托盘是否已上架(已上架不能组盘)
|
if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存)
|
{
|
return content.Error("已上架的托盘不能再次组盘");
|
}
|
|
Dt_StockInfoDetail stockInfoDetail = _stockService.StockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
|
.Where(x => x.Barcode == palletDto.Barcode && x.StockId == 0)
|
.First();
|
if (stockInfoDetail == null)
|
{
|
return content.Error($"{palletDto.Barcode} 条码已关联其他托盘,无法组盘");
|
}
|
|
Dt_TakeStockOrder takeStockOrder = _takeStockOrder.Db.Queryable<Dt_TakeStockOrder>()
|
.Where(x => x.OrderNo == stockInfoDetail.OrderNo)
|
.First();
|
if (takeStockOrder == null)
|
{
|
return content.Error($"{palletDto.Barcode} 不属于盘点单据中的条码,不允许盘亏组盘");
|
}
|
if (stockInfo == null)
|
{
|
stockInfo = new Dt_StockInfo()
|
{
|
PalletType = (int)PalletTypeEnum.None,
|
LocationType = Convert.ToInt32(palletDto.locationType),
|
PalletCode = palletDto.PalletCode,
|
StockStatus = (int)StockStatusEmun.组盘暂存,
|
Details = new List<Dt_StockInfoDetail>()
|
};
|
}
|
|
if (stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType)
|
{
|
return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘");
|
}
|
|
_unitOfWorkManage.BeginTran();
|
|
try
|
{
|
if (stockInfo.Id == 0)
|
{
|
int newStockId = await _stockInfoRepository.Db.Insertable(stockInfo).ExecuteReturnIdentityAsync();
|
stockInfo.Id = newStockId;
|
}
|
|
stockInfoDetail.StockId = stockInfo.Id;
|
|
await _stockService.StockInfoDetailService.Db.Updateable(stockInfoDetail)
|
.Where(x => x.Id == stockInfoDetail.Id)
|
.ExecuteCommandAsync();
|
|
if (stockInfo.Id != 0 && stockInfo.Details != null && !stockInfo.Details.Contains(stockInfoDetail))
|
{
|
stockInfo.Details.Add(stockInfoDetail);
|
|
await _stockInfoRepository.Db.Updateable(stockInfo)
|
.IgnoreColumns(x => x.Details)
|
.ExecuteCommandAsync();
|
}
|
|
// 提交事务
|
_unitOfWorkManage.CommitTran();
|
}
|
catch (Exception)
|
{
|
// 事务回滚
|
_unitOfWorkManage.RollbackTran();
|
throw; // 抛给外层catch处理日志
|
}
|
|
// 查询最新的库存信息(包含关联的明细)
|
Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>()
|
.Includes(x => x.Details)
|
.Where(x => x.PalletCode == palletDto.PalletCode)
|
.FirstAsync();
|
|
return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id));
|
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}");
|
return content.Error(ex.Message);
|
}
|
}
|
|
public async Task<WebResponseContent> ReCheckGroupPallet(GroupPalletDto palletDto)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
(bool, string, object?) result2 = ModelValidate.ValidateModelData(palletDto);
|
if (!result2.Item1) return content.Error(result2.Item2);
|
|
var code = _warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>().Where(x => x.Code == palletDto.WarehouseType).Select(x => x.Code).First();
|
if (string.IsNullOrEmpty(code))
|
{
|
return content.Error($"仓库中没有该{palletDto.WarehouseType}编号。");
|
}
|
|
Dt_StockInfo? stockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync();
|
|
if (_taskRepository.QueryFirst(x => x.PalletCode == palletDto.PalletCode) != null)
|
{
|
return content.Error($"该托盘已生成任务");
|
}
|
if (stockInfo != null && !string.IsNullOrEmpty(stockInfo.LocationCode) && stockInfo.StockStatus != (int)StockStatusEmun.组盘暂存)
|
{
|
return content.Error("已上架的托盘不能再次组盘");
|
}
|
|
if (stockInfo == null)
|
{
|
stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = Convert.ToInt32(palletDto.locationType) };
|
stockInfo.Details = new List<Dt_StockInfoDetail>();
|
}
|
|
if (stockInfo != null && stockInfo.Details.Count > 0 && stockInfo.Details.FirstOrDefault()?.WarehouseCode != palletDto.WarehouseType)
|
{
|
return content.Error($"该托盘组盘仓库为{stockInfo.Details.FirstOrDefault()?.WarehouseCode}与当前仓库{palletDto.WarehouseType}不一致,不允许组盘");
|
}
|
Dt_StockInfoDetail stockInfoDetail = _stockInfoRepository.Db.Queryable<Dt_StockInfoDetail>().Where(x => x.Barcode == palletDto.Barcode && x.Status == StockStatusEmun.重检中.ObjToInt()).First();
|
if(stockInfoDetail == null)
|
{
|
return content.Error("未找到库存中重检冻结的条码");
|
}
|
Dt_ReCheckOrder reCheckOrder = _stockInfoRepository.Db.Queryable<Dt_ReCheckOrder>().Where(x => x.MaterielCode == stockInfoDetail.MaterielCode && x.BatchNo == stockInfoDetail.BatchNo && x.OrderNo == stockInfoDetail.OrderNo && (x.Result == 1 || x.Result == 2 )).First();
|
if(reCheckOrder == null)
|
{
|
return content.Error($"该重检条码的批次在重检单中未拿到重检结果,请检查重检单中物料{stockInfoDetail.MaterielCode}和{stockInfoDetail.BatchNo}物料批次状态");
|
}
|
|
int newStatus = reCheckOrder.Result == 1 ? StockStatusEmun.入库完成.ObjToInt(): StockStatusEmun.手动冻结.ObjToInt();
|
|
stockInfo.Details.Add(new Dt_StockInfoDetail
|
{
|
StockId = stockInfo == null ? 0 : stockInfo.Id,
|
Barcode = stockInfoDetail.Barcode,
|
MaterielCode = stockInfoDetail.MaterielCode,
|
MaterielName = stockInfoDetail.MaterielName,
|
BatchNo = stockInfoDetail.BatchNo,
|
Unit = stockInfoDetail.Unit,
|
SupplyCode = stockInfoDetail.SupplyCode,
|
WarehouseCode = stockInfoDetail.WarehouseCode,
|
StockQuantity = stockInfoDetail.StockQuantity,
|
BarcodeQty = stockInfoDetail.BarcodeQty,
|
BarcodeUnit = stockInfoDetail.BarcodeUnit,
|
FactoryArea = stockInfoDetail.FactoryArea,
|
Status = newStatus,
|
OrderNo = stockInfoDetail.OrderNo,
|
BusinessType = "30",
|
ValidDate = stockInfoDetail.ValidDate
|
});
|
_stockInfoRepository.Db.Deleteable<Dt_StockInfoDetail>().Where(x => x.Barcode == stockInfoDetail.Barcode).ExecuteCommand();
|
if (stockInfo.Id == 0)
|
{
|
stockInfo.PalletCode = palletDto.PalletCode;
|
stockInfo.StockStatus = (int)StockStatusEmun.送检库存完成;
|
}
|
stockInfo.PalletType = (int)PalletTypeEnum.None;
|
_unitOfWorkManage.BeginTran();
|
_stockService.StockInfoService.AddMaterielGroup(stockInfo);
|
_unitOfWorkManage.CommitTran();
|
|
Dt_StockInfo oldStockInfo = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.Id == stockInfoDetail.StockId).Includes(x=>x.Details).First();
|
if (oldStockInfo.Details.Count <= 0)
|
{
|
oldStockInfo.PalletType = (int)PalletTypeEnum.Empty;
|
}
|
_stockInfoRepository.UpdateData(oldStockInfo);
|
|
Dt_StockInfo? NewstockInfo = await _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == palletDto.PalletCode).FirstAsync();
|
|
return WebResponseContent.Instance.OK(data: NewstockInfo.Details.OrderByDescending(x => x.Id));
|
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
LogFactory.GetLog($"组盘信息").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}");
|
return content.Error(ex.Message);
|
}
|
}
|
}
|
}
|