You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

924 lines
39 KiB

using System;
using System.Collections.Generic;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using Microsoft.AspNetCore.Mvc;
using WY.NewJit.Common;
using WY.NewJit.EntityFrameworkCore;
using Shouldly;
using Volo.Abp.BlobStoring;
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Data;
using Microsoft.AspNetCore.Authorization;
using WY.NewJit.Extends.PaiGe;
using Volo.Abp;
using Magicodes.ExporterAndImporter.Core.Models;
namespace WY.NewJit.MsgBaseData
{
/// <summary>
/// 总成配置应用服务实现
/// </summary>
[Route("api/newjit/assembly-cfg-erp")]
[ApiExplorerSettings(GroupName = SwaggerGroupConsts.基础数据)]
public class AssemblyCfgErpAppService : ApplicationService, IAssemblyCfgErpAppService
{
/// <summary>
/// 总成组
/// </summary>
private readonly IRepository<AssemblyCfgGroup, Guid> _assemblyCfgGroupRepository;
/// <summary>
/// ERP总成仓储
/// </summary>
private readonly IRepository<AssemblyCfgErp, Guid> _assemblyCfgErpRepository;
/// <summary>
/// 结算件仓储
/// </summary>
private readonly IRepository<AssemblyCfgPart, Guid> _assemblyCfgPartRepos;
/// <summary>
/// 日志
/// </summary>
private ILogger<AssemblyCfgErpAppService> _logger;
/// <summary>
/// Dapper仓储
/// </summary>
private readonly NewJitDapperRepository _newJitDapperRepository;
/// <summary>
/// BLOB存储
/// </summary>
private readonly IBlobContainer<OurFileContainer> _blobContainer;
/// <summary>
/// 总成领域服务
/// </summary>
private readonly AssemblyDomainService _assemblyDomainService;
/// <summary>
/// 零件仓储
/// </summary>
private readonly IRepository<PartCfg, Guid> _partCfgRepository;
/// <summary>
/// 派格版本物料库扩展
/// </summary>
private readonly IRepository<MaterialExt, Guid> _materialExtRepository;
/// <summary>
/// 跨进程全局配置领域服务
/// </summary>
private readonly GlobalSettingsDomainService _globalSettingsDomainService;
/// <summary>
/// 错误信息前缀
/// </summary>
private string _errorMessagePrefix
{
get
{
return System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + ".";
}
}
private const string chkSql = @"
SELECT top 1 v.Id
FROM FisAssemblyCfgVehicle AS v INNER JOIN
FisAssemblyCfgVehicleChild AS vc ON v.Id = vc.AssemblyCfgVehicleId INNER JOIN
FisAssemblyCfgErp AS e ON vc.ErpAssemblyId = e.Id
WHERE e.IsDeleted = 0 and e.Id = '{0}'
";
/// <summary>
/// 构造函数
/// </summary>
public AssemblyCfgErpAppService(
IRepository<AssemblyCfgErp, Guid> assemblyCfgErpRepository,
ILogger<AssemblyCfgErpAppService> logger,
NewJitDapperRepository newJitDapperRepository,
IRepository<AssemblyCfgPart, Guid> assemblyCfgPartRepos,
IBlobContainer<OurFileContainer> blobContainer,
AssemblyDomainService assemblyDomainService,
IRepository<PartCfg, Guid> partCfgRepository,
IRepository<MaterialExt, Guid> materialExtRepository,
GlobalSettingsDomainService globalSettingsDomainService,
IRepository<AssemblyCfgGroup, Guid> assemblyCfgGroupRepository
)
{
_assemblyCfgErpRepository = assemblyCfgErpRepository;
_logger = logger;
_newJitDapperRepository = newJitDapperRepository;
_assemblyCfgPartRepos = assemblyCfgPartRepos;
_blobContainer = blobContainer;
_assemblyDomainService = assemblyDomainService;
_partCfgRepository = partCfgRepository;
_materialExtRepository = materialExtRepository;
_globalSettingsDomainService = globalSettingsDomainService;
_assemblyCfgGroupRepository = assemblyCfgGroupRepository;
}
#region 私有方法
/// <summary>
/// 根据筛选条件获取实体列表
/// </summary>
private async Task<PagedResultDto<AssemblyCfgErpDto>> QueryByConditionAsync(QueryAssemblyCfgErpDto input, PagedAndSortedBase page)
{
PagedResultDto<AssemblyCfgErpDto> ret = new PagedResultDto<AssemblyCfgErpDto>();
string sqlCnt = @"
select * from
(
select count(*) as cnt
from FisAssemblyCfgErp a
join FisAssemblyCfgGroup g on g.Id = a.GroupId
where g.IsDeleted = 0 and g.IsDisable <> 1 {0}
) t
";
string sql = @"
select * from
(
select ROW_NUMBER() OVER(order by a.[CreationTime]) as row_number,
a.Id, a.ErpAssemblyCode, a.ErpAssemblyName, a.ErpAssemblyVersion,
g.GroupCode, g.VehicleModel, g.IsDisable, g.CreationTime
from FisAssemblyCfgErp a
join FisAssemblyCfgGroup g on g.Id = a.GroupId
where g.IsDeleted = 0 and g.IsDisable <> 1 {0}
) t where row_number between {1} and {2}
";
string where = GetSqlWhere(input);
sqlCnt = string.Format(sqlCnt, where);
ret.TotalCount = await _newJitDapperRepository.GetSingleBySqlAsync<int>(sqlCnt);
//计算分页
int fromRec = page.SkipCount + 1;
int ToRec = page.SkipCount + page.MaxResultCount;
sql = string.Format(sql, where, fromRec, ToRec);
var lst = await _newJitDapperRepository.GetListBySqlAsync<AssemblyCfgErpDto>(sql);
ret.Items = lst;
return ret;
}
/// <summary>
/// 根据筛选条件获取导出实体列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<List<ExportErpAssemblyDto>> ExportByConditionAsync(QueryAssemblyCfgErpDto input)
{
List<ExportErpAssemblyDto> ret = new List<ExportErpAssemblyDto>();
string sql = @"
select ROW_NUMBER() OVER(order by a.[CreationTime]) as row_number,
a.Id, g.GroupCode, a.ErpAssemblyCode, a.ErpAssemblyName,
p.PartCode, pc.PartName, p.PartNum,
g.VehicleModel, g.IsDisable, g.CreationTime
from FisAssemblyCfgErp a
join FisAssemblyCfgGroup g on g.Id = a.GroupId
join FisAssemblyCfgPart p on a.Id = p.AssemblyCfgErpId
left join FisPartCfg pc on p.PartCode = pc.PartCode
where g.IsDeleted = 0 and g.IsDisable <> 1 {0}
";
string where = GetSqlWhere(input);
sql = string.Format(sql, where);
ret = await _newJitDapperRepository.GetListBySqlAsync<ExportErpAssemblyDto>(sql);
return ret;
}
private static string GetSqlWhere(QueryAssemblyCfgErpDto input)
{
string where = "";
if (!string.IsNullOrEmpty(input.ErpAssemblyName))
{
where += string.Format(" and a.ErpAssemblyName like '%{0}%'", input.ErpAssemblyName);
}
if (!string.IsNullOrEmpty(input.ErpAssemblyCode))
{
where += string.Format(" and a.ErpAssemblyCode like '%{0}%'", input.ErpAssemblyCode);
}
if (!string.IsNullOrEmpty(input.VehicleModelCode))
{
where += string.Format(" and g.VehicleModel = '{0}'", input.VehicleModelCode);
}
if (input.BeginCreateTime != null)
{
where += string.Format(" and g.CreationTime >= '{0}'", ((DateTime)input.BeginCreateTime).ToString("yyyy-MM-dd HH:mm:ss"));
}
if (input.EndCreateTime != null)
{
where += string.Format(" and g.CreationTime <= '{0}'", ((DateTime)input.EndCreateTime).ToString("yyyy-MM-dd HH:mm:ss"));
}
if (input.GroupCode != null)
{
where += string.Format(" and g.GroupCode like '%{0}%'", input.GroupCode);
}
return where;
}
/// <summary>
/// 两个集合比较
/// </summary>
/// <param name="sourceLst"></param>
/// <param name="targetLst"></param>
/// <returns></returns>
private bool CompareTwoCollection(List<AssemblyCfgPart> sourceLst, List<AssemblyCfgPart> targetLst)
{
if (sourceLst == null || targetLst == null || sourceLst.Count == 0 || targetLst.Count == 0)
{
return false;
}
if (sourceLst.Count != targetLst.Count)
{
return false;
}
//将目标对象转换成和源对象一样的类型 AssemblyCfgErp2PartDto to BillM100Part
var srcOrdLst = sourceLst.OrderBy(itm => itm.PartCode).ThenBy(itm => itm.PartNum).ToList();
var tarOrdLst = targetLst.OrderBy(itm => itm.PartCode).ThenBy(itm => itm.PartNum).ToList();
bool isEqual = srcOrdLst.SequenceEqual(tarOrdLst, new AssemblyCfgPartListEquality());
return isEqual;
}
#endregion
#region 公共方法
/// <summary>
/// 根据筛选条件获取分页实体列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
[UnitOfWork(false)]
[Route("list")]
public virtual async Task<PagedResultDto<AssemblyCfgErpDto>> GetErpAssemblyListAsync(QueryAssemblyCfgErpDto input)
{
_logger.LogDebug(_errorMessagePrefix + "GetErpAssemblyListAsync 进入");
try
{
PagedResultDto<AssemblyCfgErpDto> ret = await QueryByConditionAsync(input, (PagedAndSortedBase)input);
return ret;
}
catch (Exception ex)
{
string errMsg = _errorMessagePrefix + "GetErpAssemblyListAsync 执行出错:" + ex.Message;
_logger.LogError(errMsg);
return new PagedResultDto<AssemblyCfgErpDto>(0, new List<AssemblyCfgErpDto>());
}
}
/// <summary>
/// 按主键获取唯一实体
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
[Route("{id}")]//obj/
public virtual async Task<ObjectResultDto<AssemblyCfgErpDto>> GetErpAssemblyAsync(Guid id)
{
_logger.LogDebug(_errorMessagePrefix + "GetAsync 进入");
ObjectResultDto<AssemblyCfgErpDto> ret = new ObjectResultDto<AssemblyCfgErpDto>();
try
{
AssemblyCfgErp sourceObj = await _assemblyCfgErpRepository.GetAsync(id);
AssemblyCfgErpDto targetObj = ObjectMapper.Map<AssemblyCfgErp, AssemblyCfgErpDto>(sourceObj);
ret.Item = targetObj;
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "GetAsync 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
/// <summary>
/// 添加实体
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
[Route("")]//create
public virtual async Task<ObjectResultDto<Guid>> CreateErpAssemblyAsync(CreateUpdateAssemblyCfgErpDto input)
{
_logger.LogDebug(_errorMessagePrefix + "CreateAsync 进入");
ObjectResultDto<Guid> ret = new ObjectResultDto<Guid>();
try
{
int maxVer = _assemblyCfgErpRepository.Any() ? _assemblyCfgErpRepository.Max(itm => itm.ErpAssemblyVersion) : 0;
AssemblyCfgErp obj = ObjectMapper.Map<CreateUpdateAssemblyCfgErpDto, AssemblyCfgErp>(input);
obj.SetErpAssemblyVersion(++maxVer);
foreach (var childObj in obj.Details)
{
childObj.SetId(GuidGenerator.Create());
}
AssemblyCfgErp obj2 = await _assemblyCfgErpRepository.InsertAsync(obj);
_globalSettingsDomainService.SetSetting(GlobalSettingsNameEnum., true);
ret.Item = obj2.Id; //返回添加对象的主键
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "CreateAsync 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
/// <summary>
/// 修改实体
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpPut]
[UnitOfWork]
[Route("{id}")]//update/
public virtual async Task<ObjectResultDto> UpdateErpAssemblyAsync(Guid id, CreateUpdateAssemblyCfgErpDto input)
{
_logger.LogDebug(_errorMessagePrefix + "UpdateAsync 进入");
ObjectResultDto ret = new ObjectResultDto();
try
{
#region 校验
string sql = string.Format(chkSql, id.ToString());
Guid? vid = _newJitDapperRepository.GetSingleBySql<Guid?>(sql, true);
if (vid != null)
{
throw new BusinessException("1001", "当前ERP总成已经绑定单据,不能删除!");
}
#endregion
AssemblyCfgErp targetObj = await _assemblyCfgErpRepository.GetAsync(id);
await _assemblyCfgPartRepos.DeleteManyAsync(targetObj.Details); //先删除子实体列表
ObjectMapper.Map<CreateUpdateAssemblyCfgErpDto, AssemblyCfgErp>(input, targetObj);
await _assemblyCfgErpRepository.UpdateAsync(targetObj);
await _assemblyCfgPartRepos.InsertManyAsync(targetObj.Details); //再添加子实体列表
_globalSettingsDomainService.SetSetting(GlobalSettingsNameEnum., true);
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "UpdateAsync 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
/// <summary>
/// 删除实体
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[UnitOfWork]
[HttpDelete]
[Route("{id}")]//delete/
public virtual async Task<ObjectResultDto> DeleteErpAssemblyAsync(string id)
{
_logger.LogDebug(_errorMessagePrefix + "DeleteAsync 进入");
ObjectResultDto ret = new ObjectResultDto();
try
{
List<Guid> idLst = ServerHelper.GetGuidListByStr(id);
foreach (Guid item in idLst)
{
#region 校验
string sql = string.Format(chkSql, item.ToString());
Guid? vid = _newJitDapperRepository.GetSingleBySql<Guid?>(sql, true);
if (vid != null)
{
throw new BusinessException("1001", "当前ERP总成已经绑定单据,不能删除!");
}
#endregion
var sourceObj = await _assemblyCfgErpRepository.GetAsync(item);
if (sourceObj != null)
{
await _assemblyCfgPartRepos.DeleteManyAsync(sourceObj.Details);
await _assemblyCfgErpRepository.DeleteAsync(item);
}
}
_globalSettingsDomainService.SetSetting(GlobalSettingsNameEnum., true);
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "DeleteAsync 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
/// <summary>
/// 导出信息
/// </summary>
/// <param name="input">导出查询条件</param>
/// <returns>执行成功返回真</returns>
[UnitOfWork(false)]
[HttpPost]
[Route("export")]
public virtual async Task<ObjectResultDto<string>> ExportErpAssemblyAsync(QueryAssemblyCfgErpDto input)
{
_logger.LogDebug(_errorMessagePrefix + "ExportErpAssemblyAsync 进入");
ObjectResultDto<string> ret = new ObjectResultDto<string>();
try
{
input.SkipCount = 0;
input.MaxResultCount = 50000;
List<ExportErpAssemblyDto> items = await ExportByConditionAsync(input);
//将实体列表转换成excel文件流
IExporter exporter = new ExcelExporter();
byte[] byteArr = await exporter.ExportAsByteArray<ExportErpAssemblyDto>(items);
byteArr.ShouldNotBeNull();
//将excel文件流保存到服务器端文件系统
string fileName = string.Format("ERP总成配置_{0}.xlsx", Guid.NewGuid().ToString());
await _blobContainer.SaveAsync(fileName, byteArr);
ret.Item = fileName;
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "ExportErpAssemblyAsync 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
/// <summary>
/// 导入ERP总成【派格版本】
/// </summary>
/// <param name="files">导入文件</param>
/// <returns>执行成功返回真</returns>
[HttpPost]
[Route("import")]
[DisableRequestSizeLimit]
public virtual async Task<ObjectResultDto<string>> ImportErpAssemblyAsync([FromForm] IFormFileCollection files)
{
_logger.LogDebug(_errorMessagePrefix + "ImportErpAssemblyAsync 进入");
ObjectResultDto<string> ret = new ObjectResultDto<string>();
try
{
List<MaterialExt> material3Lst = await _materialExtRepository.Where(itm => itm.MaterialType == "3").ToListAsync();
List<PartCfg> partCfgLst = await _partCfgRepository.GetListAsync(); //取结算件信息列表
List<ErpAssemblyInfo2Part> ass2partLst = new List<ErpAssemblyInfo2Part>();
using (var memoryStream = new MemoryStream())
{
//保存到内存流
IFormFile file = files[0];
await file.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(memoryStream, Encoding.Default);
string strLine = ""; //记录每次读取的一行记录
string[] aryLine = null; //记录每行记录中的各字段内容
int columnCount = 0; //标示列数
//遍历文件行
while ((strLine = sr.ReadLine()) != null)
{
if (strLine.IsNullOrEmpty())
{
continue;
}
if (strLine.Contains('�'))
{
ret.Message = "导入文件的格式不对,请将其转换成utf-8格式后再导入";
ret.Status = false;
return ret;
}
aryLine = strLine.Split(" ");
columnCount = aryLine.Count();
if (columnCount == 0)
{
continue;
}
if (columnCount < 14)
{
ret.Message = "当前行的列数小于14,行号:" + aryLine[0];
ret.Status = false;
return ret;
}
ErpAssemblyInfo2Part ass2partObj = new ErpAssemblyInfo2Part();
ass2partObj.ErpAssemblyCode = aryLine[1].Trim();
ass2partObj.ErpAssemblyName = aryLine[2].Trim();
//从物料表取车型,操作员导入BOM时已经在SAP中录入物料了
MaterialExt materialObj = material3Lst.FirstOrDefault(itm => itm.MaterialNum == ass2partObj.ErpAssemblyCode);
if (materialObj != null)
{
ass2partObj.VehicleModel = materialObj.VehicleModel;
ass2partObj.MaterialMemo = materialObj.MaterialMemo?.Replace(" ",""); //SAP分组
}
//将模板中的SAP物料号转换成客户零件号
string sapMaterialNum = aryLine[11].Trim().Replace(" "," "); //取派格SAP物料号
var partCfgObj = partCfgLst.FirstOrDefault(itm => itm.RelationKey == sapMaterialNum);
if (partCfgObj != null)
{
ass2partObj.PartCode = partCfgObj.PartCode;
ass2partObj.PartCode2 = sapMaterialNum;
}
else
{
ret.Message = $"当前行的SAP物料号在零件信息表没有匹配的客户零件号,行号:{aryLine[0]},SAP物料号:{sapMaterialNum}";
ret.Status = false;
return ret;
}
ass2partObj.PartNum = aryLine[13].TryToDouble();
//数据校验
if (ass2partObj.ErpAssemblyCode == null || ass2partObj.ErpAssemblyCode.Trim() == "")
{
ret.Message = "当前行的ERP总成代码列是空,行号:" + aryLine[0];
ret.Status = false;
return ret;
}
if (ass2partObj.PartCode == null || ass2partObj.PartCode.Trim() == "")
{
if (partCfgObj.IsDisable == true) //不参与解析的也进入BOM, 报文解析时排除
{
}
else
{
ret.Message = "当前行的零件代码列是空,行号:" + aryLine[0] + "对应SAP零件号:" + sapMaterialNum;
ret.Status = false;
return ret;
}
}
if (ass2partObj.PartNum == null || ass2partObj.PartNum == 0)
{
ret.Message = "当前行的零件数量列是空或零,行号:" + aryLine[0];
ret.Status = false;
return ret;
}
ass2partLst.Add(ass2partObj);
}
}
//取Erp总成
List<AssemblyCfgErp> erpDataLst = await _assemblyCfgErpRepository.GetListAsync(itm => itm.NewVersionId == null, true);
//总成编码去重
List<string> erpAssemblyCodeLst = ass2partLst
.Where(itm => string.IsNullOrEmpty(itm.ErpAssemblyCode) == false)
.Select(itm => itm.ErpAssemblyCode)
.Distinct()
.ToList();
//校验导入
string repeatMsg = "";
foreach (var erpAssemblyCode in erpAssemblyCodeLst)
{
var partLst = ass2partLst.Where(itm => itm.ErpAssemblyCode == erpAssemblyCode).ToList();
if (partLst.Count() > 0)
{
string erpAssCode = partLst[0].ErpAssemblyCode;
string erpAssName = partLst[0].ErpAssemblyName;
string vehicleModel = partLst[0].VehicleModel;
AssemblyCfgErp erpObj = new AssemblyCfgErp(
GuidGenerator.Create(),
erpAssCode,
erpAssName,
0,
vehicleModel
);
foreach (var partObj in partLst)
{
erpObj.AddChildObject(
GuidGenerator.Create(),
partObj.PartCode,
partObj.PartNum,
partObj.PartCode2
);
}
List<string> repeatLst = _assemblyDomainService.ReturnRepeatErpAssembly(erpObj, erpDataLst, material3Lst); //返回重复总成
foreach (var repeatStr in repeatLst)
{
repeatMsg += repeatStr;
}
}
}
if (repeatMsg.Length > 0)
{
ret.Status = false;
ret.Message = repeatMsg;
return ret;
}
//遍历总成,插入数据库
int maxVer = _assemblyCfgErpRepository.Any() ? _assemblyCfgErpRepository.Max(itm => itm.ErpAssemblyVersion) : 0;
foreach (var erpAssemblyCode in erpAssemblyCodeLst)
{
var partLst = ass2partLst.Where(itm => itm.ErpAssemblyCode == erpAssemblyCode).ToList();
if (partLst.Count() > 0)
{
string erpAssCode = partLst[0].ErpAssemblyCode;
string erpAssName = partLst[0].ErpAssemblyName;
string vehicleModel = partLst[0].VehicleModel;
AssemblyCfgErp erpObj = new AssemblyCfgErp(
GuidGenerator.Create(),
erpAssCode,
erpAssName,
++maxVer,
vehicleModel
);
foreach (var partObj in partLst)
{
erpObj.AddChildObject(
GuidGenerator.Create(),
partObj.PartCode,
partObj.PartNum,
partObj.PartCode2
);
}
AssemblyCfgErp obj2 = await _assemblyCfgErpRepository.InsertAsync(erpObj);
await _assemblyDomainService.RemoveRepeatErpAssembly(obj2, erpDataLst); //删除重复总成
}
}
_globalSettingsDomainService.SetSetting(GlobalSettingsNameEnum., true);
ret.Status = true;
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "ImportErpAssemblyAsync 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
/// <summary>
/// 导入
/// </summary>
/// <param name="files">导入文件</param>
/// <returns>执行成功返回真</returns>
[HttpPost]
[Route("import-erp-assembly-group")]
[DisableRequestSizeLimit]
public virtual async Task<ObjectResultDto> ImportErpAssemblyGroupAsync([FromForm] IFormFileCollection files)
{
_logger.LogDebug(_errorMessagePrefix + "ImportErpAssemblyGroupAsync 进入");
ObjectResultDto ret = new ObjectResultDto();
try
{
#region 导入文件处理
ImportResult<ImportErpAssemblyGroupDto> impResult;
using (var memoryStream = new MemoryStream())
{
//保存到内存流
IFormFile file = files[0];
await file.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
//StreamReader sr = new StreamReader(memoryStream, Encoding.Default);
IImporter importer = new ExcelImporter();
impResult = await importer.Import<ImportErpAssemblyGroupDto>(memoryStream);
if (impResult.HasError)
{
string rowErrStr = "";
foreach (var rowErr in impResult.RowErrors)
{
string fieldErr = string.Concat(rowErr.FieldErrors.Select(itm => $"字段:{itm.Key},错误信息:{itm.Value}"));
rowErrStr += $"行号:{rowErr.RowIndex},{fieldErr}\r\n";
}
string templateErrStr = "";
foreach (var templateErr in impResult.TemplateErrors)
{
string errorLevel = templateErr.ErrorLevel == ErrorLevels.Error ? "错误" : "警告";
templateErrStr += $"错误等级:{errorLevel},列名:{templateErr.ColumnName},需要列:{templateErr.RequireColumnName},错误消息:{templateErr.Message}\r\n";
}
ret.Message = rowErrStr + templateErrStr;
ret.Status = false;
return ret;
}
}
#endregion
#region 数据验证
var srcLst = impResult.Data.AsEnumerable().ToList();
List<MaterialExt> material3Lst = await _materialExtRepository.Where(itm => itm.MaterialType == "3").ToListAsync();
var error= CheckGroup(srcLst, material3Lst);
if (!string.IsNullOrEmpty(error))
{
ret.Message = error;
ret.Status = false;
return ret;
}
#endregion
#region 插入数据
List<AssemblyCfgGroup> assemblyCfgGroups = new List<AssemblyCfgGroup>();
List<AssemblyCfgGroup> deleteAssemblyCfgGroups = new List<AssemblyCfgGroup>();
List<AssemblyCfgErp> assemblyCfgErps = new List<AssemblyCfgErp>();
var groups = srcLst.GroupBy(r => new { r.SpecExplain, r.ColorExplain }).ToList();
foreach (var group in groups)
{
var olditem= await _assemblyCfgGroupRepository.FirstOrDefaultAsync(r=>r.IsDisable==true&&r.SpecExplain== group.Key.SpecExplain.Trim()&& r.ColorExplain == group.Key.ColorExplain.Trim());
if (olditem != null)
{
olditem.IsDisable = false;
deleteAssemblyCfgGroups.Add(olditem);
}
string groupCode = group.Key.SpecExplain + group.Key.ColorExplain;
AssemblyCfgGroup assemblyCfgGroup = new AssemblyCfgGroup(GuidGenerator.Create() , groupCode,"",true);
assemblyCfgGroup.SpecExplain = group.Key.SpecExplain.Trim();
assemblyCfgGroup.ColorExplain = group.Key.ColorExplain.Trim();
foreach (var item in group)
{
var material3 = material3Lst.FirstOrDefault(r => r.MaterialNum == item.MaterialNum.Trim());
AssemblyCfgErp assemblyCfgErp = new AssemblyCfgErp(GuidGenerator.Create());
assemblyCfgErp.ErpAssemblyCode = item.MaterialNum.Trim();
assemblyCfgErp.ErpAssemblyName = material3.MaterialDescription;
assemblyCfgErp.ErpAssemblyVersion = 1;
assemblyCfgErp.GroupCode = groupCode;
assemblyCfgErp.GroupId = assemblyCfgGroup.Id;
assemblyCfgErp.SpecExplain = item.SpecExplain.Trim();
assemblyCfgErp.ColorExplain = item.ColorExplain.Trim();
assemblyCfgErps.Add(assemblyCfgErp);
}
assemblyCfgGroups.Add(assemblyCfgGroup);
}
//插入“导入记录表”
await _assemblyCfgGroupRepository.UpdateManyAsync(deleteAssemblyCfgGroups);//更新总成组
await _assemblyCfgGroupRepository.InsertManyAsync(assemblyCfgGroups);
await _assemblyCfgErpRepository.InsertManyAsync(assemblyCfgErps);
#endregion
ret.Status = true;
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "ImportErpAssemblyGroupAsync 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
private string CheckGroup(List<ImportErpAssemblyGroupDto> srcLst, List<MaterialExt> material3Lst)
{
//验证是否有重复项
string error = "";
var disitem = srcLst.Distinct();
if (disitem.Count() != srcLst.Count())
{
error = "导入数据有重复项,检查后在导入!";
}
if (!string.IsNullOrEmpty(error)) return error;
#region 验证分组是否符合分组规
var checkGroups = srcLst.GroupBy(r => new { r.SpecExplain, r.ColorExplain }).Select(r => new { SpecExplain = r.Key.SpecExplain, ColorExplain = r.Key.ColorExplain, Count = r.Count() });
var errorgroups = checkGroups.Where(r => r.Count != 4).ToList();
foreach (var item in errorgroups)
{
error += $"规格说明【{item.SpecExplain}】,颜色说明【{item.ColorExplain}】,零件数【{item.Count}】不符合分组规则\r\n";
}
if (!string.IsNullOrEmpty(error)) return error;
#endregion
#region 验证零件是否存在(门板)
var partdists = srcLst.Select(r => r.MaterialNum).Distinct();
foreach (var material in partdists)
{
var material3 = material3Lst.FirstOrDefault(r => r.MaterialNum == material);
if (material3 == null)
{
error += $"零件编号【{material}】系统同不存在,请检查后再导入\r\n";
}
}
#endregion
return error;
}
//[UnitOfWork]
//[HttpPost]
//[Route("check")]
//public virtual async Task<ObjectResultDto> CheckErpAssembly(CreateUpdateAssemblyCfgErpDto input)
//{
// _logger.LogDebug(_errorMessagePrefix + "CheckErpAssembly 进入");
// ObjectResultDto ret = new ObjectResultDto();
// if (input.IsCover == true && input.NewVersionId != null)
// {
// Guid gu = (Guid)input.NewVersionId;
// await _assemblyCfgErpRepository.GetAsync(gu);
// }
// else
// {
// Guid gu = (Guid)input.NewVersionId;
// await _assemblyCfgErpRepository.GetAsync(gu);
// }
// _logger.LogDebug(_errorMessagePrefix + "CheckErpAssembly 完成");
// return ret;
//}
/// <summary>
/// 系统初始化时使用,去掉重复的ERP总成
/// </summary>
/// <param name="takeCount"></param>
/// <returns></returns>
[HttpPost]
[Route("remove-repeat")]
public virtual async Task<ObjectResultDto> RemoveRepeatErpAssembly(int takeCount)
{
_logger.LogDebug(_errorMessagePrefix + "RemoveRepeatErpAssembly 进入");
ObjectResultDto ret = new ObjectResultDto();
try
{
await _newJitDapperRepository.ExecuteSqlAsync("update FisAssemblyCfgErp set NewVersionId = null", null, true);
//取Erp总成
List<AssemblyCfgErp> allLst = await _assemblyCfgErpRepository.GetListAsync(true);
List<AssemblyCfgErp> ordLst = allLst.OrderByDescending(itm => itm.ErpAssemblyVersion).ToList();
foreach (AssemblyCfgErp ordItm in ordLst)
{
var filterLst = allLst.Where(itm => itm.ErpAssemblyVersion < ordItm.ErpAssemblyVersion);
foreach (AssemblyCfgErp filterItm in filterLst)
{
//if (filterItm.NewVersionId != null)
//{
// continue;
//}
bool isSame = CompareTwoCollection(ordItm.Details, filterItm.Details);
if (isSame)
{
await _assemblyDomainService.UpdateNewVersionId(filterItm.Id, ordItm.Id); //更新历史数据NewVersionId字段
}
}
}
_logger.LogDebug(_errorMessagePrefix + "RemoveRepeatErpAssembly 完成");
ret.Status = true;
return ret;
}
catch (Exception ex)
{
ret.Status = false;
ret.Message = _errorMessagePrefix + "RemoveRepeatErpAssembly 执行出错:" + ex.Message;
_logger.LogError(ret.Message);
return ret;
}
}
/// <summary>
/// 同步ERP总成(从结算系统)(天合版本)
/// </summary>
/// <param name="takeRecordCount"></param>
/// <returns></returns>
[HttpPost]
[Route("sync-erp-assembly")]
public virtual void SyncErpAssemblyAsync(int takeRecordCount)
{
_assemblyDomainService.SyncErpAssemblyAsync(takeRecordCount).GetAwaiter().GetResult();
RemoveRepeatErpAssembly(takeRecordCount).GetAwaiter().GetResult();
}
#endregion
}
}