using AutoMapper;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Npoi.Mapper;
using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using WMS.Web.Core.Dto;
using WMS.Web.Core.Dto.ChangeBoxRecord;
using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Dto.Erp.Org;
using WMS.Web.Core.Dto.InStock;
using WMS.Web.Core.Dto.InStockTask;
using WMS.Web.Core.Dto.Inventory;
using WMS.Web.Core.Dto.Login;
using WMS.Web.Core.Internal.Results;
using WMS.Web.Domain.Entitys;
using WMS.Web.Domain.Infrastructure;
using WMS.Web.Domain.IService;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Mappers;
using WMS.Web.Domain.Options;
using WMS.Web.Domain.Values;
using WMS.Web.Domain.Values.Erp;
namespace WMS.Web.Domain.Services
{
///
/// 入库单服务
///
public class InStockService : IInStockService
{
private readonly IMapper _mapper;
private readonly IErpService _erpService;
private readonly ILoginService _loginService;
private readonly ISerialNumberService _serialNumberService;
private readonly ISerialNumbersRepositories _serialNumbersRepositories;
private readonly IInStockTaskBoxRepositories _inStockTaskBoxRepositories;
private readonly IChangeMoveBoxService _changeMoveBoxService;
private readonly IBoxRepositories _boxRepositories;
private readonly IBoxInventoryService _boxInventoryService;
private readonly IBasicsRepositories _basicsRepositories;
private readonly IInStockRepositories _inStockRepositories;
private readonly IInStockTaskRepositories _inStockTaskRepositories;
private readonly IErpBasicDataExtendService _erpBasicDataExtendService;
private readonly IBoxInventoryRepositories _boxInventoryRepositories;
private readonly ILogger _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly AppOptions _options;
private ConnectionMultiplexer redisMultiplexer;
public StackExchange.Redis.IDatabase _redisDb = null;
public InStockService(IMapper mapper, IOptions options, ISerialNumbersRepositories serialNumbersRepositories, IErpService erpService, IBoxInventoryService boxInventoryService, ISerialNumberService serialNumberService, ILoginService loginService, IBoxRepositories boxRepositories,
IBasicsRepositories basicsRepositories, IErpBasicDataExtendService erpBasicDataExtendService, IChangeMoveBoxService changeMoveBoxService, IInStockTaskBoxRepositories inStockTaskBoxRepositories,
IInStockRepositories inStockRepositories, IInStockTaskRepositories inStockTaskRepositories, IBoxInventoryRepositories boxInventoryRepositories, ILogger logger, IServiceScopeFactory serviceScopeFactory)
{
_logger = logger;
_mapper = mapper;
_erpService = erpService;
_loginService = loginService;
_serviceScopeFactory = serviceScopeFactory;
_boxInventoryService = boxInventoryService;
_serialNumberService = serialNumberService;
_boxRepositories = boxRepositories;
_changeMoveBoxService = changeMoveBoxService;
_basicsRepositories = basicsRepositories;
_inStockRepositories = inStockRepositories;
_inStockTaskBoxRepositories = inStockTaskBoxRepositories;
_inStockTaskRepositories = inStockTaskRepositories;
_erpBasicDataExtendService = erpBasicDataExtendService;
_serialNumbersRepositories = serialNumbersRepositories;
_boxInventoryRepositories = boxInventoryRepositories;
_options = options?.Value;
redisMultiplexer = ConnectionMultiplexer.Connect(_options.RedisConnectionString);
_redisDb = redisMultiplexer.GetDatabase();
}
///
/// 同步-金蝶
///
///
///
///
public Task Sync(OperateRequest dto, LoginInDto loginInfo, bool isRepeatSync = true)
{
var list = _inStockRepositories.GetList(dto.Ids).GetAwaiter().GetResult();
var isSuccess = true;
if (isRepeatSync)
{
list = list.Where(w => w.SuccessSync == SyncStatus.Fail || w.SuccessSync == SyncStatus.SyncIng).ToList();
list.ForEach(f => f.RepeatSync());
isSuccess = _inStockRepositories.UpdateRange(list, true).GetAwaiter().GetResult();
}
Task.Run(async () =>
{
foreach (var entity in list)
{
var res = await this.PurchaseInStock(entity, loginInfo);
if (!res.IsSuccess)
_logger.LogError($"入库单同步失败:{res.Message}");
}
});
return Task.FromResult(Result.ReSuccess());
}
///
/// 收货
///
///
///
///
public async Task Receive(UpdateInStockTaskRequest dto, LoginInDto loginInfo)
{
// 构建 Redis 锁的键名
string lockKey = $"lock:taskidreceive{dto.Id}";
// 构建 Redis 锁的值,用于标识锁的持有者
string lockValue = Guid.NewGuid().ToString();
// 获取 Redis 锁,设置超时时间为 10 秒
if (await _redisDb.LockTakeAsync(lockKey, lockValue, TimeSpan.FromSeconds(10)))
{
try
{
IDbContextTransaction _transaction = _basicsRepositories.GetTransaction();
bool isRollback = false;
bool isTransaction = false;
var result = await this.Receive(dto, loginInfo.UserInfo.StaffId, isTransaction);
if (!result.IsSuccess) isRollback = true;
//提交事务
var isSuccess = _basicsRepositories.CommitTransaction(isRollback, _transaction);
if (!isSuccess)
return result;
return Result.ReSuccess();
}
finally
{
// 释放 Redis 锁
await _redisDb.LockReleaseAsync(lockKey, lockValue);
}
}
else
{
return Result.ReFailure(ResultCodes.Concurrent_Instock);
}
}
///
/// 上架-采购订单
///
///
///
///
public async Task Shelf(PurchaseShelfRequest instock, LoginInDto loginInfo)
{
var taskId = instock.Details.Select(x => x.TaskId).FirstOrDefault();
// 构建 Redis 锁的键名
string lockKey = $"lock:taskidshelf{taskId}";
// 构建 Redis 锁的值,用于标识锁的持有者
string lockValue = Guid.NewGuid().ToString();
// 获取 Redis 锁,设置超时时间为 10 秒
if (await _redisDb.LockTakeAsync(lockKey, lockValue, TimeSpan.FromSeconds(10)))
{
try
{
IDbContextTransaction _transaction = _basicsRepositories.GetTransaction();
bool isRollback = false;
bool isTransaction = false;
//1.添加入库单:(同步金蝶在save方法里面进行)
var save_result = await this.ShelfSave(instock, InstockType.Purchase, loginInfo, isTransaction);
if (!save_result.IsSuccess) isRollback = true;
//实体
var entity = save_result.Data;
//提交事务
var isSuccess = _basicsRepositories.CommitTransaction(isRollback, _transaction);
if (!isSuccess)
return save_result;
//同步金蝶
if (entity.Type == InstockType.Purchase)
{
OperateRequest oRequest = new OperateRequest();
oRequest.Ids.Add(entity.Id);
await Sync(oRequest, loginInfo, false);
}
return Result.ReSuccess();
}
finally
{
// 释放 Redis 锁
await _redisDb.LockReleaseAsync(lockKey, lockValue);
}
}
else
{
return Result.ReFailure(ResultCodes.Concurrent_Instock);
}
}
///
/// 非采购单上架
///
///
///
///
public async Task ShelfNoPurchase(NoPurchaseShelfRequest dto, LoginInDto loginInDto)
{
// 构建 Redis 锁的键名
string lockKey = $"lock:taskidshelfnopurchase{dto.TaskId}";
// 构建 Redis 锁的值,用于标识锁的持有者
string lockValue = Guid.NewGuid().ToString();
// 获取 Redis 锁,设置超时时间为 10 秒
if (await _redisDb.LockTakeAsync(lockKey, lockValue, TimeSpan.FromSeconds(10)))
{
try
{
_logger.LogInformation($"非采购入库:{JsonConvert.SerializeObject(dto)} 操作人:{loginInDto.UserInfo.StaffId + loginInDto.UserInfo.Nickname}");
IDbContextTransaction _transaction = _basicsRepositories.GetTransaction();
bool isRollback = false;
bool isTransaction = false;
//保存非采购上架的数据
var shelfSave_result = await this.ShelfNoPurchaseSave(dto, loginInDto, isTransaction);
if (!shelfSave_result.IsSuccess) isRollback = true;
//提交事务
var isSuccess = _basicsRepositories.CommitTransaction(isRollback, _transaction);
if (!isSuccess)
return shelfSave_result;
return Result.ReSuccess();
}
finally
{
// 释放 Redis 锁
await _redisDb.LockReleaseAsync(lockKey, lockValue);
}
}
else
{
return Result.ReFailure(ResultCodes.Concurrent_Instock);
}
}
///
/// 获取任务单:根据箱号信息
///
///
///
public async Task> GetInfoByBox(BoxInStockTaskRequest dto)
{
//1.1.找到箱对应的物料信息
var box = await _boxRepositories.GetByNo(dto.BoxBillNo);
if (box == null)
return Result.ReFailure(ResultCodes.BoxNoData);
//判断箱不存在所选的物料
var isAnyHave = box.Details.Any(x => x.MaterialNumber == dto.MaterialNumber);
if (!isAnyHave)
return Result.ReFailure(ResultCodes.Contrast_Purchase_Count_Error);
//return Result.ReFailure(box.BoxBillNo + ResultCodes.BoxNoMaterialError.Item2, ResultCodes.BoxNoMaterialError.Item1);
//1.获取物料集合
var materials_result = await _erpService.BillQueryForMaterial();
var materials = new List();
if (materials_result.IsSuccess)
materials = materials_result.Data.ToList();
//1.先判断:箱号已经绑定了入库任务单中;备注:业务说法就是箱是否收货了
var ishave_tast_box = await _inStockTaskBoxRepositories.GetBy(dto.BoxBillNo);
if (ishave_tast_box == null)
return Result.ReFailure(ResultCodes.Box_No_Task_Data);
//1.先判断:箱号已经绑定了入库任务单中;备注:其它单据收的提示
var tast_box = await _inStockTaskBoxRepositories.GetBy(dto.BoxBillNo, dto.TaskId);
if (tast_box == null)
return Result.ReFailure(ResultCodes.Box_NoBind_Task_Data);
//2.1判断箱是否上架过了
var isExist = await _boxInventoryRepositories.IsExist(box.Id);
if (isExist)
return Result.ReFailure(ResultCodes.BoxIsTrueShelf);
//1.2找到任务单
var tast = await _inStockTaskRepositories.Get(tast_box.TaskId);
if (tast == null)
return Result.ReFailure(ResultCodes.InStockTaskNoData);
//1.2.1判断箱子绑定的物料明细数据的仓库,是不是用户所选的仓库;不是则提示:箱号仓库不对
foreach (var item in tast_box.Details)
{
var tast_det = tast.Details.Where(t => t.ErpDetailId == item.ErpDetailId).FirstOrDefault();
if (tast_det != null && tast_det.StockCode != dto.StockCode)
return Result.ReFailure(ResultCodes.BoxBindTaskDetailsIdNotChoose);
}
//3.组装返回数据
var result = new BoxInStockTaskDto();
result.SourceBillNo = tast.SourceBillNo;
result.TaskId = tast.Id;
result.BoxId = box.Id;
//获取:当前箱的与收货绑定的信息
foreach (var item in tast_box.Details)
{
var current_task_det = tast.Details.Where(x => x.ErpDetailId == item.ErpDetailId).FirstOrDefault();
if (current_task_det != null)
{
//3.2映射返回明细对象
var box_task_detail = new BoxDetailsInStockTaskDto();
box_task_detail.SupplierId = current_task_det.SupplierId;
box_task_detail.OrgId = current_task_det.OrgId;
box_task_detail.ReceiveQty = current_task_det.ReceiveQty;
box_task_detail.AccruedQty = current_task_det.AccruedQty;
box_task_detail.ErpDetailId = item.ErpDetailId;
box_task_detail.BoxMaterialQty = item.ReceiveQty;
box_task_detail.MaterialName = _erpBasicDataExtendService.GetMaterialName(materials, item.MaterialNumber);
box_task_detail.MaterialNumber = item.MaterialNumber;
box_task_detail.Specifications = _erpBasicDataExtendService.GetMaterialSpecifications(materials, item.MaterialNumber);
result.Details.Add(box_task_detail);
}
}
return Result.ReSuccess(result);
}
///
/// 采购上架-保存
///
///
///
///
///
private async Task> ShelfSave(PurchaseShelfRequest dto, InstockType type, LoginInDto loginInfo, bool isTransaction = true)
{
_logger.LogInformation($"采购上架-保存:{JsonConvert.SerializeObject(dto)} 操作人:{loginInfo.UserInfo.StaffId}");
//入库的时候:不能扫同样的箱
if (dto.Details != null && dto.Details.Count != 0)
{
var mIds = dto.Details.GroupBy(g => g.MaterialNumber).Select(s => s.Key).ToList();
foreach (var m in mIds)
{
var d_boxIds = dto.Details.Where(w => w.MaterialNumber == m).Select(s => s.BoxId);
if (d_boxIds.Distinct().Count() != d_boxIds.Count())
return Result.ReFailure(ResultCodes.BoxOutStockTaskBoxError);
}
}
var all_boxIds = dto.Details.Select(s => s.BoxId).ToList();
//2.1判断箱是否上架过了
var boxInventoryList = await _boxInventoryRepositories.GetList(all_boxIds);
foreach (var bid in all_boxIds)
{
var boxInventory = boxInventoryList.FirstOrDefault(f => f.BoxId == bid);
if (boxInventory != null)
{
var box = await _boxRepositories.Get(bid);
if (box == null) return Result.ReFailure(ResultCodes.BoxIsTrueShelf);
return Result.ReFailure($"{box.BoxBillNo} 箱号已上架入库", 80000);
}
}
//1.获取物料集合和组织集合和供应商的集合
var materials = new List();
var materials_result = await _erpService.BillQueryForMaterial();
if (materials_result.IsSuccess)
materials = materials_result.Data.ToList();
//1.获取来源单
var taskIds = dto.Details.GroupBy(x => x.TaskId).Select(x => x.Key).ToList();
var tasks = await _inStockTaskRepositories.GetList(taskIds);
if (tasks == null || tasks.Count == 0)
return Result.ReFailure(ResultCodes.SourceBillNoDateError);
// 组织集合
var orgs = new List();
var orgs_result = await _erpService.BillQueryForOrg();
if (orgs_result.IsSuccess)
orgs = orgs_result.Data.ToList();
var currentOrg = orgs.Where(x => x.Number == dto.OrgCode).FirstOrDefault();
var entity = new InStock();
entity.Type = type;
entity.OrgId = currentOrg == null ? 0 : currentOrg.Id;
entity.StockCode = dto.StockCode;
entity.OrgCode = dto.OrgCode;
entity.SubStockCode = dto.SubStockCode;
entity.Method = InventoryInOutMethod.Box;
entity.Details = _mapper.Map>(dto.Details);
entity.Create(loginInfo.UserInfo.StaffId);
//组装:erp明细
entity.ErpDetails = dto.Details.GroupBy(x => new { x.ErpDetailId, x.MaterialNumber, x.SourceBillNo })
.Select(x => new InStockErpDetails
{
ErpDetailId = x.Key.ErpDetailId,
MaterialNumber = x.Key.MaterialNumber,
SourceBillNo = x.Key.SourceBillNo,
Qty = x.Sum(t => t.Qty)
}).ToList();
//1.获取最新的erp明细信息
var billNo_new = await _inStockRepositories.GetLastBillNo();
//erp明细:生成批号
int new_firstBillNo = billNo_new == null ? 0 : (billNo_new.FirstBillNo.HasValue ? billNo_new.FirstBillNo.Value : 0);
int new_lastBillNo = billNo_new == null ? 0 : (billNo_new.LastBillNo.HasValue ? billNo_new.LastBillNo.Value : 0);
entity.ErpDetails.ForEach(x =>
{
//物料必须是启动了批号管理才生成批号
var mat = materials.Where(m => m.MaterialNumber == x.MaterialNumber && m.OrgCode == entity.OrgCode && m.IsBatchManage == true).FirstOrDefault();
if (mat != null)
{
x.GenerateBatchBillNo(new_firstBillNo, new_lastBillNo, mat.IsBatchManage);
new_firstBillNo = x.FirstBillNo ?? 0;
new_lastBillNo = x.LastBillNo ?? 0;
}
});
//序列号集:箱里面的
var serialNumbers = await _serialNumbersRepositories.GetEntityListByBoxIds(dto.Details.GroupBy(x => x.BoxId).Select(x => x.Key).ToList());
//赋值序列号
entity.Details.ForEach(x =>
{
var current_box_serNums = serialNumbers.Where(t => t.BoxId == x.BoxId).ToList();
if (current_box_serNums != null)
{
var current_box_mat_serNums = current_box_serNums.Where(t => t.MaterialNumber == x.MaterialNumber).Select(t => t.SerialNumber).ToList();
x.SerialNumbers.AddRange(current_box_mat_serNums);
}
});
entity = await _inStockRepositories.Add(entity, isTransaction);
if (entity == null)
return Result.ReFailure(ResultCodes.DateWriteError);
//处理添加入库汇总明细
var totalDetails = dto.Details.GroupBy(x => new { x.TaskId, x.SourceBillNo, x.SupplierId, x.MaterialNumber })
.Select(x => new InStockTotalDetails
{
InStockId = entity.Id,
TaskId = x.Key.TaskId,
SourceBillNo = x.Key.SourceBillNo,
SupplierId = x.Key.SupplierId,
MaterialNumber = x.Key.MaterialNumber,
Qty = x.Sum(t => t.Qty),
SerialNumbers = x.SelectMany(t => t.SerialNumbers).ToList()
}).ToList();
var isSuccess = await _inStockRepositories.AddRangeTotalDetails(totalDetails, isTransaction);
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
//反写任务单的已交数量
if (tasks != null && tasks.Count != 0)
{
foreach (var task in tasks)
{
task.Details.ForEach(x =>
{
var current_entityDets = dto.Details.Where(t => t.ErpDetailId == x.ErpDetailId && t.MaterialNumber == x.MaterialNumber).ToList();
if (current_entityDets != null && current_entityDets.Count != 0 && x.ErpDetailId == current_entityDets.FirstOrDefault().ErpDetailId)
{
var current_entityDet_matQty = current_entityDets.Sum(x => x.Qty);
x.RealityQty = x.RealityQty + current_entityDet_matQty;
}
});
task.Shelf(loginInfo.UserInfo.StaffId);
}
isSuccess = await _inStockTaskRepositories.UpdateRange(tasks, isTransaction);
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
}
//保存成功后:序列号跟踪流程添加
var serialNumber_result = await _serialNumberService.InStock(entity, loginInfo, isTransaction);
if (!serialNumber_result.IsSuccess)
return Result.ReFailure(serialNumber_result);
//箱库存变动
var boxInventoryResult = await _boxInventoryService.GenerateInStockBox(entity, isTransaction);
if (!boxInventoryResult.IsSuccess)
return Result.ReFailure(boxInventoryResult);
return Result.ReSuccess(entity);
}
///
/// 非采购上架-保存
///
///
///
///
///
private async Task ShelfNoPurchaseSave(NoPurchaseShelfRequest dto, LoginInDto loginInfo, bool isTransaction = true)
{
_logger.LogInformation($"非采购上架-保存:{JsonConvert.SerializeObject(dto)} 操作人:{loginInfo.UserInfo.StaffId}");
//非采购入库的时候:不能扫同样的箱,按箱入库时候
if (dto.Boxs != null && dto.Boxs.Count != 0 && dto.ShelfMethod == (int)ShelfMethod.Box)
{
if (dto.Boxs.Select(x => x.BoxId).Distinct().Count() != dto.Boxs.Select(x => x.BoxId).Count())
return Result.ReFailure(ResultCodes.BoxOutStockTaskBoxError);
}
//1.1过滤的明细:0数量入库的明细要过滤掉
dto.Boxs.ForEach(x =>
{
x.Details.RemoveAll(t => t.Qty == 0);
});
var all_boxIds = dto.Boxs.Select(s => s.BoxId).ToList();
//2.1判断箱是否上架过了 按箱出货才判断
if (dto.ShelfMethod == 1)
{
var boxInventoryList = await _boxInventoryRepositories.GetList(all_boxIds);
foreach (var b in dto.Boxs)
{
var boxInventory = boxInventoryList.FirstOrDefault(f => f.BoxId == b.BoxId);
if (boxInventory != null)
{
return Result.ReFailure($"{b.BoxBillNo} 箱号已上架入库", 80000);
}
}
}
//1.获取来源单
var task = await _inStockTaskRepositories.Get(dto.TaskId);
if (task == null)
return Result.ReFailure(ResultCodes.SourceBillNoDateError);
//1.1.2判断上架数量不能超过应入库数量
var dtoDetails = dto.Boxs.SelectMany(x => x.Details).ToList();
var dtoTotalDetails = dtoDetails.GroupBy(x => new { x.ErpDetailId, x.MaterialNumber }).Select(x => new { ErpDetailId = x.Key.ErpDetailId, MaterialNumber = x.Key.MaterialNumber, Qty = x.Sum(t => t.Qty) }).ToList();
foreach (var item in task.Details)
{
var current_det = dtoTotalDetails.Where(x => x.ErpDetailId == item.ErpDetailId && x.MaterialNumber == item.MaterialNumber).FirstOrDefault();
if (current_det != null && current_det.ErpDetailId == item.ErpDetailId && (item.AccruedQty - item.RealityQty) < current_det.Qty)
return Result.ReFailure(ResultCodes.ShelfNoPurchaseSave_Qty_Error);
}
//2.生成:入库单
var entity = new InStock();
entity.Type = task.Type;
entity.OrgId = task.Details.Select(x => x.OrgId).FirstOrDefault();
entity.StockCode = dto.StockCode;
entity.OrgCode = dto.OrgCode;
entity.SubStockCode = dto.SubStockCode;
entity.Method = dto.ShelfMethod == (int)ShelfMethod.Box ? InventoryInOutMethod.Box : InventoryInOutMethod.Product;
entity.Details = new List();
var temps = new List();
//3.遍历:box信息,并拼装入库单明细
foreach (var box in dto.Boxs)
{
//3.1先数据映射
var dets = _mapper.Map>(box.Details);
//3.2遍历赋值:boxID和仓库和仓位和来源单和供应商和组织
dets.ForEach(item =>
{
item.TaskId = dto.TaskId;
item.SourceBillNo = task.SourceBillNo;
item.BoxId = box.BoxId;
});
//3.3添加到临时集合中
temps.AddRange(dets);
}
//3.4给对象明细赋值
entity.Details = temps;
//4.创建
entity.Create(loginInfo.UserInfo.StaffId);
//序列号集:箱里面的
var serialNumbers = await _serialNumbersRepositories.GetEntityListByBoxIds(dto.Boxs.GroupBy(x => x.BoxId).Select(x => x.Key).ToList());
if (dto.ShelfMethod == (int)ShelfMethod.Box)
{
//赋值序列号
entity.Details.ForEach(x =>
{
var current_box_serNums = serialNumbers.Where(t => t.BoxId == x.BoxId).ToList();
if (current_box_serNums != null)
{
var current_box_mat_serNums = current_box_serNums.Where(t => t.MaterialNumber == x.MaterialNumber).Select(t => t.SerialNumber).ToList();
x.SerialNumbers.AddRange(current_box_mat_serNums);
}
if (x.TwoSerialNumbers != null)
{
x.SerialNumbers.AddRange(x.TwoSerialNumbers);
}
});
}
//5.1保存入库单信息
entity = await _inStockRepositories.Add(entity, isTransaction);
if (entity == null)
return Result.ReFailure(ResultCodes.DateWriteError);
//处理添加入库汇总明细
var totalDetails = dto.Boxs.SelectMany(x => x.Details).GroupBy(x => new { x.MaterialNumber })
.Select(x => new InStockTotalDetails
{
InStockId = entity.Id,
TaskId = dto.TaskId,
SourceBillNo = task.SourceBillNo,
MaterialNumber = x.Key.MaterialNumber,
Qty = x.Sum(t => t.Qty),
SerialNumbers = x.SelectMany(t => t.SerialNumbers).ToList(),
TwoSerialNumbers = x.SelectMany(t => t.TwoSerialNumbers).ToList()
}).ToList();
var isSuccess = await _inStockRepositories.AddRangeTotalDetails(totalDetails, isTransaction);
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
//反写:任务单的已交数量
if (task != null)
{
task.Details.ForEach(x =>
{
var current_entityDets = entity.Details.Where(t => t.ErpDetailId == x.ErpDetailId && t.MaterialNumber == x.MaterialNumber).ToList();
if (current_entityDets != null && current_entityDets.Count != 0 && x.ErpDetailId == current_entityDets.FirstOrDefault().ErpDetailId)
{
var current_entityDet_matQty = current_entityDets.Sum(x => x.Qty);
x.ReceiveQty = x.ReceiveQty + current_entityDet_matQty;
x.DeliveredQty = x.DeliveredQty + current_entityDet_matQty;
x.RealityQty = x.RealityQty + current_entityDet_matQty;
}
});
task.NoPurchaseShelf(loginInfo.UserInfo.StaffId);
task = await _inStockTaskRepositories.Update(task, isTransaction);
if (task == null)
return Result.ReFailure(ResultCodes.DateWriteError);
}
//6.1序列号跟踪流程添加;备注:和上面的改箱操作后会记录序列号轨迹不冲突;
var serialNumber_result = await _serialNumberService.InStock(entity, loginInfo, isTransaction);
if (!serialNumber_result.IsSuccess)
return serialNumber_result;
//箱库存变动
var boxInventoryResult = await _boxInventoryService.GenerateInStockBox(entity, isTransaction);
if (!boxInventoryResult.IsSuccess)
return boxInventoryResult;
return Result.ReSuccess();
}
///
/// 修改-入库任务信息
///
///
///
///
///
///
public async Task> Receive(UpdateInStockTaskRequest dto, int staffId, bool isTransaction)
{
_logger.LogInformation($"收货:{JsonConvert.SerializeObject(dto)} 操作人:{staffId}");
//收货的时候:不能扫同样的箱
if (dto.Boxs != null && dto.Boxs.Count != 0)
{
if (dto.Boxs.Select(x => x.BoxId).Distinct().Count() != dto.Boxs.Select(x => x.BoxId).Count())
return Result.ReFailure(ResultCodes.BoxOutStockTaskBoxError);
}
//1.修改任务单的数据
var entity = await _inStockTaskRepositories.Get(dto.Id);
if (entity == null)
return Result.ReFailure(ResultCodes.DateWriteError);
entity = _mapper.Map(dto, entity);
entity.Receive(staffId);
//子集单独映射
entity.Details.ForEach(x =>
{
//当前明细收货的明细:可以通过erp明细ID获取唯一一个;并变更收货数量
var current_dto_det = dto.Details.Where(t => t.ErpDetailId == x.ErpDetailId).FirstOrDefault();
if (current_dto_det != null && x.ErpDetailId == current_dto_det.ErpDetailId && x.MaterialNumber == current_dto_det.MaterialNumber)
x.ReceiveQty = x.ReceiveQty + current_dto_det.ReceiveQty;
});
//2.修改箱和任务单的绑定关系,先判断箱没有被收货过
var dto_boxIds = dto.Boxs.GroupBy(x => x.BoxId).Select(x => x.Key).ToList();
var taskBoxList = await _inStockTaskBoxRepositories.GetListBy(dto_boxIds);
if (taskBoxList != null && taskBoxList.Count != 0)
return Result.ReFailure(ResultCodes.InStockTaskBoxIsHaveData);
//序列号
var serialNumbs = await _serialNumbersRepositories.GetEntityListByBoxIds(dto_boxIds);
//3.组装绑定关系表,要添加的集合
var boxEntitys = await _boxRepositories.GetEntityList(dto_boxIds);
var taskBoxAdd = new List();
foreach (var item in dto.Boxs)
{
var taskBox = _mapper.Map(item);
taskBox.TaskId = entity.Id;
taskBox.Receiver(staffId);
var currentBox_serialNumbs = serialNumbs.Where(s => s.BoxId == taskBox.BoxId).ToList();
var current_dto_box_dets = boxEntitys.Where(x => x.Id == item.BoxId).SelectMany(x => x.Details).ToList();
taskBox.Details = _mapper.Map>(current_dto_box_dets);
taskBox.Details.ForEach(x =>
{
x.ErpDetailId = item.ErpDetailId;
x.SerialNumbers = currentBox_serialNumbs.Where(s => s.MaterialNumber == x.MaterialNumber).Select(s => s.SerialNumber).ToList();
});
taskBoxAdd.Add(taskBox);
}
var isSuccess = await _inStockTaskBoxRepositories.AddRange(taskBoxAdd, isTransaction);
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
//数据库操作
var result = await _inStockTaskRepositories.Update(entity, isTransaction);
if (result == null)
return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess(entity);
}
///
/// 批量修改-入库任务信息
///
///
///
///
///
///
public async Task UpdateRange(List ids, int staffId, bool isReceive, bool isTransaction = true)
{
var entitys = await _inStockTaskRepositories.GetList(ids);
if (entitys == null || entitys.Count == 0)
return Result.ReFailure(ResultCodes.DateWriteError);
foreach (var item in entitys)
{
if (isReceive)
item.Receive(staffId);
else
item.Shelf(staffId);
}
var isSuccess = await _inStockTaskRepositories.UpdateRange(entitys, isTransaction);
if (isSuccess)
return Result.ReSuccess();
else
return Result.ReFailure(ResultCodes.DateWriteError);
}
///
/// 采购订单物料明细和箱物料明细-对比
///
///
///
public async Task> Contrast(ContrastMaterialsRequest dto)
{
_logger.LogInformation($"采购订单明细和箱物料明细-对比:{JsonConvert.SerializeObject(dto)}");
//1.找到任务单的明细信息
var task = await _inStockTaskRepositories.Get(dto.TaskId);
if (task == null)
return Result.ReFailure(ResultCodes.OrderNoData);
//1.1筛选出对应仓库的明细
var task_details = task.Details.Where(x => x.StockCode == dto.StockCode && x.AccruedQty > 0).ToList();
//2.找到箱对应的物料信息:多个箱
var boxs = await _boxRepositories.GetEntityListByNos(dto.BoxBillNos);
if (boxs == null || boxs.Count == 0)
return Result.ReFailure(ResultCodes.BoxNoData);
//只有采购入库-是选择了物料明细
if (dto.IsPurchase)
{
//判断箱不存在所选的物料
foreach (var item in boxs)
{
var isAnyHave = item.Details.Any(x => x.MaterialNumber == dto.MaterialNumber);
if (!isAnyHave)
return Result.ReFailure(ResultCodes.Contrast_Purchase_Count_Error);
//return Result.ReFailure(item.BoxBillNo + ResultCodes.BoxNoMaterialError.Item2, ResultCodes.BoxNoMaterialError.Item1);
}
}
//3.判断箱里面对应的物料是否存在;不存在就报错
foreach (var item in boxs)
{
if (item.Details == null || item.Details.Count == 0)
return Result.ReFailure(ResultCodes.BoxMateriaNoData);
}
//判断箱是否存在库存:有的话就提示“箱号已上架入库”
var boxInventory = await _boxInventoryRepositories.GetList(boxs.Select(x => x.Id).ToList());
if (boxInventory != null && boxInventory.Count != 0)
return Result.ReFailure(ResultCodes.BoxInventoryHaveInventoryError);
//合并多个箱明细的数据:相同物料数量合并
var boxDetails = boxs.SelectMany(x => x.Details).GroupBy(x => x.MaterialNumber).Select(x => new { MaterialNumber = x.Key, Qty = x.Sum(t => t.Qty) }).ToList();
//采购单:要对比数量
if (task.Type == InstockType.Purchase)
{
//3.比对:false为比对失败;
bool isRight = boxDetails.All(x => task_details.Any(t => t.MaterialNumber == x.MaterialNumber && t.AccruedQty >= x.Qty)) && boxDetails.Count <= task_details.Count;
if (!isRight)
{
var qtyIsError = boxDetails.All(x => task_details.Any(t => t.MaterialNumber == x.MaterialNumber && t.AccruedQty < x.Qty));
if (boxDetails.Count > task_details.Count && qtyIsError)
return Result.ReFailure(ResultCodes.Contrast_Purchase_Error);
else if (qtyIsError)
return Result.ReFailure(ResultCodes.Contrast_Qty_Error);
else
return Result.ReFailure(ResultCodes.Contrast_Purchase_Count_Error);
}
}
//非采购单:不要对比数量,只对比物料
else
{
//3.比对:false为比对失败;
bool isRight = boxDetails.All(x => task_details.Any(t => t.MaterialNumber == x.MaterialNumber)) && boxDetails.Count <= task_details.Count;
if (!isRight)
return Result.ReFailure(ResultCodes.Contrast_Count_Error);
}
//4.是否任务单存在绑定箱号判断:存在的话,就不能收货或者非采购上架
var taskBoxList = await _inStockTaskBoxRepositories.GetListBy(dto.BoxBillNos);
if (taskBoxList != null && taskBoxList.Count != 0)
return Result.ReFailure(ResultCodes.BoxHaveError);
//4.返回对比结果:true为比对成功,并把箱ID和箱号返回
var response = new ContrastMaterialsResponse();
foreach (var box in boxs)
{
var r_box = new ContrastBoxResponse();
r_box.BoxBillNo = box.BoxBillNo;
r_box.BoxId = box.Id;
r_box.TotalCount = box.Details.Sum(x => x.Qty);
r_box.Details = _mapper.Map>(box.Details);
response.Boxs.Add(r_box);
}
return Result.ReSuccess(response);
}
///
/// 采购:同步金蝶
///
///
///
///
private async Task PurchaseInStock(InStock entity, LoginInDto loginInfo)
{
_logger.LogInformation($"采购下推-同步:{JsonConvert.SerializeObject(entity)} 操作人:{loginInfo.UserInfo.StaffId}");
var scope = _serviceScopeFactory.CreateScope();
var sc_InStockRepositories = scope.ServiceProvider.GetRequiredService();
if (entity.Type != InstockType.Purchase) return Result.ReSuccess();
if (entity.SuccessSync == SyncStatus.Success) return Result.ReSuccess();
var erpDetails_tags = entity.ErpDetails.Where(w => w.SuccessSync == SyncStatus.SyncIng).ToList();
//要下推的明细
var erpDetails = new List();
var sc_erpService = scope.ServiceProvider.GetRequiredService();
var sc_inStockRepositories = scope.ServiceProvider.GetRequiredService();
//找到金蝶最新的采购订单数据
var erp_purchase_result = await sc_erpService.BillQueryForPurchaseInStock(entity.ErpDetails.GroupBy(x => x.SourceBillNo).Select(x => x.Key).ToList());
if (!erp_purchase_result.IsSuccess)
return erp_purchase_result;
//然后刷选出对应金蝶明细和物料和wms的任务单的明细和物料是一致的就同步下推
foreach (var item in erpDetails_tags)
{
var isHave = erp_purchase_result.Data.Where(x => x.ErpDetailId == item.ErpDetailId && x.MaterialNumber == item.MaterialNumber).Any();
if (isHave)
erpDetails.Add(item);
}
var sourceBillNos = entity.ErpDetails.GroupBy(x => x.SourceBillNo).Select(x => x.Key).ToList();
var erp_InStockErpDetails = await sc_inStockRepositories.GetErpDetails(sourceBillNos);
foreach (var det in erpDetails)
{
var erpDto = new ErpPushDto()
{
RuleId = "PUR_PurchaseOrder-STK_InStock",//转换规则内码 采购订单下推采购入库单
FormId = FormIdParam.PUR_PurchaseOrder.ToString(),
TargetFormId = FormIdParam.STK_InStock.ToString(),
DetailsId = det.ErpDetailId.ToString(),
IsDraftWhenSaveFail = true//是否需要暂存
};
var erp_InStockBillNos = erp_InStockErpDetails.Where(x => x.SourceBillNo == det.SourceBillNo).Select(x => x.ErpSyncBillNo).ToList();
List details = new List();
var resPurchaseInStockDetails_result = await sc_erpService.BillQueryForPurchaseInStockBy(det.ErpDetailId.ToString(), erp_InStockBillNos);
if (resPurchaseInStockDetails_result.IsSuccess)
details = resPurchaseInStockDetails_result.Data;
//金蝶已有的单;进行金蝶不同操作处理:保存,提交,审核
ErpPurchaseInStockDetailsDto currentDet = null;
if (det.ErpInStockDetailId.HasValue)
currentDet = details.Where(x => x.DetailId == det.ErpInStockDetailId.Value.ToString()).FirstOrDefault();
if (currentDet != null)
{
var res = await this.QueryFirst(currentDet, erpDto.TargetFormId, entity.BillNo, det, sc_erpService);
if (res.result.IsSuccess)
entity.SyncSuccess(det.ErpDetailId, loginInfo?.UserInfo?.StaffId ?? 0, res.erpBillNo);
else
entity.SyncFail(res.result.Message, det.ErpDetailId, loginInfo?.UserInfo?.StaffId ?? 0, res.syncStatus);
//记录金蝶入库单明细ID
det.RecodErpInStockDetailId(res.instockDetailId);
}
else
{
//下推金蝶
var res = await this.Push(erpDto, det, entity.BillNo, sc_erpService, sc_inStockRepositories);
if (res.result.IsSuccess)
entity.SyncSuccess(det.ErpDetailId, loginInfo?.UserInfo?.StaffId ?? 0, res.erpBillNo);
else
entity.SyncFail(res.result.Message, det.ErpDetailId, loginInfo?.UserInfo?.StaffId ?? 0, res.syncStatus);
//记录金蝶入库单明细ID
det.RecodErpInStockDetailId(res.instockDetailId);
}
}
//最好一条一条执行,否则执行失败 但是金蝶那边又同步成功 就会造成数据比价乱
var isSuccess = await sc_InStockRepositories.Update(entity, true);
if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
///
/// 下推
///
///
///
///
///
private async Task<(Result result, SyncStatus syncStatus, string erpBillNo, string instockDetailId)> Push(ErpPushDto dto, InStockErpDetails erpDetail, string billNo, IErpService sc_erpService, IInStockRepositories sc_inStockRepositories)
{
var erp_instock_detId = string.Empty;
try
{
_logger.LogInformation($"入库单->开始下推 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 数据: {JsonConvert.SerializeObject(dto)}");
//下推动作
var res = await sc_erpService.Push(dto);
if (!res.IsSuccess)
{
_logger.LogInformation($"入库单->下推失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{res.Message}");
return (Result.ReFailure(res.Message, res.Status), SyncStatus.Fail, "", null);
}
string id = res.Data;
var resPurchaseInStock = await sc_erpService.BillQueryForPurchaseInStock(id);
var purchaseInStock = resPurchaseInStock.Data;
purchaseInStock.Details[0].Qty = erpDetail.Qty;
string formId = dto.TargetFormId.ToString();
erp_instock_detId = purchaseInStock.Details[0].DetailId;
//批号生成和同步
if (string.IsNullOrEmpty(erpDetail.BatchBillNo))
{
var current_erp_material = await sc_erpService.BillQueryForMaterialByNumber(erpDetail.MaterialNumber);
if (current_erp_material != null && current_erp_material.IsBatchManage == true)
{
//1.获取最新的erp明细信息
var billNo_new = await sc_inStockRepositories.GetLastBillNo();
//erp明细:最新批号
int new_firstBillNo = billNo_new == null ? 0 : (billNo_new.FirstBillNo.HasValue ? billNo_new.FirstBillNo.Value : 0);
int new_lastBillNo = billNo_new == null ? 0 : (billNo_new.LastBillNo.HasValue ? billNo_new.LastBillNo.Value : 0);
//生成批号
erpDetail.GenerateBatchBillNo(new_firstBillNo, new_lastBillNo, current_erp_material.IsBatchManage);
//赋值批号
if (!string.IsNullOrEmpty(erpDetail.BatchBillNo))
{
purchaseInStock.Details[0].Lot = new ErpLotSaveDto();
purchaseInStock.Details[0].Lot.Number = erpDetail.BatchBillNo;
}
}
}
else
{
purchaseInStock.Details[0].Lot = new ErpLotSaveDto();
purchaseInStock.Details[0].Lot.Number = erpDetail.BatchBillNo;
}
//保存
_logger.LogInformation($"入库单->下推成功 开始保存 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 数据: {JsonConvert.SerializeObject(purchaseInStock)}");
var res_s = await sc_erpService.Save(purchaseInStock, formId);
if (!res_s.IsSuccess)
{
_logger.LogInformation($"入库单->保存失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{res_s.Message}");
return (Result.ReFailure(res_s.Message, res_s.Status), SyncStatus.SubmitFail, "", purchaseInStock.Details[0].DetailId);
}
//提交
_logger.LogInformation($"入库单->保存成功 开始提交 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
ErpOperateDto o_dto = new ErpOperateDto(formId, res_s.Data);//res_s.Data
var resSubmit = await sc_erpService.Submit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->提交失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.SubmitFail, o_dto.Numbers.First(), purchaseInStock.Details[0].DetailId);
}
//审核
_logger.LogInformation($"入库单->提交成功 开始审核 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
resSubmit = await sc_erpService.Audit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->审核失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.CheckFail, o_dto.Numbers.First(), purchaseInStock.Details[0].DetailId);
}
_logger.LogInformation($"入库单->同步金蝶成功->单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
return (Result.ReSuccess(), SyncStatus.Success, o_dto.Numbers.First(), purchaseInStock.Details[0].DetailId);
}
catch (Exception ex)
{
_logger.LogInformation($"入库单-同步:错误:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{ex.Message}");
var result = Result.ReFailure(ex.Message, 50001);
return (result, SyncStatus.Fail, "", erp_instock_detId);
}
}
///
/// 金蝶已有的入库单进行不同处理:保存、提交、审核
///
///
///
///
///
///
///
private async Task<(Result result, SyncStatus syncStatus, string erpBillNo, string instockDetailId)> QueryFirst(ErpPurchaseInStockDetailsDto currentDet, string formId, string billNo, InStockErpDetails erpDetail, IErpService sc_erpService)
{
var erp_instock_detId = string.Empty;
try
{
var purchaseInstock = new ErpPurchaseInStockSaveDto(currentDet.OrderId);
var det = new ErpPurchaseInStockDetailsSaveDto();
det.DetailId = currentDet.DetailId;
det.Qty = currentDet.Qty;
purchaseInstock.Details.Add(det);
erp_instock_detId = det.DetailId;
ErpOperateDto o_dto = new ErpOperateDto(formId, currentDet.OrderBillNo);//res_s.Data
if (currentDet.DocumentStatus == ErpOrderStatus.Z.ToString())
{
//保存
_logger.LogInformation($"入库单->查询到已有暂存的入库单 开始保存 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 数据: {JsonConvert.SerializeObject(purchaseInstock)}");
var res_s = await sc_erpService.Save(purchaseInstock, formId);
if (!res_s.IsSuccess)
{
_logger.LogInformation($"入库单->保存失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{res_s.Message}");
return (Result.ReFailure(res_s.Message, res_s.Status), SyncStatus.SubmitFail, currentDet.OrderId, det.DetailId);
}
//提交
_logger.LogInformation($"入库单->保存成功 开始提交 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
var resSubmit = await sc_erpService.Submit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->提交失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.SubmitFail, o_dto.Numbers.First(), det.DetailId);
}
//审核
_logger.LogInformation($"入库单->提交成功 开始审核 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
resSubmit = await sc_erpService.Audit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->审核失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.CheckFail, o_dto.Numbers.First(), det.DetailId);
}
}
else if (currentDet.DocumentStatus == ErpOrderStatus.A.ToString())
{
//提交
_logger.LogInformation($"入库单->查询到已有保存的入库单 开始提交 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
var resSubmit = await sc_erpService.Submit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->提交失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.SubmitFail, o_dto.Numbers.First(), det.DetailId);
}
//审核
_logger.LogInformation($"入库单->提交成功 开始审核 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
resSubmit = await sc_erpService.Audit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->审核失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.CheckFail, o_dto.Numbers.First(), det.DetailId);
}
}
else if (currentDet.DocumentStatus == ErpOrderStatus.B.ToString())
{
//审核
_logger.LogInformation($"入库单->查询到已有提交的入库单 开始审核 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
var resSubmit = await sc_erpService.Audit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->审核失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.CheckFail, o_dto.Numbers.First(), det.DetailId);
}
}
else if (currentDet.DocumentStatus == ErpOrderStatus.D.ToString())
{
//提交
_logger.LogInformation($"入库单->查询到已有重新审核的入库单 开始提交 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
var resSubmit = await sc_erpService.Submit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->提交失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.SubmitFail, o_dto.Numbers.First(), det.DetailId);
}
//审核
_logger.LogInformation($"入库单->提交成功 开始审核 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
resSubmit = await sc_erpService.Audit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->审核失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.CheckFail, o_dto.Numbers.First(), det.DetailId);
}
}
else if (currentDet.DocumentStatus == ErpOrderStatus.C.ToString())
{
_logger.LogInformation($"入库单->存在已审核的ERP入库单 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:存在已审核的ERP入库单");
return (Result.ReFailure("存在已审核的ERP入库单", 2001), SyncStatus.CheckFail, o_dto.Numbers.First(), det.DetailId);
}
_logger.LogInformation($"入库单->同步金蝶成功->单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
return (Result.ReSuccess(), SyncStatus.Success, o_dto.Numbers.First(), det.DetailId);
}
catch (Exception ex)
{
_logger.LogInformation($"入库单-同步:错误:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{ex.Message}");
var result = Result.ReFailure(ex.Message, 50001);
return (result, SyncStatus.Fail, "", erp_instock_detId);
}
}
///
/// 解绑箱子
///
///
///
///
public async Task UnBind(List boxIds, bool isTransaction = true)
{
var delete_ids = new List();
var t_boxIds = boxIds.Distinct().ToList();
var list = await _inStockRepositories.GetListBy(t_boxIds);
//解绑
list.SelectMany(s => s.Details)
.Where(w => t_boxIds.Contains(w.BoxId))
.ForEach(f => f.UnBind = true);
if (list.Count != 0)
{
var isSuccess = await _inStockRepositories.UpdateRange(list, isTransaction);
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
}
return Result.ReSuccess();
}
///
/// 标记同步成功
///
///
///
///
///
public async Task SyncSuccess(List dto, LoginInDto loginInfo)
{
_logger.LogInformation($"标记同步成功:{JsonConvert.SerializeObject(dto)} 操作人:{loginInfo.UserInfo.StaffId},{loginInfo.UserInfo.Nickname}");
var ids = dto.Select(s => s.Id).ToList();
var entityList = await _inStockRepositories.GetList(ids);
foreach (var d in dto)
{
var entity = entityList.FirstOrDefault(f => f.Id == d.Id);
if (entity == null) return Result.ReFailure(ResultCodes.NoDateError);
var res = entity.OperationSyncSuccess(d.SourceBillNo, d.MaterialNumber, d.ErpBillNo);
if (!res.IsSuccess) return res;
}
var isSuccess = await _inStockRepositories.UpdateRange(entityList, true);
if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
}
}