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();
List s = new List();
for (var i = 0; i < olistTmp.Count; i++)
{
string[] y= olistTmp[i].TwoSerialNumber.Split(',');
s.Add(y[0]);
s.Add(y[1]);
}
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.Union(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();
}
}
}