using BarCode.Web.Core.Dto; using BarCode.Web.Core.Dto.Erp; using BarCode.Web.Core.Dto.Login; using BarCode.Web.Core.Dto.SerialNumbers; using BarCode.Web.Core.Internal.Results; using BarCode.Web.Domain.Entitys; using BarCode.Web.Domain.Infrastructure; using BarCode.Web.Domain.IService; using BarCode.Web.Domain.IService.Public; using BarCode.Web.Domain.Services.Public; using BarCode.Web.Domain.Values; using BarCode.Web.Domain.Values.Single; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using NPOI.HPSF; using NPOI.HSSF.Record; using NPOI.OpenXmlFormats.Wordprocessing; using Org.BouncyCastle.Crypto; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BarCode.Web.Domain.Services { /// /// 序列号服务 /// public class SerialNumberService : ISerialNumberService { private readonly ISerialNumbersRepositories _serialNumbersRepositories; private readonly ISGenerateRecordRepositories _sGenerateRecordRepositories; private readonly RedisClientService _redisClientService; private readonly IServiceScopeFactory _serviceScopeFactory; private readonly ILogger _logger; private IBasicsRepositories _transactionRepositories; private ICenerateDataRepositories _cenerateDataRepositories; private readonly ISingleDataService _singleDataService; private readonly IErpService _erpService; /// /// 序列号服务 /// /// /// /// /// /// /// /// public SerialNumberService(ISerialNumbersRepositories serialNumbersRepositories, ISGenerateRecordRepositories sGenerateRecordRepositories, RedisClientService redisClientService, IServiceScopeFactory serviceScopeFactory, ILogger logger, IBasicsRepositories transactionRepositories, ICenerateDataRepositories cenerateDataRepositories, ISingleDataService singleDataService, IErpService erpService) { _serialNumbersRepositories = serialNumbersRepositories; _sGenerateRecordRepositories = sGenerateRecordRepositories; _redisClientService = redisClientService; _serviceScopeFactory = serviceScopeFactory; _logger = logger; _transactionRepositories = transactionRepositories; _cenerateDataRepositories = cenerateDataRepositories; _singleDataService = singleDataService; _erpService = erpService; } /// /// 生成序列号 /// /// /// /// /// public Task Generate(GenerateSerialNumberRequest dto, LoginInDto loginInfo) { if (dto.Details.Count() == 0) return Task.FromResult(Result.ReSuccess()); //if (dto.Details.Count() > 1000) return Task.FromResult(Result.ReFailure(ResultCodes.SerialGenerateBigNumber)); _logger.LogInformation($"生成序列号:{JsonConvert.SerializeObject(dto)},用户:{loginInfo.UserInfo.Nickname}"); var info = _redisClientService.GetStringKey($"barcode_cenerate_serial"); if (info == true) return Task.FromResult(Result.ReFailure(ResultCodes.SerialNumberG)); _redisClientService.SetStringKey($"barcode_cenerate_serial", true, TimeSpan.FromMinutes(5)); var materials_result = _erpService.BillQueryForMaterial().GetAwaiter().GetResult(); List materials = new List(); if (materials_result.IsSuccess) materials = materials_result.Data.ToList(); var cList = dto.Details.GroupBy(g => g.Specifications).Select(s => s.Key).ToList(); foreach (var s in cList) { var m = materials.FirstOrDefault(w => w.Specifications.Equals(s)); var details = dto.Details.Where(w => w.Specifications.Equals(s)).ToList(); if (m == null) { details.ForEach(f => dto.Details.Remove(f)); } else { foreach (var de in details) { de.MaterialNumber = m.MaterialNumber; de.IdConvertBar = m.IdConvertBar; } } } string supplierCode = ""; string orgCode = ""; if (dto.OrgCode.Substring(0, 1).Equals("s")) supplierCode = dto.OrgCode.Substring(2, dto.OrgCode.Length - 2); else orgCode = dto.OrgCode.Substring(2, dto.OrgCode.Length - 2); var dataEntity = _cenerateDataRepositories.Get(CenerateDataType.Serial).GetAwaiter().GetResult(); int beginNumber = dataEntity.Number; if (beginNumber == 0) dataEntity.Number = dto.Details.Sum(s => s.Number); else dataEntity.Number += dto.Details.Sum(s => s.Number); List sgList = new List(); foreach (var d in dto.Details) { if(d.Number>1000) { d.Number = 1000; } if (d.isTwo == 0)//如果套装数为0,那么自动变成1 { d.isTwo = 1; } else if(d.isTwo==2) { int result = d.Number % d.isTwo; if (result !=0)// { return Task.FromResult(Result.ReFailure(ResultCodes.IsTwoError)); } } else if(d.isTwo>2) { return Task.FromResult(Result.ReFailure(ResultCodes.IsTwoError)); } SerialNumberGenerateRecord sg = new SerialNumberGenerateRecord() { CompanyId = loginInfo.UserInfo.CompanyId, CreateTime = DateTime.Now, CreatorId = loginInfo.UserInfo.UcId, OrgCode = orgCode, IdConvertBar = d.IdConvertBar, MaterialNumber = d.MaterialNumber, Number = d.Number, BeginNumber = beginNumber, PurchaseBillNo = d.PurchaseBillNo, SupplierCode = supplierCode, IsTwo=d.isTwo//alter by yzh }; //下一个物料开始数量要重新赋值 beginNumber = beginNumber + d.Number; sgList.Add(sg); } IDbContextTransaction _transaction = _transactionRepositories.GetTransaction(); bool res_Rollback = false; var isSuccess = _sGenerateRecordRepositories.AddRange(sgList, false).GetAwaiter().GetResult(); if (!isSuccess) res_Rollback = true; if (!res_Rollback) { var entity = _cenerateDataRepositories.Edit(dataEntity, false).GetAwaiter().GetResult(); if (entity == null) res_Rollback = true; } isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction); if (!isSuccess) return Task.FromResult(Result.ReFailure(ResultCodes.DateWriteError)); Task.Run(async () => { await GenerateSerialNumber(sgList); }); _redisClientService.SetStringKey($"barcode_cenerate_serial", false, TimeSpan.FromMinutes(5)); return Task.FromResult(Result.ReSuccess()); } /// /// 循环生成序列码 /// /// /// private async Task GenerateSerialNumber(List sgList) { try { var info = _redisClientService.GetStringKey($"cenerate_serial_exec"); if (info == true) { //如果当前有在生成的计划 则挂起 等生成完成 while (true) { Thread.Sleep(5000); info = _redisClientService.GetStringKey($"cenerate_serial_exec"); if (info != true) break; } } _redisClientService.SetStringKey($"cenerate_serial_exec", true, TimeSpan.FromMinutes(30)); _logger.LogInformation($"生成序列码开始:{DateTime.Now}-{JsonConvert.SerializeObject(sgList)}"); using (var scope = _serviceScopeFactory.CreateScope()) { bool isSuccess = true; bool res_Rollback = false; var _snRepositories = scope.ServiceProvider.GetRequiredService(); var _sgRepositories = scope.ServiceProvider.GetRequiredService(); _transactionRepositories = scope.ServiceProvider.GetRequiredService(); foreach (var sg in sgList) { List sList = new List(); for (int i = 0; i < sg.Number; i++) { SerialNumbers s = new SerialNumbers() { CreateTime = DateTime.Now, CreatorId = sg.CreatorId, OrgCode = sg.OrgCode, SupplierCode = sg.SupplierCode, SerialNumber = sg.IdConvertBar, MaterialNumber = sg.MaterialNumber, Number = sg.BeginNumber + i, IsTwo = sg.IsTwo, thisNumber = i+1,//alter by yzh GenerateRecordId = sg.Id }; sList.Add(s); } //一个生成记录一个事物,这样能一条条记录对应的生成下去 成功一个是一个 IDbContextTransaction _transaction = _transactionRepositories.GetTransaction(); var isRes = await _snRepositories.AddRange(sList, false); if (!isRes) res_Rollback = true; if (!res_Rollback) { sg.Complete();//生成完成 var sg_entity = await _sgRepositories.Edit(sg, false); if (sg_entity == null) res_Rollback = true; } //提交事务 isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction); if (res_Rollback || !isSuccess) _logger.LogError("生成序列码数据操作失败"); } } _redisClientService.SetStringKey($"cenerate_serial_exec", false, TimeSpan.FromMinutes(30)); _logger.LogInformation($"生成序列码结束{DateTime.Now}"); } catch (Exception ex) { _logger.LogError($"生成序列码异常:{ex.ToString}"); } } /// /// 下载 /// /// /// /// public async Task DownLoad(OperateSerialNumberRequest dto) { //取出所有的生成记录 var generateRecords = await _sGenerateRecordRepositories.GetEntityList(dto.GenerateRecordIds,"0"); if (generateRecords.Count() != dto.GenerateRecordIds.Count()) return Result.ReFailure(ResultCodes.NoDateError); var snGRList = await _serialNumbersRepositories.GetEntityListByGRIds(dto.GenerateRecordIds); //修改序列号下载数 List olist = new List(); if (dto.IsAll) olist = snGRList; else { if (dto.IsTwo == 2)//说明为两件装 { // var olistTmp=snGRList.Where(w => dto.SerialNumbers.Contains(w.SerialNumber)).ToList(); olist = snGRList.Where(w => dto.SerialNumbers.Contains(w.SerialNumber)).ToList(); List s = new List(); for (var i = 0; i < olist.Count; i++) { string[] y= olist[i].TwoSerialNumber.Split(','); s.Add(y[0]); s.Add(y[1]); olist = snGRList.Where(w => dto.SerialNumbers.Contains(y[0])).ToList(); olist = snGRList.Where(w => dto.SerialNumbers.Contains(y[1])).ToList(); } s.Distinct(); var snGRList2 = await _serialNumbersRepositories.GetEntityList(s); olist=snGRList2; } else { olist = snGRList.Where(w => dto.SerialNumbers.Contains(w.SerialNumber)).ToList(); } //olist = snGRList.Where(w => dto.SerialNumbers.Contains(w.TwoSerialNumber)).ToList(); } olist.ForEach(f => f.DownLoad()); //if(dto.IsTwo == 2) //{ //snGRList.Find(olist.) //} foreach (var g in generateRecords) { int downLoad = snGRList.Where(w => w.GenerateRecordId == g.Id && w.DownLoadNumber > 0).Count(); g.DownLoad(downLoad); } IDbContextTransaction _transaction = _transactionRepositories.GetTransaction(); bool res_Rollback = false; var isSuccess = await _serialNumbersRepositories.EditEntityList(olist, false); if (!isSuccess) res_Rollback = true; if (!res_Rollback) { var res = await _sGenerateRecordRepositories.EditEntityList(generateRecords, false); if (!res) res_Rollback = true; } isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction); if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); return Result.ReSuccess(); } /// /// 更新错的Sn /// /// /// /// public async Task UpdateSn(OperateSerialNumberRequest dto) { //取出所有的生成记录 var generateRecords = await _sGenerateRecordRepositories.GetEntityList(dto.GenerateRecordIds,"1"); List olist = new List(); bool res_Rollback = false; for (int i=0;i< generateRecords.Count;i++) { List s = []; string newSuitNumber = ""; string oldSuitNumber = ""; int ids = generateRecords[i].Id; s.Add(ids); olist = await _serialNumbersRepositories.GetEntityListByGRIds(s); //修改序列号下载数 int m=0; foreach (var item in olist) { m++; //自动生成序列码 string sn = item.SerialNumber; if (m % 2 == 0) { newSuitNumber = oldSuitNumber; } else { oldSuitNumber = sn; newSuitNumber = sn; } item.GenerateSuitNumber(newSuitNumber); // item.GenerateTwoSerialNumber(newSuitNumber); item.SetThisNumber(m); item.IsTwo = 2; } foreach (var item in olist) { string ss = _serialNumbersRepositories.GetTwoSerialNumber(olist, item.SuitNumber); item.GenerateTwoSerialNumber(ss); string sNumberCode = _serialNumbersRepositories.GetTwoNumberCode(olist, item.SuitNumber); item.GenerateTwoNumberCode(sNumberCode); } IDbContextTransaction _transaction = _transactionRepositories.GetTransaction(); var isSuccess = await _serialNumbersRepositories.EditEntityList(olist, false); if (!isSuccess) res_Rollback = true; generateRecords[i].IsTwo = 2; isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction); if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); //return Result.ReSuccess(); } if (!res_Rollback) { var res = await _sGenerateRecordRepositories.EditEntityList(generateRecords, false); if (!res) res_Rollback = true; } return Result.ReSuccess(); } /// /// 转换序列号(从单件装转为两件装) /// /// /// /// public async Task TransferSn(TransferSNOneTwoTwoRequest dto) { //取出所有的生成记录 var generateRecords = await _sGenerateRecordRepositories.GetEntityList(dto.ids, "0"); for (int i = 0; i < generateRecords.Count; i++) { int intNum = generateRecords[i].Number; int result = intNum % 2; if (result != 0)// { return Result.ReFailure(ResultCodes.IsTwoError); } } List olist = new List(); bool res_Rollback = false; for (int i = 0; i < generateRecords.Count; i++) { List s = []; string newSuitNumber = ""; string oldSuitNumber = ""; int ids = generateRecords[i].Id; s.Add(ids); olist = await _serialNumbersRepositories.GetEntityListByGRIds(s); //修改序列号下载数 int m = 0; foreach (var item in olist) { m++; //自动生成序列码 string sn = item.SerialNumber; if (m % 2 == 0) { newSuitNumber = oldSuitNumber; } else { oldSuitNumber = sn; newSuitNumber = sn; } item.GenerateSuitNumber(newSuitNumber); // item.GenerateTwoSerialNumber(newSuitNumber); item.SetThisNumber(m); item.IsTwo = 2; } foreach (var item in olist) { string ss = _serialNumbersRepositories.GetTwoSerialNumber(olist, item.SuitNumber); item.GenerateTwoSerialNumber(ss); string sNumberCode = _serialNumbersRepositories.GetTwoNumberCode(olist, item.SuitNumber); item.GenerateTwoNumberCode(sNumberCode); } IDbContextTransaction _transaction = _transactionRepositories.GetTransaction(); var isSuccess = await _serialNumbersRepositories.EditEntityList(olist, false); if (!isSuccess) res_Rollback = true; generateRecords[i].IsTwo = 2; isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction); if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); //return Result.ReSuccess(); } if (!res_Rollback) { var res = await _sGenerateRecordRepositories.EditEntityList(generateRecords, false); if (!res) res_Rollback = true; } return Result.ReSuccess(); } /// /// 打印 /// /// /// /// public async Task Print(OperateSerialNumberRequest dto) { //取出所有的生成记录 var generateRecords = await _sGenerateRecordRepositories.GetEntityList(dto.GenerateRecordIds,""); if (generateRecords.Count() != dto.GenerateRecordIds.Count()) return Result.ReFailure(ResultCodes.NoDateError); var snGRList = await _serialNumbersRepositories.GetEntityListByGRIds(dto.GenerateRecordIds); //修改序列号下载数 List olist = new List(); if (dto.IsAll) olist = snGRList; else { olist = snGRList.Where(w => dto.SerialNumbers.Contains(w.SerialNumber)).ToList(); } olist.ForEach(f => f.Print()); foreach (var g in generateRecords) { int printNumber = snGRList.Where(w => w.GenerateRecordId == g.Id && w.PrintNumber > 0).Count(); g.Print(printNumber); } IDbContextTransaction _transaction = _transactionRepositories.GetTransaction(); bool res_Rollback = false; var isSuccess = await _serialNumbersRepositories.EditEntityList(olist, false); if (!isSuccess) res_Rollback = true; if (!res_Rollback) { var res = await _sGenerateRecordRepositories.EditEntityList(generateRecords, false); if (!res) res_Rollback = true; } isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction); if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); return Result.ReSuccess(); } /// /// 反写使用数 /// /// /// public async Task Use(List sGIds) { var sGList = await _sGenerateRecordRepositories.GetEntityList(sGIds,""); //_logger.LogInformation($"获取到:sGList:{JsonConvert.SerializeObject(sGList)}"); var sGSNumberList = await _serialNumbersRepositories.GetEntityListByGRIds(sGIds); // _logger.LogInformation($"获取到:sGSNumberList:{JsonConvert.SerializeObject(sGSNumberList)}"); foreach (var sg in sGList) { int number = sGSNumberList.Where(w => w.GenerateRecordId == sg.Id && w.BoxId > 0 ).Count(); sg.Use(number); // _logger.LogInformation($"获取到:sg:{sg}"); } var isSuccess = await _sGenerateRecordRepositories.EditEntityList(sGList, false); if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); return Result.ReSuccess(); } /// /// 修改序列码物料 /// /// /// /// public async Task UpdateMaterial(UpdateMaterialRequest dto) { //取出所有的生成记录 var generateRecord = await _sGenerateRecordRepositories.GetEntity(dto.GenerateRecordId); if (generateRecord == null) return Result.ReFailure(ResultCodes.NoDateError); var serialNumbers = await _serialNumbersRepositories.GetEntityList(dto.SerialNumbers); var exec_m = serialNumbers.Where(w => w.MaterialNumber == dto.MaterialNumber).Select(s => s.MaterialNumber).ToList(); if (exec_m.Count() > 0) return Result.ReFailure($"序列号{string.Join(",", exec_m)}对应物料跟需要修改的物料一致", 611007); //修改物料 foreach (var s in serialNumbers) { var res = s.UpdateMaterial(dto.MaterialNumber); if (!res.IsSuccess) return res; } generateRecord.UpdateMaterial(); IDbContextTransaction _transaction = _transactionRepositories.GetTransaction(); bool res_Rollback = false; var isSuccess = await _serialNumbersRepositories.EditEntityList(serialNumbers, false); if (!isSuccess) res_Rollback = true; if (!res_Rollback) { var res = await _sGenerateRecordRepositories.Edit(generateRecord, false); if (res == null) res_Rollback = true; } isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction); if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); return Result.ReSuccess(); } } }