using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; using Volo.Abp.Uow; using WmsWebApi.Domain; using WmsWebApi.EntityFrameworkCore; using WmsWebApi.StockMove; using WmsWebApi.Wms; namespace WmsWebApi.StockMove; /// /// Agv出入库 /// [Route("/api/ss")] public class StockMoveService : ApplicationService, IStockMoveService { private readonly ITsStockDetailRepository _tsStockDetailRepository; private readonly ITbStockMoveRepository _tbStockMoveRepository; private readonly ITbBillRepository _tbBillRepository; private readonly ITLTransactionRepository _tlTransactionRepository; private readonly IStockMoveManager _stockMoveManager; private readonly TmPgWmsUpdate _tmPgWmsUpdate; private readonly ITaPartRepository _taPartRepository; private readonly ITaStoreLocationRepository _taStoreLocationRepository; private readonly IConfiguration _configuration; private readonly Volo.Abp.Uow.IUnitOfWorkManager _unitOfWorkManager; public StockMoveService(ITsStockDetailRepository tsStockDetailRepository, ITbStockMoveRepository tbStockMoveRepository, ITbBillRepository tbBillRepository, ITaPartRepository taPartRepository, ITaStoreLocationRepository taStoreLocationRepository, ITLTransactionRepository tlTransactionRepository, IStockMoveManager stockMoveManager, TmPgWmsUpdate tmPgWmsUpdate, IConfiguration configuration, IUnitOfWorkManager unitOfWorkManager) { _tsStockDetailRepository = tsStockDetailRepository; _tbStockMoveRepository = tbStockMoveRepository; _tbBillRepository = tbBillRepository; _taPartRepository = taPartRepository; _taStoreLocationRepository = taStoreLocationRepository; _tlTransactionRepository = tlTransactionRepository; _stockMoveManager = stockMoveManager; _tmPgWmsUpdate = tmPgWmsUpdate; _configuration = configuration; _unitOfWorkManager = unitOfWorkManager; } [HttpPost("add")] public async Task AddAsync([FromBody] object content) { var result = new ReturnResult(); SSDto _SSDto; //bool bUpdate = false,bOtherWork = false, bDel = false,bNotFind = false, bPartGroup = false; bool bErr = false; try { _SSDto = JsonConvert.DeserializeObject(content.ToString()); } catch (Exception ex) { result.TYPE = 'E'; result.MESSAGE = "Json格式不正确,详细信息:" + ex.Message; return result; } WmsWebApiStockMoveDTO apiSSdto = new WmsWebApiStockMoveDTO() { AccountDate = _SSDto.AccountDate, BillType = _SSDto.BillType, ReceiveDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), GUID = _SSDto.GUID, OperName = _SSDto.OperName, BillTime = _SSDto.BillTime, SourceBillNum = _SSDto.SourceBillNum, JSON = content.ToString() }; apiSSdto.SetId(GuidGenerator); try { List _billList = new List(); List _stockMoveList = new List(); List _stockList = new List(); List _stockUpdateList = new List(); List _stockDelList = new List(); List _transList = new List(); #region 添加BILL var tbBill = new TB_BILL { BillNum = "AGVM." + DateTime.Now.ToString("yyyyMMddHHmmss"), SourceBillNum2 = _SSDto.SourceBillNum, BillTime = DateTime.Now, StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), FinishTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), OperName = _SSDto.OperName, DetailQty = _SSDto.items.Count, BillType = 302, SubBillType = 30201, State = 2, Remark = "AGVMove" }; try { tbBill.AccountDate = DateTime.ParseExact(_SSDto.AccountDate, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture); } catch (Exception) { tbBill.AccountDate = DateTime.Parse(_SSDto.AccountDate); } _billList.Add(tbBill); #endregion var agvloc = _configuration.GetConnectionString("AgvInLoc"); var wmsloc = _configuration.GetConnectionString("AgvOutLoc"); foreach (var item in _SSDto.items) { //判断物料信息 var part = await _taPartRepository.FirstOrDefaultAsync(p => p.PartCode == item.PartCode); if (part == null) { //result.TYPE = 'E'; bErr = true; result.MESSAGE += $"err:物料 {item.PartCode} 不在WinWMS管理!"; continue; } if (string.IsNullOrEmpty(part.DefaultReceiveLocCode)) { bErr = true; result.MESSAGE += $"err:物料 {item.PartCode} 未设置收货库位!"; continue; } var partLoc = await _taStoreLocationRepository.FirstOrDefaultAsync(p => p.LocCode == part.DefaultReceiveLocCode); if (partLoc == null) { bErr = true; result.MESSAGE += $"err:物料 {item.PartCode} 的默认收货库位未配置ERP库位!"; continue; } var _barcode = $"{item.PartCode}_{item.Batch}"; #region StockMove //插入StockMove var tbStockMove = new TB_STOCK_MOVE { BillNum = tbBill.BillNum, BarCode = _barcode, PartCode = item.PartCode, FromBatch = item.Batch, ToBatch = item.Batch, //FromLocCode = "", //ToLocCode = part.DefaultReceiveLocCode, Remark = part.QLevel, Qty = item.Qty, FromState = EnumStockState.合格, ToState = EnumStockState.合格 }; if (_SSDto.BillType == "902")//从WMS移库到AGV { tbStockMove.FromLocCode = wmsloc; tbStockMove.ToLocCode = agvloc; } else if (_SSDto.BillType == "903") { tbStockMove.FromLocCode = agvloc; tbStockMove.ToLocCode = wmsloc; } _stockMoveList.Add(tbStockMove); #endregion #region StockDetail //插入ts_stock_detail var tsStock = new TS_STOCK_DETAIL { BarCode = _barcode, PartCode = item.PartCode, Batch = item.Batch, EqptCode = "", //LocCode = part.DefaultReceiveLocCode, AreaCode = partLoc.AreaCode,//"FG", Qty = item.Qty, UpdateQty = item.Qty, VendId = "", ProduceDate = DateTime.Now, OverdueDate = (DateTime.Now).AddDays(part.ValidityDays), ReceiveDate = DateTime.Now, VendBatch = item.Batch, Remark = "", State = EnumStockState.合格, Amount = 0, VinState = 0, }; var stockagv = await _tsStockDetailRepository.FirstOrDefaultAsync(p => p.BarCode == _barcode && p.LocCode == agvloc && p.State == EnumStockState.合格); var stockwms = await _tsStockDetailRepository.FirstOrDefaultAsync(p => p.BarCode == _barcode && p.LocCode == wmsloc && p.State == EnumStockState.合格); if (_SSDto.BillType == "902")//AGV库位增加库存,WMS库位减少库存 { #region 出库 tsStock.LocCode = wmsloc; if (stockwms == null || stockwms.Qty - item.Qty < 0) { bErr = true; result.MESSAGE = $"err:物料 {item.PartCode} 批次 {item.Batch} 的WMS库存不足!"; break; } else if (stockwms.Qty - item.Qty == 0) { _stockDelList.Add(tsStock); } else { tsStock.Qty = 0 - tsStock.Qty; tsStock.UpdateQty = tsStock.Qty; _stockUpdateList.Add(tsStock); } #endregion #region 入库 tsStock.LocCode = agvloc; if (stockagv == null) { _stockList.Add(tsStock); } else { _stockUpdateList.Add(tsStock); } #endregion } else//WMS库位增加库存 { #region 出库 tsStock.LocCode = agvloc; if (stockagv == null || stockagv.Qty - item.Qty < 0) { bErr = true; result.MESSAGE = $"err:物料 {item.PartCode} 批次 {item.Batch} 的AGV库存不足!"; break; } else if (stockagv.Qty - item.Qty == 0) { _stockDelList.Add(tsStock); } else { tsStock.Qty = 0 - tsStock.Qty; tsStock.UpdateQty = tsStock.Qty; _stockUpdateList.Add(tsStock); } #endregion #region 入库 tsStock.LocCode = wmsloc; if (stockwms == null) { _stockList.Add(tsStock); } else { _stockUpdateList.Add(tsStock); } #endregion } #endregion #region TranSaction if (_SSDto.BillType == "902") { var tlTrans1 = new TL_TRANSACTION { OperName = "AGV", LogTime = DateTime.Now, BillNum = tbBill.BillNum, BillType = tbBill.BillType, SubBillType = tbBill.SubBillType, PartCode = item.PartCode, Batch = item.Batch, Qty = item.Qty, BarCode = _barcode, LocCode = agvloc, EqptCode = "", Remark = "In", State = 2, TransType = 1 }; var tlTrans2 = new TL_TRANSACTION { OperName = "AGV", LogTime = DateTime.Now, BillNum = tbBill.BillNum, BillType = tbBill.BillType, SubBillType = tbBill.SubBillType, PartCode = item.PartCode, Batch = item.Batch, Qty = 0 - item.Qty, BarCode = _barcode, LocCode = wmsloc, EqptCode = "", Remark = "Out", State = 2, TransType = 0 }; _transList.Add(tlTrans1); _transList.Add(tlTrans2); } else { var tlTrans1 = new TL_TRANSACTION { OperName = "AGV", LogTime = DateTime.Now, BillNum = tbBill.BillNum, BillType = tbBill.BillType, SubBillType = tbBill.SubBillType, PartCode = item.PartCode, Batch = item.Batch, Qty = item.Qty, BarCode = _barcode, LocCode = wmsloc, EqptCode = "", Remark = "In", State = 2, TransType = 1 }; var tlTrans2 = new TL_TRANSACTION { OperName = "AGV", LogTime = DateTime.Now, BillNum = tbBill.BillNum, BillType = tbBill.BillType, SubBillType = tbBill.SubBillType, PartCode = item.PartCode, Batch = item.Batch, Qty = 0 - item.Qty, BarCode = _barcode, LocCode = agvloc, EqptCode = "", Remark = "Out", State = 2, TransType = 0 }; _transList.Add(tlTrans1); _transList.Add(tlTrans2); } #endregion } if (!bErr) { if (_stockMoveList.Count > 0) { await _tbBillRepository.AddManyAsync(_billList); await _tbStockMoveRepository.AddAsync(_stockMoveList); } if (_stockList != null && _stockList.Count() > 0) await _tsStockDetailRepository.AddAsync(_stockList); if (_stockUpdateList != null && _stockUpdateList.Count() > 0) await _tmPgWmsUpdate.UpdateTsStock(_stockUpdateList); if (_stockDelList != null && _stockDelList.Count() > 0) await _tmPgWmsUpdate.DeleteTsStock(_stockDelList); await _tlTransactionRepository.AddAsync(_transList); } } catch (Exception ex) { bErr = true; apiSSdto.EnumRetryStatus = Enums.EnumRetryStatus.WaitRetry; result.TYPE = 'E'; result.MESSAGE = ex.Message; throw new Exception($"接口异常,请稍后重试:{ex.GetBaseException().Message}", ex); } finally { if (bErr) { result.TYPE = 'E'; apiSSdto.ITYPE = result.MESSAGE; } await AddWmsWebApiStockMoveDTONowUnitOfWorkAsync(apiSSdto); } return result; } private async Task AddWmsWebApiStockMoveDTONowUnitOfWorkAsync(WmsWebApiStockMoveDTO wmsWebApiStockMoveDTO) { if (wmsWebApiStockMoveDTO == null) { return; } using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false)) { await _stockMoveManager.AddAsync(wmsWebApiStockMoveDTO); await uow.SaveChangesAsync(); } } }