Files
BarCode-Api/src/BarCode.Web.Domain/Services/BoxService.cs
2025-06-06 14:16:29 +08:00

597 lines
27 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using BarCode.Web.Core.Dto;
using BarCode.Web.Core.Dto.Box;
using BarCode.Web.Core.Dto.Erp.Org;
using BarCode.Web.Core.Dto.Erp.Supplier;
using BarCode.Web.Core.Dto.Login;
using BarCode.Web.Core.Dto.SingleData;
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.Storage;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npoi.Mapper;
using NPOI.SS.Formula.Functions;
using Quartz;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BarCode.Web.Domain.Services
{
/// <summary>
/// 箱信息
/// </summary>
public class BoxService : IBoxService
{
private readonly ILogger<BoxService> _logger;
private IBasicsRepositories _transactionRepositories;
private readonly IBoxRepositories _boxRepositories;
private readonly ISingleDataService _singleDataService;
private readonly ISerialNumbersRepositories _serialNumbersRepositories;
private readonly IErpService _erpService;
private readonly IWmsService _wmsService;
private readonly ISerialNumberService _serialNumberService;
public BoxService(ILogger<BoxService> logger, IBasicsRepositories transactionRepositories,
IBoxRepositories boxRepositories, ISingleDataService singleDataService, ISerialNumbersRepositories serialNumbersRepositories,
IErpService erpService, IWmsService wmsService, ISerialNumberService serialNumberService)
{
_logger = logger;
_transactionRepositories = transactionRepositories;
_boxRepositories = boxRepositories;
_singleDataService = singleDataService;
_serialNumbersRepositories = serialNumbersRepositories;
_erpService = erpService;
_wmsService = wmsService;
_serialNumberService = serialNumberService;
}
/// <summary>
/// 生成箱码
/// </summary>
/// <param name="dto"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> Generate(GenerateBoxRequest dto, LoginInDto loginInfo)
{
_logger.LogInformation($"生成箱码:{JsonConvert.SerializeObject(dto)},用户:{loginInfo.UserInfo.Nickname}");
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);
List<Box> boxs = new List<Box>();
for (int i = 1; i <= dto.Number; i++)
{
Box b = new Box()
{
CreatorId = loginInfo.UserInfo.UcId,
OrgCode = orgCode,
SupplierCode = supplierCode,
CompanyId = loginInfo.UserInfo.CompanyId
};
boxs.Add(b);
}
var res = await _boxRepositories.AddRange(boxs);
if (!res) return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// 装箱
/// </summary>
/// <param name="dto"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> Save(SaveBoxRequest dto, LoginInDto loginInfo)
{
_logger.LogInformation($"装箱:{JsonConvert.SerializeObject(dto)},用户:{loginInfo.UserInfo.Nickname}");
var box = await _boxRepositories.Get(dto.BoxId);
if (box == null)
return Result.ReFailure(ResultCodes.NoDateError);
if (box.Status == BoxStatus.Complete)
return Result.ReFailure(ResultCodes.CartonCompleteError);
//去重
dto.Details = dto.Details.Distinct().ToList();
var sAll = dto.Details.Select(s => s.SerialNumber).ToList();
var serialNumberList = await _serialNumbersRepositories.GetEntityListContainNumber(sAll);
// List<SerialNumbers> serialList;
//两件装
var sAllTwo = dto.Details.Select(s => s.TwoSerialNumber).ToList();
sAllTwo.RemoveAll(string.IsNullOrEmpty);
var serialNumberListTwo = await _serialNumbersRepositories.GetEntityListContainNumber(sAllTwo);
// List<SerialNumbers> serialListTwo;
if (serialNumberList.Count() != sAll.Count())
return Result.ReFailure(ResultCodes.SerialNumberNoDateError);
if (serialNumberList.Where(w => w.BoxId != 0 || w.IsUse == true).Any())
return Result.ReFailure(ResultCodes.SerialNumberBindBox);
//新的序列号以存在于箱中
var bs = box.Details.SelectMany(s => s.SerialNumbers).ToList();
var jj = sAll.Intersect(bs);
if (jj.Count() > 0)
return Result.ReFailure(ResultCodes.SerialNumberBindBox);
//装箱状态
var resCarton = box.Carton(dto.IsCarton, loginInfo.UserInfo.UcId);
if (!resCarton.IsSuccess) return resCarton;
var materialNumbers = dto.Details.GroupBy(g => g.MaterialNumber).Select(s => s.Key).ToList();
foreach (var m in materialNumbers)
{
List<string> s=[null];
s.Clear();
var detail = box.Details.FirstOrDefault(f => f.MaterialNumber.Equals(m));
var serialNumbers = dto.Details.Where(w => w.MaterialNumber.Equals(m)).Select(s => s.SerialNumber).ToList();
var serialNumbersTwo = dto.Details.Where(w => w.MaterialNumber.Equals(m)).Select(s => s.TwoSerialNumber).ToList();
var intCount = serialNumbers.Count();
s = serialNumbers;
serialNumbersTwo.RemoveAll(string.IsNullOrEmpty);
if (serialNumbersTwo != null)
{
for(int i = 0; i < serialNumbersTwo.Count; i++)
{
s.Add(serialNumbersTwo[i]);
}
}
s.OrderDescending();
s.Sort();
//for(int i=0;i<serialNumbers.Count;i++)
//{
// //跟据serialNumbers 取得对应的serialNumber
// var serialList2 = await _serialNumbersRepositories.GetEntityListBySuitNumber(serialNumbers[i]);
// for (int j = 0; j < serialList2.Count; j++)
// {
// s.Add( serialList2[j].SerialNumber);
// }
//}
if (detail == null)
{
detail = new BoxDetails()
{
MaterialNumber = m,
// Qty = serialNumbers.Count(),
Qty = intCount,
// SerialNumbers = serialNumbers
SerialNumbers = s
};
box.Details.Add(detail);
}
else
{
//detail.Qty += serialNumbers.Count();
//detail.SerialNumbers.AddRange(serialNumbers);
detail.Qty += intCount;
detail.SerialNumbers.AddRange(s);
detail.SerialNumbers.Sort();
}
}
IDbContextTransaction _transaction = _transactionRepositories.GetTransaction();
bool res_Rollback = false;
bool isSuccess = true;
//装箱
foreach (var d in dto.Details.Select(s => s.SerialNumber).Reverse())
{
//原来的
var serial = serialNumberList.FirstOrDefault(f => f.SerialNumber.Equals(d)
|| f.NumberCode.Equals(d));
if (serial == null) return Result.ReFailure(ResultCodes.SerialNumberNoDateError);
serial.CompleteBox(box.Id, d,"0");
//原来的到此
//serialList = await _serialNumbersRepositories.GetEntityListBySuitNumber(d);
//if (serialList == null) return Result.ReFailure(ResultCodes.SerialNumberNoDateError);
//if (serialList.Count == 0) return Result.ReFailure(ResultCodes.SerialNumberNoDateError);
//for (int i = 0; i < serialList.Count; i++)
//{
// if (serialList[i].SerialNumber.ToString() == d)
// {
// serialList[i].CompleteBox(box.Id, d, "0");
// }
// else
// {
// serialList[i].CompleteBox(box.Id, d, "1");
// }
//}
//if (!res_Rollback)
//{
// isSuccess = await _serialNumbersRepositories.EditEntityList(serialNumberList, false);
// if (!isSuccess) res_Rollback = true;
//}
}
//装箱
foreach (var d in dto.Details.Select(s => s.TwoSerialNumber).Reverse())
{
//原来的
if (d==null) continue;
if (d == "") continue;
var serial = serialNumberListTwo.FirstOrDefault(f => f.SerialNumber.Equals(d)
|| f.NumberCode.Equals(d));
if (serial == null) return Result.ReFailure(ResultCodes.SerialNumberNoDateError);
serial.CompleteBox(box.Id, d, "1");
}
var res = await _boxRepositories.Edit(box, false);
if (res == null) res_Rollback = true;
if (!res_Rollback)
{
isSuccess = await _serialNumbersRepositories.EditEntityList(serialNumberList, false);
if (!isSuccess) res_Rollback = true;
}
if (!res_Rollback)
{
isSuccess = await _serialNumbersRepositories.EditEntityList(serialNumberListTwo, false);
if (!isSuccess) res_Rollback = true;
}
if (!res_Rollback)
{
var ids = serialNumberList.Select(s => s.GenerateRecordId).ToList();
var resUse = await _serialNumberService.Use(ids);
if (!resUse.IsSuccess) res_Rollback = true;
}
//提交事务
isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction);
if (res_Rollback || !isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// 打印
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> Print(OperateRequest dto)
{
var boxs = await _boxRepositories.GetEntityList(dto.Ids);
boxs.ForEach(f => f.Print());
var res = await _boxRepositories.EditEntityList(boxs);
if (!res) return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// 删除
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> Delete(DeleteBoxSerialNumberRequest dto, LoginInDto loginInfo)
{
_logger.LogInformation($"删除箱物料:{JsonConvert.SerializeObject(dto)},用户:{loginInfo.UserInfo.Nickname}");
var box = await _boxRepositories.Get(dto.BoxId);
if (box == null)
return Result.ReFailure(ResultCodes.BoxNoDataError);
if (box.Status == BoxStatus.Complete)
return Result.ReFailure(ResultCodes.CartonCompleteError);
var sList = await _serialNumbersRepositories.GetEntityList(new List<string>() { dto.SerialNumber });
var s = sList.FirstOrDefault(f => f.SerialNumber.Equals(dto.SerialNumber));
if (s == null)
return Result.ReFailure(ResultCodes.SerialNumberNoDateError);
//判断使用的是数字序列码还是序列码
var sStr = s.IsUseNumber == true ? s.NumberCode : s.SerialNumber;
var resUn = box.UnSerialNumber(sStr, dto.MaterialNumber,"0");
if (!resUn.IsSuccess) return resUn;
//var sList = await _serialNumbersRepositories.GetEntityListContainNumber(new List<string>() { dto.SerialNumber });
//sList.ForEach(f => f.UnBox());
s.UnBox();//解绑
// _logger.LogInformation($"现在进行TwoSerialNumber的写入");
if (dto.TwoSerialNumber != null && dto.TwoSerialNumber!="")
{
_logger.LogInformation($"获取到TwoSerialNumber:{dto.TwoSerialNumber}");
// var TwosList = await _serialNumbersRepositories.GetEntityList(new List<string>() { dto.TwoSerialNumber });
var TwosList = await _serialNumbersRepositories.GetEntityListContainNumber(new List<string>() { dto.TwoSerialNumber });
var Twos = TwosList.FirstOrDefault(f => f.SerialNumber.Equals(dto.TwoSerialNumber)||f.NumberCode.Equals(dto.TwoSerialNumber));
_logger.LogInformation($"获取到Twos:{JsonConvert.SerializeObject(Twos)}");
if (Twos == null)
return Result.ReFailure(ResultCodes.SerialNumberNoDateError);
////判断使用的是数字序列码还是序列码
sList.AddRange(TwosList);
var TwosStr = s.IsUseNumber == true ? Twos.NumberCode : Twos.SerialNumber;
//_logger.LogInformation($"获取到TwosStr:{TwosStr}");
//_logger.LogInformation($"获取到TwosStr:{TwosStr}");
var TworesUn = box.UnSerialNumber(TwosStr, dto.MaterialNumber,"1");
if (!TworesUn.IsSuccess) return TworesUn;
//var sList = await _serialNumbersRepositories.GetEntityListContainNumber(new List<string>() { dto.SerialNumber });
//sList.ForEach(f => f.UnBox());
Twos.UnBox();//解绑
}
IDbContextTransaction _transaction = _transactionRepositories.GetTransaction();
bool res_Rollback = false;
bool isSuccess = true;
var res = await _boxRepositories.Edit(box, false);
if (res == null) res_Rollback = true;
if (!res_Rollback)
{
isSuccess = await _serialNumbersRepositories.EditEntityList(sList, false);
if (!isSuccess) res_Rollback = true;
}
if (!res_Rollback)
{
var ids = sList.Select(s => s.GenerateRecordId).ToList();
var resUse = await _serialNumberService.Use(ids);
if (!resUse.IsSuccess) res_Rollback = true;
}
//提交事务
isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction);
if (res_Rollback || !isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// 清空装箱信息
/// </summary>
/// <param name="boxId"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> Clear(int boxId, LoginInDto loginInfo)
{
_logger.LogInformation($"清空装箱信息:{boxId},用户:{loginInfo.UserInfo.Nickname}");
var box = await _boxRepositories.Get(boxId);
if (box == null)
return Result.ReFailure(ResultCodes.BoxNoDataError);
var s = box.Details.SelectMany(s => s.SerialNumbers).ToList();
box.Details.Clear();
IDbContextTransaction _transaction = _transactionRepositories.GetTransaction();
bool res_Rollback = false;
bool isSuccess = true;
var sList = await _serialNumbersRepositories.GetEntityListByBoxIds(new List<int>() { boxId });
//foreach (var f in sList)
//{
// if( f.IsTwo>1)
// {
// //说明是两件装的产品,那么要分别清除
// var sList2 = await _serialNumbersRepositories.GetEntityListBySuitNumber(f.SerialNumber);
// for(int i=0;i<sList2.Count;i++)
// {
// sList2[i].UnBox();
// if (!res_Rollback)
// {
// isSuccess = await _serialNumbersRepositories.EditEntityList(sList2, false);
// if (!isSuccess) res_Rollback = true;
// }
// }
// }
// f.UnBox();
//}
sList.ForEach(f => f.UnBox());
var res = await _boxRepositories.Edit(box, false);
if (res == null) res_Rollback = true;
if (!res_Rollback)
{
isSuccess = await _serialNumbersRepositories.EditEntityList(sList, false);
if (!isSuccess) res_Rollback = true;
}
if (!res_Rollback)
{
var ids = sList.Select(s => s.GenerateRecordId).ToList();
var resUse = await _serialNumberService.Use(ids);
if (!resUse.IsSuccess) res_Rollback = true;
}
//提交事务
isSuccess = _transactionRepositories.CommitTransaction(res_Rollback, _transaction);
if (res_Rollback || !isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// wms系统调用 获取完成装箱箱信息
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<(List<WmsBoxResponse> list, int total)> GetCartonListAsync(WmsBoxRequest dto)
{
var org_result = await _erpService.BillQueryForOrg();
List<ErpOrgDto> orgs = new List<ErpOrgDto>();
if (org_result.IsSuccess)
orgs = org_result.Data.ToList();
var supplier_result = await _erpService.BillQueryForSupplier();
List<ErpSupplierDto> suppliers = new List<ErpSupplierDto>();
if (supplier_result.IsSuccess)
suppliers = supplier_result.Data.ToList();
var (list, count) = await _boxRepositories.GetEntityByWmsList(dto);
var ids = list.Select(s => s.Id).ToList();
var serialList = await _serialNumbersRepositories.GetEntityListByBoxIds(ids);
List<WmsBoxResponse> response = new List<WmsBoxResponse>();
foreach (var box in list)
{
WmsBoxResponse res = new WmsBoxResponse()
{
BoxBillNo = box.BoxBillNo,
OpsBoxId = box.Id,
CompleteCartonTime = box.CartonEndTime ?? DateTime.Now,
CompleteCartonUser = _singleDataService.GetSingleData(SingleAction.Users, box.CompanyId, box.CartonUserId),
CreateTime = box.CreateTime,
OrgId = orgs.FirstOrDefault(f => f.Number.Equals(box.OrgCode))?.Id ?? 0,
SupplierId = suppliers.FirstOrDefault(f => f.Number.Equals(box.SupplierCode))?.Id ?? 0,
CreateUser = _singleDataService.GetSingleData(SingleAction.Users, box.CompanyId, box.CreatorId),
};
foreach (var bd in box.Details)
{
//var bdsList = serialList.Where(w => w.BoxId == box.Id && w.MaterialNumber.Equals(bd.MaterialNumber)).ToList();
var bdsList = bd.SerialNumbers;
List<Core.Dto.Box.OpsSerialNumbersResponse> sList = new List<Core.Dto.Box.OpsSerialNumbersResponse>();
foreach (var s in bdsList)
{
var sentity = serialList.FirstOrDefault(f => f.SerialNumber.Equals(s) || f.NumberCode.Equals(s));
if (sentity == null) continue;
if (sentity.TwoNumberCode.IndexOf(s) >= 0)
{
sList.Add(new Core.Dto.Box.OpsSerialNumbersResponse()
{
SerialNumber = s,
BarCereateUser = _singleDataService.GetSingleData(SingleAction.Users, box.CompanyId, sentity == null ? 0 : sentity.CreatorId),
BarCreateTime = sentity == null ? null : sentity.CreateTime,
IsTwo = sentity == null ? 1 : sentity.IsTwo,
TwoSerialNumber = sentity == null ? s : sentity.TwoNumberCode,
IsNotCount = sentity == null ? "0" : sentity.IsNotCount
});
}
else
{
sList.Add(new Core.Dto.Box.OpsSerialNumbersResponse()
{
SerialNumber = s,
BarCereateUser = _singleDataService.GetSingleData(SingleAction.Users, box.CompanyId, sentity == null ? 0 : sentity.CreatorId),
BarCreateTime = sentity == null ? null : sentity.CreateTime,
IsTwo = sentity == null ? 1 : sentity.IsTwo,
TwoSerialNumber = sentity == null ? s : sentity.TwoSerialNumber,
IsNotCount = sentity == null ? "0" : sentity.IsNotCount
});
}
//以前是之前的
//// var sentity = serialList.FirstOrDefault(f => f.SerialNumber.Equals(s) || f.NumberCode.Equals(s));
//// var sentity = serialList.GetEntityListBySuitNumber(f => f.SerialNumber.Equals(s) || f.NumberCode.Equals(s));
//var serialList2 = await _serialNumbersRepositories.GetEntityListBySuitNumber(s);
////int isTwo = 1;
////if (serialList2.Count > 1)
////{
//// isTwo = serialList2.Count;
////}
//foreach (var s2 in serialList2)
//{
// var sentity = serialList.FirstOrDefault(f => f.SerialNumber.Equals(s2) || f.NumberCode.Equals(s2));
// sList.Add(new Core.Dto.Box.OpsSerialNumbersResponse()
// {
// SerialNumber = s2.SerialNumber,
// BarCereateUser = _singleDataService.GetSingleData(SingleAction.Users, box.CompanyId, sentity == null ? 0 : sentity.CreatorId),
// BarCreateTime = sentity == null ? null : sentity.CreateTime,
// IsTwo= s2.IsTwo,
// TwoSerialNumber=s2.TwoSerialNumber,
// IsNotCount=s2.isNotCount
// });
//}
}
Core.Dto.Box.OpsBoxDetailsResponse Detail = new Core.Dto.Box.OpsBoxDetailsResponse()
{
MaterialNumber = bd.MaterialNumber,
Qty = bd.Qty,
SerialNumbers = sList
};
res.Details.Add(Detail);
}
response.Add(res);
}
return (response, count);
}
/// <summary>
/// 重新装箱
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> Restart(OperateRequest dto, LoginInDto loginInfo)
{
_logger.LogInformation($"重新装箱的箱:{JsonConvert.SerializeObject(dto.Ids)} 操作人:{loginInfo.UserInfo.Nickname}");
var boxList = await _boxRepositories.GetEntityList(dto.Ids);
if (boxList.Where(w => w.Status != BoxStatus.Complete).Any())
return Result.ReFailure(ResultCodes.BoxNoComplete);
var nos = boxList.Select(s => s.BoxBillNo).ToList();
List<string> failBox = new List<string>();
var res = await _wmsService.Restart(nos);
if (!res.IsSuccess)
return res;
//已收货的箱返回在数据里带过来
failBox = res.Data;
//把已收货的箱排除出去 然后重置
boxList.Where(w => !failBox.Contains(w.BoxBillNo)).ForEach(f => f.Restart());
var isSuccess = await _boxRepositories.EditEntityList(boxList);
if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError);
if (failBox.Count() > 0)
{
return Result.ReFailure($"箱号:{string.Join(",", failBox)} 已收货,不允许重新装箱,请和仓库人员沟通", 3433535);
}
return Result.ReSuccess();
}
/// <summary>
/// 开始装箱
/// </summary>
/// <param name="boxId"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> BeginCarton(int boxId, LoginInDto loginInfo)
{
_logger.LogInformation($"开始装箱:{boxId},用户:{loginInfo.UserInfo.Nickname}");
var box = await _boxRepositories.Get(boxId);
if (box == null)
return Result.ReFailure(ResultCodes.BoxNoDataError);
if (box.Status == BoxStatus.Complete)
return Result.ReFailure(ResultCodes.CartonCompleteError);
var res = box.BeginCarton(loginInfo.UserInfo.UcId);
if (!res.IsSuccess)
return res;
var res_box = await _boxRepositories.Edit(box, true);
if (res_box == null) return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
}
}