using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Polly;
using Polly.Retry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using WmsWebApi.BackgroundJobs;
using WmsWebApi.EntityFrameworkCore;
using WmsWebApi.Enums;
using WmsWebApi.Jsons;
using WmsWebApi.Wms;
namespace WmsWebApi.ZlldcjLogs;
///
/// 领物料
///
[Route("/api/zlldcj")]
public class ZlldcjLogAppService : ApplicationService, IZlldcjLogAppService
{
private readonly ZlldcjLogManager _zlldcjLogManager;
private readonly ITbBillRepository _tbBillRepository;
private readonly ITmSapMoveTypeRepository _tbSapMoveTypeRepository;
private readonly ITmOtherAskRepository _tbOtherInOutAskRepository;
private readonly TmOtherAskRepositoryUpdate _tmOtherAskRepositoryUpdate;
private readonly Volo.Abp.Uow.IUnitOfWorkManager _unitOfWorkManager;
private readonly IBackgroundJobRequestRetry _backgroundJobRequestRetry;
private readonly IZlldcjLogJsonRepository _zlldcjLogJsonRepository;
private readonly AsyncRetryPolicy _asyncRetryPolicy;
///
/// 是否是请求重试
///
public bool IsRequestRetry { get; set; } = false;
public ZlldcjLogAppService(ZlldcjLogManager zlldcjLogManager
, ITbBillRepository tbBillRepository
, ITmSapMoveTypeRepository tbSapMoveTypeRepository
, ITmOtherAskRepository tbOtherInOutAskRepository
, TmOtherAskRepositoryUpdate tmOtherAskRepositoryUpdate
, Volo.Abp.Uow.IUnitOfWorkManager unitOfWorkManager,
IBackgroundJobRequestRetry backgroundJobRequestRetry,
IZlldcjLogJsonRepository zlldcjLogJsonRepository)
{
_zlldcjLogManager = zlldcjLogManager;
_tbBillRepository = tbBillRepository;
_tbSapMoveTypeRepository = tbSapMoveTypeRepository;
_tbOtherInOutAskRepository = tbOtherInOutAskRepository;
_tmOtherAskRepositoryUpdate = tmOtherAskRepositoryUpdate;
_unitOfWorkManager = unitOfWorkManager;
_backgroundJobRequestRetry = backgroundJobRequestRetry;
_zlldcjLogJsonRepository = zlldcjLogJsonRepository;
_asyncRetryPolicy = Policy.Handle()
.WaitAndRetryAsync(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(5)
}, (exception, timeSpan, retryCount, context) =>
{
Logger.LogInformation($"执行失败,第 {retryCount} 次重试");
});
}
[HttpPost("add")]
public async Task AddAsync(List dto)
{
var result = new ReturnResult();
List _ZlldcjLogs = new List();
foreach (var dtoItem in dto)
{
var entity = ObjectMapper.Map(dtoItem);
entity.SetId(GuidGenerator);
_ZlldcjLogs.Add(entity);
}
try
{
var ret = await _zlldcjLogManager.AddAsync(_ZlldcjLogs);
}
catch (Exception ex)
{
result.TYPE = 'E';
result.MESSAGE = ex.Message;
throw new Exception(ex.Message, ex);
}
return result;
}
[HttpPost("addObj")]
public async Task AddAsync([FromBody] object content)
{
var result = new ReturnResult();
List _ZlldcjLogs = new List();
List dtos;
bool bErr = false;
try
{
dtos = JsonConvert.DeserializeObject>(content.ToString());
}
catch (Exception ex)
{
result.TYPE = 'E';
result.MESSAGE = "Json格式不正确,详细信息:" + ex.GetBaseException().Message;
return result;
}
if (dtos == null || dtos.Count == 0)
{
bErr = true;
result.MESSAGE = "err:没有1000工厂数据";
return result;
}
WmsWebApiZLLDCJDTO zlldcjdto = new WmsWebApiZLLDCJDTO()
{
ZLLDJ = dtos[0].ZLLDJ,
ZDJLX = dtos[0].ZDJLX,
ZLTLX = dtos[0].ZLTLX,
JSON = content.ToString()
};
zlldcjdto.SetId(GuidGenerator);
try
{
var dtoList = dtos.Where(p => p.WERKS == "1000").ToList();
if (dtoList == null || dtoList.Count == 0)
{
bErr = true;
result.MESSAGE = "err:没有1000工厂数据";
}
else
{
foreach (var dtoItem in dtos)
{
var entity = ObjectMapper.Map(dtoItem);
entity.SetId(GuidGenerator);
_ZlldcjLogs.Add(entity);
}
var djList = _ZlldcjLogs.Select(p => p.ZLLDJ).Distinct();
foreach (var dj in djList)
{
var _zlldcjList = _ZlldcjLogs.Where(p => p.ZLLDJ == dj).ToList();
//检查是否为存在
var tbBill = await _tbBillRepository.FirstOrDefaultAsync(p => p.BillNum == dj);
if (tbBill != null)
{
result.TYPE = 'E';
bErr = true;
result.MESSAGE = $"{dj} 单据已存在";
break;
}
//TODO 创建 tbOrder
tbBill = new TB_BILL
{
BillNum = dj,
BillTime = DateTime.Now,
OperName = _zlldcjList[0].ERNAM,
DetailQty = _zlldcjList.Count,
BillType = 309,
State = 0
//...
};
//确定SubBillType
var sapMoveType = await _tbSapMoveTypeRepository.FirstOrDefaultAsync(p => p.SAPBillType == _zlldcjList[0].ZDJLX
&& p.GetOrBack == _zlldcjList[0].ZLTLX
&& p.MoveType == _zlldcjList[0].BWART);
var sapBillDesc = "";
if (sapMoveType != null)
{
tbBill.SubBillType = sapMoveType.SubBillType;
tbBill.Remark = sapMoveType.SAPBillDesc;
sapBillDesc = sapMoveType.SAPBillDesc;
List askList = new List();
foreach (var item in _zlldcjList)
{
var hasdetail = await _tbOtherInOutAskRepository.FirstOrDefaultAsync(p => p.BillNum == item.ZLLDJ && p.BillLineID == item.ZLLITEM.ToString());
if (hasdetail != null)
{
throw new UserFriendlyException($"单号 {item.ZLLDJ},行号 {item.ZLLITEM} 已存在!");
}
TM_PG_OTHER_INOUT_ASK ask = new TM_PG_OTHER_INOUT_ASK
{
BillNum = item.ZLLDJ,
BillLineID = item.ZLLITEM.ToString(),
BillType = item.ZDJLX,
BillTypeDesc = sapBillDesc,
GetOrBack = item.ZLTLX,
PartCode = item.MATNR,
Qty = item.BDMNG,
BUn = item.MEINS,
CostCenter = item.KOSTL,
BaseOrder = item.AUFNR,
MoveType = item.BWART,
OrderReason = item.GRUND.ToString(),
MoveReason = sapBillDesc,
Creator = item.ERNAM,
CreatDate = item.ERDAT + " " + item.ERZET,
Remark = item.ZBZSM,
RejecteQty = item.BKNUM,
PickLocation = item.LGORT1,
RejecteLocation = item.LGORT2,
ClaimLocation = item.LGORT3,
PickPerson = item.ZLLR
};
askList.Add(ask);
item.IType = "新增";
}
try
{
//新增本地单据
await _tbBillRepository.InsertAsync(tbBill, true);
await _tbOtherInOutAskRepository.InsertManyAsync(askList);
}
catch (Exception ex)
{
foreach (var item in _zlldcjList)
{
item.IType = ex.GetBaseException().Message;
}
throw;
}
finally
{
//新增日志记录
await AddZlldcjAsync(_zlldcjList);
}
}
else
{
foreach (var item in _zlldcjList)
{
item.IType = "WMS 不需要的接口";
}
//新增日志记录
await AddZlldcjAsync(_zlldcjList);
}
}
}
await CurrentUnitOfWork.SaveChangesAsync();
}
catch (UserFriendlyException ex)
{
bErr = true;
result.TYPE = 'E';
result.MESSAGE = ex.GetBaseException().Message;
}
catch (Exception ex)
{
bErr = true;
zlldcjdto.EnumRetryStatus = Enums.EnumRetryStatus.WaitRetry;
result.TYPE = 'E';
result.MESSAGE = ex.GetBaseException().Message;
if (IsRequestRetry == false)
{
try
{
await _asyncRetryPolicy.ExecuteAsync(async () => await _backgroundJobRequestRetry.AddBackgroundJobAsync(EnumActionName.ZlldcjLogAdd, content.ToString()));
}
catch (Exception)
{
throw new Exception("操作数据库失败,请稍后重试。", ex);
}
}
throw new Exception("操作数据库失败,稍后系统自动重试。", ex);
}
finally
{
if (IsRequestRetry == false)
{
Logger.LogInformation(zlldcjdto.JSON);
if (bErr)
{
zlldcjdto.ITYPE = result.MESSAGE;
}
try
{
await AddDtoAsync(zlldcjdto);
}
catch (Exception)
{
try
{
await _asyncRetryPolicy.ExecuteAsync(async () => await AddJsonNowUnitOfWorkAsync(zlldcjdto));
}
catch (Exception ex)
{
Logger.LogError("ZlldcjLog JSON记录失败");
Logger.LogError(zlldcjdto.JSON);
Logger.LogError(ex.Message);
}
}
}
}
return result;
}
private async Task AddDtoAsync(WmsWebApiZLLDCJDTO dto)
{
if (dto == null) { return; }
using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
await _zlldcjLogManager.AddDtoAsync(dto);
await uow.SaveChangesAsync();
}
}
private async Task AddJsonNowUnitOfWorkAsync(WmsWebApiZLLDCJDTO dto)
{
if (dto == null) { return; }
using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
await _zlldcjLogJsonRepository.InsertAsync(dto);
await uow.SaveChangesAsync();
}
}
private async Task AddZlldcjAsync(List dtos)
{
if (dtos == null || dtos.Count <= 0) { return; }
using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
await _zlldcjLogManager.AddZlldcjAsync(dtos);
await uow.SaveChangesAsync();
}
}
[HttpPost("close")]
//[UnitOfWork(false)]
public async Task CloseAsync([FromBody] object content)//ZlldcjLogDto dto
{
var result = new ReturnResult();
List dtos;
List _ZlldcjLogs = new List();
bool bErr = false;
try
{
dtos = JsonConvert.DeserializeObject>(content.ToString());
}
catch (Exception ex)
{
result.TYPE = 'E';
result.MESSAGE = "Json格式不正确,详细信息:" + ex.Message;
return result;
}
foreach (var dtoItem in dtos)
{
var entity = ObjectMapper.Map(dtoItem);
entity.SetId(GuidGenerator);
_ZlldcjLogs.Add(entity);
}
try
{
//var ret = await _zlldcjLogManager.CloseAsync(entity);
var tbBill = await _tbBillRepository.FirstOrDefaultAsync(p => p.BillNum == _ZlldcjLogs[0].ZLLDJ);
var tbOtherAskList = _tbOtherInOutAskRepository.Where(p => p.BillNum == _ZlldcjLogs[0].ZLLDJ);
//检查是否存在
if (tbBill == null)
{
bErr = true;
result.MESSAGE = $"{_ZlldcjLogs[0].ZLLDJ} 单据不存在";
}
else
{
//检查状态是否为开启
//tbBill.CheckStatusIsOpen();
if (tbBill.State == 9 || tbBill.State == 2 || tbBill.State == -1)
{
result.TYPE = 'E';
bErr = true;
result.MESSAGE = $"{_ZlldcjLogs[0].ZLLDJ} 单据已完成或已关闭";
}
else
{
bool bClose = true, bFind = false;
foreach (var item in tbOtherAskList)
{
if (_ZlldcjLogs.Find(p => p.ZLLITEM.ToString() == item.BillLineID.Trim()) != null)
{
bFind = true;
item.IsClosed = true;
await _tmOtherAskRepositoryUpdate.UpdateOtherAsk(item);
}
else
{
if (item.IsClosed == false)
bClose = false;
}
}
if (bClose)
{
tbBill.State = 9;
await _tmOtherAskRepositoryUpdate.UpdateBillState(tbBill);
}
//新增日志记录
var ret = await _zlldcjLogManager.CloseAsync(_ZlldcjLogs);
}
}
WmsWebApiZLLDCJDTO zlldcjdto = new WmsWebApiZLLDCJDTO()
{
ZLLDJ = dtos[0].ZLLDJ,
ZDJLX = dtos[0].ZDJLX,
ZLTLX = dtos[0].ZLTLX,
JSON = content.ToString(),
ITYPE = "关闭!"
};
zlldcjdto.SetId(GuidGenerator);
if (bErr)
{
zlldcjdto.ITYPE += result.MESSAGE;
}
await _zlldcjLogManager.AddDtoAsync(zlldcjdto);
await CurrentUnitOfWork.SaveChangesAsync();
}
catch (Exception ex)
{
result.TYPE = 'E';
result.MESSAGE = ex.Message;
throw new Exception($"接口异常,请稍后重试:{ex.GetBaseException().Message}", ex);
}
return result;
}
}