Files
wcs/WCS.BLL/Services/Service/BatchBindMatDetailService.cs
hehaibing-1996 5a074ee3d6 客户端版本更新为V1.0.3
批量导入默认批次+输入批次格式校验
2025-04-02 14:11:34 +08:00

519 lines
24 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using TouchSocket.Core;
using WCS.BLL.Config;
using WCS.BLL.DbModels;
using WCS.BLL.HardWare;
using WCS.BLL.Manager;
using WCS.BLL.Services.IService;
using WCS.DAL;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
using WCS.Model;
using WCS.Model.ApiModel;
using WCS.Model.ApiModel.BatchBindMatDetail;
using WCS.Model.ApiModel.InOutRecord;
using WCS.Model.ApiModel.MatBaseInfo;
using WCS.Model.ApiModel.MatDetailCurrentInfo;
using WCS.Model.ApiModel.MatDetailHistoryInfo;
using WCS.Model.ApiModel.StoreInfo;
using WCS.Model.ApiModel.User;
namespace WCS.BLL.Services.Service
{
public class BatchBindMatDetailService : IBatchBindMatDetailService
{
/// <summary>
/// 按照工位号获取绑定明细
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<PageQueryResponse<MatDetailCurrentInfoModel>> GetMatDetailCurrentInfosByStationCode(GetMatDetailCurrentInfosByStationCodeRequest request)
{
try
{
var recordsQueryable = DbHelp.db.Queryable<MatDetailCurrentInfo>()
.LeftJoin<ShelfInfo>((mci, si) => mci.ShelfId == si.Id)
.LeftJoin<LocationInfo>((mci, si, li) => (si.TransStatus == TransStatusEnum. && si.CurrentLocationId == li.Id)
|| (si.TransStatus == TransStatusEnum. && si.DestinationLocationId == li.Id))
.Where((mci, si, li) => !string.IsNullOrEmpty(mci.StationCode))
.WhereIF(request.OrderTypeId != null && request.OrderTypeId != 0, (mci, si, li) => mci.OrderTypeId == request.OrderTypeId)
.WhereIF(!string.IsNullOrEmpty(request.ShelfCode), (mci, si, li) => si.ShelfCode.Contains(request.ShelfCode))
.WhereIF(!string.IsNullOrEmpty(request.StationCode) && request.StationCode.ToLower() != "admin", (mci, si, li) => mci.StationCode.Contains(request.StationCode))
.Select((mci, si, li) => new MatDetailCurrentInfoModel()
{
Id = mci.Id,
ShelfId = mci.ShelfId,
ShelfCode = mci.ShelfCode,
ShelfType = mci.ShelfType,
LocationArea = li.LocationArea,
LocationCode = li.LocationCode,
MatCode = mci.MatCode,
MatName = mci.MatName,
MatBatch = mci.MatBatch,
MatSpec = mci.MatSpec,
MatUnit = mci.MatUnit,
MatCustomer = mci.MatCustomer,
MatQty = mci.MatQty,
MatSupplier = mci.MatSupplier,
OrderTypeId = mci.OrderTypeId,
OrderTypeName = mci.OrderTypeName,
OrderNumber = mci.OrderNumber,
StationCode = mci.StationCode,
ModifyUser = mci.ModifyUser,
ModifyTime = mci.ModifyTime
});
//分页
var totalCount = await recordsQueryable.CountAsync();
var records = await recordsQueryable
.OrderByDescending(mci => mci.Id)
.Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize)
.ToListAsync();
//生成序号
for (int i = 0; i < records.Count; i++)
{
records[i].RowNumber = (request.PageNumber - 1) * request.PageSize + i + 1;
}
return new PageQueryResponse<MatDetailCurrentInfoModel>()
{
Code = 200,
Message = $"success",
Data = new PageQueryResponseData<MatDetailCurrentInfoModel>()
{
TotalCount = totalCount,
MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize),
Count = records.Count,
Lists = records.ToList()
}
};
}
catch (Exception ex)
{
return new PageQueryResponse<MatDetailCurrentInfoModel>()
{
Code = 300,
Message = $"操作失败:{ex.Message}",
};
}
}
public async Task<ResponseCommon<object>> updateMatDetailCurrentInfo(AddLocaionInfoRequest<MatDetailCurrentInfo> request)
{
try
{
var matDetailCurrentInfo = await DbHelp.db.Queryable<MatDetailCurrentInfo>() //.Where(t => t.MatDetailCurrentCode == request.MatDetailCurrentInfo.MatDetailCurrentCode)
.Where(t => t.Id == request.LocationInfo.Id)
.FirstAsync();
if (matDetailCurrentInfo == null)
{
return new ResponseCommon<Object>
{
Code = 205,
Message = $"更新位置信息失败:此条数据不存在,请确认!",
Data = null
};
}
DbHelp.db.BeginTran();
//新增数据修改记录表
var historyInfo = new MatDetailHistoryInfo()
{
ShlefId = matDetailCurrentInfo.ShelfId,
ShelfType = matDetailCurrentInfo.ShelfType,
ShelfCode = matDetailCurrentInfo.ShelfCode,
MatCode = matDetailCurrentInfo.MatCode,
MatName = matDetailCurrentInfo.MatName,
MatBatch = matDetailCurrentInfo.MatBatch,
MatSpec = matDetailCurrentInfo.MatSpec,
MatCustomer = matDetailCurrentInfo?.MatCustomer,
MatSupplier = matDetailCurrentInfo?.MatSupplier,
BeforeQty = matDetailCurrentInfo.MatQty,
AfterQty = request.LocationInfo.MatQty,
ModifyTime = DateTime.Now,
ModifyUser = request.UserName,
RecordType = RecordTypeEnum.,
FunctionType = FunctionTypeEnum.,
};
await DbHelp.db.Insertable(historyInfo).ExecuteCommandAsync();
//更新货架存量数据
matDetailCurrentInfo.MatQty = request.LocationInfo.MatQty;
matDetailCurrentInfo.ModifyUser = request.UserName;
matDetailCurrentInfo.ModifyTime = DateTime.Now;
var rowNum = await DbHelp.db.Updateable(matDetailCurrentInfo).ExecuteCommandAsync();
if (rowNum == 0)
{
DbHelp.db.RollbackTran();
return new ResponseCommon<Object>
{
Code = 201,
Message = $"更新货架存量信息失败:请重试!",
Data = null
};
}
else
{
DbHelp.db.CommitTran();
DataProcessManager.UpdateShelfStatus();
return new ResponseCommon<Object>
{
Code = 200,
Message = $"更新货架存量信息成功!",
Data = null
};
}
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
var response = new ResponseCommon<Object>
{
Code = 300,
Message = $"更新货架存量信息失败:{ex.Message}",
Data = null
};
return response;
}
}
public async Task<ResponseCommon<object>> deleteMatDetailCurrentInfo(DeleteInfosRequest request)
{
//先查询出具体的数据
var matDetailCurrentInfos = await DbHelp.db.Queryable<MatDetailCurrentInfo>()
.Where(t => request.needDeleteIds.Contains(t.Id))
.ToListAsync();
//执行删除
try
{
DbHelp.db.BeginTran();
//新增数据删除记录
foreach (var matDetailCurrentInfo in matDetailCurrentInfos)
{
var historyInfo = new MatDetailHistoryInfo()
{
ShlefId = matDetailCurrentInfo.ShelfId,
ShelfType = matDetailCurrentInfo.ShelfType,
ShelfCode = matDetailCurrentInfo.ShelfCode,
MatCode = matDetailCurrentInfo.MatCode,
MatName = matDetailCurrentInfo.MatName,
MatBatch = matDetailCurrentInfo.MatBatch,
MatSpec = matDetailCurrentInfo.MatSpec,
MatCustomer = matDetailCurrentInfo?.MatCustomer,
MatSupplier = matDetailCurrentInfo?.MatSupplier,
BeforeQty = matDetailCurrentInfo.MatQty,
AfterQty = 0,//删除数据 为0
ModifyTime = DateTime.Now,
ModifyUser = request.UserName,
RecordType = RecordTypeEnum.,
FunctionType = FunctionTypeEnum.,
};
await DbHelp.db.Insertable(historyInfo).ExecuteCommandAsync();
}
var deleteRows = await DbHelp.db.Deleteable(matDetailCurrentInfos).ExecuteCommandAsync();
DbHelp.db.CommitTran();
DataProcessManager.UpdateShelfStatus();
return new ResponseCommon<Object>
{
Code = 200,
Message = $"已删除{deleteRows}条数据!",
Data = null
};
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
var response = new ResponseCommon<Object>
{
Code = 300,
Message = $"操作失败:{ex.Message}",
Data = null
};
return response;
}
}
/// <summary>
/// 批量导入物料绑定关系
/// </summary>
/// <param name="lists"></param>
/// <param name="userName"></param>
/// <param name="deviceType"></param>
/// <returns></returns>
public async Task<ResponseCommon<List<string>>> importMatDetailCurrentInfo(List<MatDetailCurrentInfoImportModel> lists, string userName, string deviceType, string stationCode)
{
#region
////工位校验 工位是否有货架校验
//var station = await DbHelp.db.Queryable<LocationInfo>()
// .Where(t => t.LocationCode == stationCode && t.IsEnable == true)
// .FirstAsync();
//if (station == null)
//{
// return new ResponseCommon<List<string>>()
// {
// Code = 201,
// Message = $"导入失败:工位[{stationCode}]不存在或已被禁用!",
// Data = null,
// };
//}
//var shelfInfo = await DbHelp.db.Queryable<ShelfInfo>()
// .Where(t => (t.TransStatus == TransStatusEnum.静止 && t.CurrentLocationId == station.Id) ||
// t.TransStatus == TransStatusEnum.运输中 && t.DestinationLocationId == station.Id)
// .Where(t => t.IsEnable)
// .FirstAsync();
//if (shelfInfo == null)
//{
// return new ResponseCommon<List<string>>()
// {
// Code = 201,
// Message = $"导入失败:当前工位不存在货架,请呼叫货架后再进行操作!",
// Data = null,
// };
//}
//货架编码校验
var shelfCodes = lists.Select(t => t.).Distinct().ToList();
var shelfInfosInDb = await DbHelp.db.Queryable<ShelfInfo>()
.Where(t => shelfCodes.Contains(t.ShelfCode))
.Where(t => t.IsEnable)
.ToListAsync();
if (shelfInfosInDb == null)
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:货架编码无效!请重试!",
Data = null,
};
}
//判断如果导入表中的货架编码数量与数据库中有效的货架数量不一致证明中间有无效的货架编码
if (shelfInfosInDb != null && shelfInfosInDb.Count < shelfCodes.Count)
{
var shelfCodesInDb = shelfInfosInDb.Select(t => t.ShelfCode).ToList();
shelfCodes.RemoveAll(t => shelfCodesInDb.Contains(t));
if (shelfCodes.Count > 0)
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:以下货架编码无效!\r\n{string.Join(",", shelfCodes)}",
Data = null,
};
}
}
//单据类型校验 物料类型数量较小 不会对内存造成负担
var orderTypesInDb = await DbHelp.db.Queryable<OrderTypeInfo>()
.ToListAsync();
var orderTypeNamesInDb = orderTypesInDb.Select(t => t.OrderTypeName)
.ToList();
//数量、物料编码等必填项的校验
foreach (var matDetailCurrentInfo in lists)
{
if (matDetailCurrentInfo. == null || matDetailCurrentInfo. <= 0)
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:数量应该大于0!",
Data = null,
};
}
if (string.IsNullOrEmpty(matDetailCurrentInfo.))
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:物料编码必填!",
Data = null,
};
}
if (!string.IsNullOrEmpty(matDetailCurrentInfo.) && !orderTypeNamesInDb.Contains(matDetailCurrentInfo.))
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:单据类型[{matDetailCurrentInfo.单据类型}]无效!",
Data = null,
};
}
//物料批次
//如果未填写 默认为当前日期
matDetailCurrentInfo. = matDetailCurrentInfo..Trim();
if (string.IsNullOrEmpty(matDetailCurrentInfo.))
{
matDetailCurrentInfo. = DateTime.Now.ToString("yyMMdd");
}
//如果填写 校验其必须为6位数字
else
{
if (!Regex.IsMatch(matDetailCurrentInfo., @"^\d{6}$"))
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:批次应输入六位数字!\r\n如20250101",
Data = null,
};
}
}
//不校验货架
//if (!string.IsNullOrEmpty(matDetailCurrentInfo.货架编码) && matDetailCurrentInfo.货架编码 == shelfInfo.ShelfCode)
//{
// return new ResponseCommon<List<string>>()
// {
// Code = 201,
// Message = $"导入失败:货架[{matDetailCurrentInfo.货架编码}]不是当前工位的货架!",
// Data = null,
// };
//}
}
#region
//物料编码校验 物料编码的数据可能比较多 所以有可能会对服务器内存造成负担所以采用以下形式进行校验
var matCodes = lists.Select(t => t.)
.Distinct()
.ToList();
var matBaseInfoInDb = await DbHelp.db.Queryable<MatBaseInfo>()
.Where(t => matCodes.Contains(t.MatCode))
.Where(t => t.IsEnable == true)
.ToListAsync();
if (matBaseInfoInDb == null)
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:请重试!",
Data = null,
};
}
//判断如果导入表中的物料编码数量与数据库中有效的编码数量不一致证明中间有无效的物料编码
if (matBaseInfoInDb != null && matBaseInfoInDb?.Count < matCodes.Count)
{
var matCodesInDb = matBaseInfoInDb.Select(t => t.MatCode.ToUpper()).ToList();
matCodes.RemoveAll(t => matCodesInDb.Contains(t.ToUpper()));
if (matCodes.Count > 0)
{
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = $"导入失败:以下物料编码无效!\r\n{string.Join(",", matCodes)}",
Data = null,
};
}
}
#endregion
#endregion
#region
try
{
await DbHelp.db.BeginTranAsync();
foreach (var info in lists)
{
var matBaseInfo = matBaseInfoInDb?.Where(t => t.MatCode.ToUpper() == info..ToUpper() || t.MatCode.ToLower() == info..ToLower()).First();
var shelfInfo = shelfInfosInDb?.Where(t => t.ShelfCode == info.).First();
var orderType = orderTypesInDb?.Where(t => t.OrderTypeName == info.).FirstOrDefault();
//应该是不能走进的分支
if (matBaseInfo == null || shelfInfo == null)
{
continue;
}
var matDetailCurrentInfo = new MatDetailCurrentInfo()
{
ShelfId = shelfInfo.Id,
ShelfCode = shelfInfo.ShelfCode,
ShelfType = shelfInfo.ShelfTypeName,
MatCode = matBaseInfo.MatCode,
MatName = matBaseInfo.MatName,
MatBatch = info.,
MatSpec = matBaseInfo.MatSpec,
MatUnit = matBaseInfo.MatUnit,
MatSupplier = matBaseInfo.MatSupplier,
MatCustomer = matBaseInfo.MatCustomer,
MatQty = info..GetValueOrDefault(),
OrderTypeId = orderType?.Id,
OrderTypeName = orderType?.OrderTypeName,
OrderNumber = info.,
StationCode = stationCode,
ModifyUser = userName,
};
await DbHelp.db.Insertable(matDetailCurrentInfo).ExecuteCommandAsync();
var historyInfo = new MatDetailHistoryInfo()
{
ShlefId = matDetailCurrentInfo.ShelfId,
ShelfType = matDetailCurrentInfo.ShelfType,
ShelfCode = matDetailCurrentInfo.ShelfCode,
MatCode = matDetailCurrentInfo.MatCode,
MatName = matDetailCurrentInfo.MatName,
MatBatch = matDetailCurrentInfo.MatBatch,
MatSpec = matDetailCurrentInfo.MatSpec,
MatCustomer = matDetailCurrentInfo?.MatCustomer,
MatSupplier = matDetailCurrentInfo?.MatSupplier,
BeforeQty = 0,
AfterQty = matDetailCurrentInfo.MatQty,
ModifyTime = DateTime.Now,
ModifyUser = userName,
RecordType = RecordTypeEnum.,
FunctionType = FunctionTypeEnum.,
};
await DbHelp.db.Insertable(historyInfo).ExecuteCommandAsync();
}
await DbHelp.db.CommitTranAsync();
DataProcessManager.UpdateShelfStatus();
return new ResponseCommon<List<string>>()
{
Code = 200,
Message = "导入数据成功",
Data = null
};
}
catch (Exception ex)
{
await DbHelp.db.RollbackTranAsync();
var ErrList = new List<string>
{
ex.Message
};
return new ResponseCommon<List<string>>()
{
Code = 201,
Message = "导入失败",
Data = ErrList
};
}
#endregion
}
}
}