Browse Source

[CI SKIP] 印度件价格单

master
mahao 1 year ago
parent
commit
98f7454b2d
  1. 204
      code/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/Prices/PriceListDtoBase.cs
  2. 4
      code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/Prices/PriceListAppServiceBJ.cs
  3. 238
      code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/Prices/PriceListAppServiceYinDu.cs
  4. 19
      code/src/Modules/SettleAccount/src/SettleAccount.Application/SettleAccountApplicationAutoMapperProfile.cs

204
code/src/Modules/SettleAccount/src/SettleAccount.Application.Contracts/Entities/Prices/PriceListDtoBase.cs

@ -413,6 +413,210 @@ namespace Win.Sfs.SettleAccount.Entities.Prices
[Display(Name = "是否作废")] [Display(Name = "是否作废")]
public bool IsCancel { get; set; } public bool IsCancel { get; set; }
} }
#endregion
#region 印度价格
/// <summary>
/// 印度价格
/// </summary>
public class PriceListYinDuDto : AuditedEntityDto<Guid>
{
/// <summary>
/// 客户零件号
/// </summary>
[Display(Name = "客户零件号")]
public string LU { get; set; }
/// <summary>
/// 价格
/// </summary>
[Display(Name = "价格")]
public decimal Price { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[Display(Name = "开始时间")]
public DateTime BeginDate { set; get; }
/// <summary>
/// 结束时间
/// </summary>
[Display(Name = "结束时间")]
public DateTime EndDate { set; get; }
/// <summary>
/// 客户编码
/// </summary>
[Display(Name = "客户编码")]
public string ClientCode { get; set; }
/// <summary>
/// 合同签订时间
/// </summary>
[Display(Name = "合同签订时间")]
public DateTime Date { get; set; }
/// <summary>
/// 合同号
/// </summary>
[Display(Name = "合同号")]
public string ContractNo { get; set; }
/// <summary>
/// 是否作废
/// </summary>
[Display(Name = "是否作废")]
public bool IsCancel { get; set; }
}
/// <summary>
/// 印度价格导出
/// </summary>
[Display(Name = "备件价格")]
public class PriceListYinDuExportDto
{
/// <summary>
/// 客户零件号
/// </summary>
[Display(Name = "客户零件号")]
[ExporterHeader(DisplayName = "客户零件号")]
public string LU { get; set; }
/// <summary>
/// 价格
/// </summary>
[Display(Name = "价格")]
[ExporterHeader(DisplayName = "价格")]
public decimal Price { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[Display(Name = "开始时间")]
[ExporterHeader(DisplayName = "开始时间")]
public DateTime BeginDate { set; get; }
/// <summary>
/// 结束时间
/// </summary>
[Display(Name = "结束时间")]
[ExporterHeader(DisplayName = "结束时间")]
public DateTime EndDate { set; get; }
/// <summary>
/// 客户编码
/// </summary>
[Display(Name = "客户编码")]
[ExporterHeader(DisplayName = "客户编码")]
public string ClientCode { get; set; }
/// <summary>
/// 合同签订时间
/// </summary>
[Display(Name = "合同签订时间")]
[ExporterHeader(DisplayName = "合同签订时间")]
public DateTime Date { get; set; }
/// <summary>
/// 合同号
/// </summary>
[Display(Name = "合同号")]
[ExporterHeader(DisplayName = "合同号")]
public string ContractNo { get; set; }
/// <summary>
/// 是否作废
/// </summary>
[Display(Name = "是否作废")]
[ExporterHeader(DisplayName = "是否已经停用")]
[ValueMapping("否", false)]
[ValueMapping("是", true)]
public bool IsCancel { get; set; }
}
/// <summary>
/// 印度价格导入
/// </summary>
[Importer(HeaderRowIndex = 22)]
public class PriceListYinDuImportDto
{
/// <summary>
/// 合同签订时间
/// </summary>
[ImporterHeader(IsIgnore = true)]
[ExcelImporterHeadDesc(Row = 1, Cell = 1)]
public string Date { get; set; }
/// <summary>
/// 合同号
/// </summary>
[ImporterHeader(IsIgnore = true)]
[ExcelImporterHeadDesc(Row = 2, Cell = 1)]
public string ContractNo { get; set; }
/// <summary>
/// 零件号
/// </summary>
[Display(Name = "零件号")]
[Required(ErrorMessage = "{0}是必填项")]
[ImporterHeader(Name = "Part No.")]
public string PartNo { get; set; }
/// <summary>
/// 价格
/// </summary>
[ImporterHeader(Name = "Total Price")]
public decimal TotalPrice { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[ImporterHeader(Name = "Valid From")]
public DateTime ValidFrom { get; set; }
/// <summary>
/// 结束时间
/// </summary>
[ImporterHeader(Name = "Valid To")]
public DateTime ValidTo { get; set; }
/// <summary>
/// 客户编码
/// </summary>
[ImporterHeader(Name = "Plant")]
public string Plant { get; set; }
/// <summary>
/// ES1
/// </summary>
[ImporterHeader(Name = "ES1")]
public string ES1 { get; set; }
/// <summary>
/// ES2
/// </summary>
[ImporterHeader(Name = "ES2")]
public string ES2 { get; set; }
}
public class PriceListYinDuRequestDto : RequestInputBase
{
[Display(Name = "开始时间")]
public DateTime BeginDate { get; set; }
[Display(Name = "结算时间")]
public DateTime EndDate { get; set; }
[Display(Name = "价格")]
public decimal Price { get; set; }
[Display(Name = "物料编号")]
public string MaterialCode { get; set; }
[Display(Name = "价格类型")]
public int Type { get; set; }
public Guid ParentId { set; get; }
public int FileType { set; get; }
public string Version { set; get; }
public virtual List<FilterCondition> Filters { get; set; } = new List<FilterCondition>();
}
/// <summary>
/// UpdateDto
/// </summary>
public class PriceListYinDuUpdateDto : EntityDto<Guid>
{
/// <summary>
/// 是否作废
/// </summary>
[Display(Name = "是否作废")]
public bool IsCancel { get; set; }
} }
#endregion #endregion
}

4
code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/Prices/PriceListAppServiceBJ.cs

@ -55,10 +55,10 @@ namespace Win.Sfs.SettleAccount.Entities.Prices
/// * 备件价格单筛选 Plant(客户编码) 为(1049)的数据 /// * 备件价格单筛选 Plant(客户编码) 为(1049)的数据
/// * 客户零件号为 PartNo+6个空格+ES1+ES2 /// * 客户零件号为 PartNo+6个空格+ES1+ES2
/// * 根据 合同日期、客户编码、零件号、开始时间、结束时间分组导入(过滤重复数据) /// * 根据 合同日期、客户编码、零件号、开始时间、结束时间分组导入(过滤重复数据)
/// 数据校验 /// * 数据校验
/// * 同一合同日期、客户编码、零件号 不能存在时间交集 /// * 同一合同日期、客户编码、零件号 不能存在时间交集
/// * 判断同一个零件号时间区间是否连续 /// * 判断同一个零件号时间区间是否连续
/// 作废旧合同日期的数据 /// * 作废旧合同日期的数据
/// * 比较新导入的数据和数据库中老数据(同一零件号、旧合同日期的数据修改状态为作废) /// * 比较新导入的数据和数据库中老数据(同一零件号、旧合同日期的数据修改状态为作废)
/// </remarks> /// </remarks>
[HttpPost] [HttpPost]

238
code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/Prices/PriceListAppServiceYinDu.cs

@ -0,0 +1,238 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using EFCore.BulkExtensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Shouldly;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Caching;
using Win.Abp.Snowflakes;
using Win.Sfs.BaseData.ImportExcelCommon;
using Win.Sfs.SettleAccount.CommonManagers;
using Win.Sfs.SettleAccount.Constant;
using Win.Sfs.SettleAccount.Entities.BQ.Dtos;
using Win.Sfs.SettleAccount.ExcelImporter;
using Win.Sfs.SettleAccount.ExportReports;
using Win.Sfs.Shared.RepositoryBase;
namespace Win.Sfs.SettleAccount.Entities.Prices
{
/// <summary>
/// 印度件价格
/// </summary>
[AllowAnonymous]
[Route("api/settleaccount/[controller]/[action]")]
public class PriceListAppServiceYinDu : SettleAccountApplicationBase<PriceListYinDu>
{
/// <summary>
/// 数据上下文
/// </summary>
private readonly SettleAccountDbContext _settleAccountDbContext;
private readonly INormalEfCoreRepository<PriceListYinDu, Guid> _repository;
public PriceListAppServiceYinDu(
SettleAccountDbContext settleAccountDbContext,
INormalEfCoreRepository<PriceListYinDu, Guid> repository,
IDistributedCache<PriceListYinDu> cache,
IExcelImportAppService excelImportService,
ISnowflakeIdGenerator snowflakeIdGenerator,
ICommonManager commonManager
) : base(cache, excelImportService, snowflakeIdGenerator, commonManager)
{
_settleAccountDbContext = settleAccountDbContext;
_repository = repository;
}
#region 导入、导出
/// <summary>
/// 导入
/// </summary>
/// <remarks>
/// <seealso cref="PriceListAppServiceBJ.ImportAsync"/>
/// </remarks>
[HttpPost]
public async Task<IActionResult> ImportAsync([FromForm] IFormFileCollection files, string version)
{
var checkList = new List<ErrorExportDto>();
var _exportImporter = new ExportImporter();
var result = await _exportImporter.UploadExcelImportByHeadDesc<PriceListYinDuImportDto>(files, _excelImportService).ConfigureAwait(false);
var filter = new List<string>
{
"1049"
};
result = result.Where(p => filter.Contains(p.Plant)).ToList();
result.FindAll(t => !string.IsNullOrEmpty(t.ES1) || !string.IsNullOrEmpty(t.ES2)).ForEach(t => t.PartNo = t.PartNo + new string(' ', 6) + t.ES1 + t.ES2);
var newPrice = ObjectMapper.Map<List<PriceListYinDuImportDto>, List<PriceListYinDu>>(result);
newPrice = newPrice.GroupBy(p => new { p.Date, p.ClientCode, p.LU, p.BeginDate, p.EndDate }).Select(p => p.FirstOrDefault()).ToList();
#region 校验
if (newPrice.Any())
{
var query = from item1 in newPrice
join item2 in newPrice
on new { item1.Date, item1.ClientCode, item1.LU } equals new { item2.Date, item2.ClientCode, item2.LU }
where (item1.BeginDate > item2.BeginDate && item1.EndDate < item2.EndDate) || (item2.BeginDate > item1.BeginDate && item2.EndDate < item1.EndDate) || (item1.BeginDate == item2.BeginDate && item1.EndDate != item2.EndDate) || (item1.BeginDate != item2.BeginDate && item1.EndDate == item2.EndDate)
select item1;
var repeat = query.Distinct().ToList();
foreach (var item in repeat)
{
checkList.Add(new ErrorExportDto(string.Empty, string.Empty, string.Empty, string.Empty, item.LU, string.Empty, $"合同号:{item.ContractNo},合同签订时间:{item.Date:yyyy-MM-dd},时间区间存在交集", string.Empty));
}
//foreach (var item in CheckPriceListContinuity(newPrice))
//{
// checkList.Add(new ErrorExportDto(string.Empty, string.Empty, string.Empty, string.Empty, item.LU, string.Empty, $"合同号:{item.ContractNo},合同签订时间:{item.Date:yyyy-MM-dd},时间区间【{item.BeginDate:yyyy-MM-dd}至{item.EndDate:yyyy-MM-dd}】不连续", string.Empty));
//}
}
if (checkList.Count > 0)
{
var fileName = await ExportErrorReportAsync(checkList).ConfigureAwait(false);
return new JsonResult(new { code = ApplicationConsts.ImportFailCode, message = "导入失败", fileName });
}
#endregion
newPrice.ForEach(t => t.IsCancel = true);
newPrice.GroupBy(t => new { t.ClientCode, t.LU })
.SelectMany(t =>
{
var data = t.OrderByDescending(t => t.Date).First().Date;
return t.Where(t => t.Date == data);
})
.ForEach(t => t.IsCancel = false);
var importLus = newPrice.Select(t => t.LU).Distinct().ToList();
var oldPrices = _settleAccountDbContext.Set<PriceListYinDu>()
.Where(t => t.IsCancel == false)
.Where(t => importLus.Contains(t.LU))
.ToList();
//系统中合同日期比导入文件中的合同日期晚
var oldPriceNewDate = from oldPriceItem in oldPrices
from newPriceItem in newPrice.FindAll(t => t.IsCancel == false)
where oldPriceItem.ClientCode == newPriceItem.ClientCode && oldPriceItem.LU == newPriceItem.LU && oldPriceItem.Date > newPriceItem.Date
select new { oldPriceItem, newPriceItem };
oldPrices.ForEach(t => t.IsCancel = true);
if (oldPriceNewDate.Any())
{
oldPrices.FindAll(t => t.IsCancel == true && oldPriceNewDate.Select(t => t.oldPriceItem).Contains(t)).ForEach(t => t.IsCancel = false);
newPrice.FindAll(t => t.IsCancel == false && oldPriceNewDate.Select(t => t.newPriceItem).Contains(t)).ForEach(t => t.IsCancel = true);
}
foreach (var item in newPrice)
{
item.Update(GuidGenerator.Create());
}
using var transaction = await _settleAccountDbContext.Database.BeginTransactionAsync().ConfigureAwait(false);
try
{
await _settleAccountDbContext.BulkUpdateAsync<PriceListYinDu>(oldPrices).ConfigureAwait(false);
await _settleAccountDbContext.BulkInsertAsync<PriceListYinDu>(newPrice).ConfigureAwait(false);
await transaction.CommitAsync().ConfigureAwait(false);
}
catch (Exception)
{
await transaction.RollbackAsync().ConfigureAwait(false);
return new JsonResult(new { Code = 200, Message = "导入失败" });
}
return new JsonResult(new { Code = 200, Message = "导入成功" });
}
/// <summary>
/// 价格表时间是否连续
/// </summary>
private List<PriceListYinDu> CheckPriceListContinuity(List<PriceListYinDu> priceList)
{
var result = new List<PriceListYinDu>();
if (priceList.Count <= 1)
{
return result; // 只有一个或零个价格条目
}
var dateGroups = priceList.GroupBy(t => t.Date);
foreach (var dateGroup in dateGroups)
{
var clientCodeGroups = dateGroup.GroupBy(t => t.ClientCode);
foreach (var clientCodeGroup in clientCodeGroups)
{
if (clientCodeGroup.ToList().Count <= 1)
{
continue;
}
var sortedList = clientCodeGroup.OrderBy(t => t.LU).ThenBy(t => t.BeginDate).ToList();
for (var i = 1; i < sortedList.Count; i++)
{
if (sortedList[i].LU == sortedList[i - 1].LU && sortedList[i].BeginDate != sortedList[i - 1].EndDate.AddDays(1))
{
result.Add(sortedList[i]);
}
}
}
}
return result; // 所有价格时间都连续
}
/// <summary>
/// 导出
/// </summary>
[HttpPost]
public async Task<string> ExportAsync(RequestDto input)
{
string fileName = $"印度件价格_{Guid.NewGuid()}.xlsx";
var entities = await _repository.GetListByFilterAsync(input.Filters, input.Sorting, int.MaxValue, 0, true).ConfigureAwait(false);
var dtos = ObjectMapper.Map<List<PriceListYinDu>, List<PriceListYinDuExportDto>>(entities);
ExportImporter _exportImporter = new ExportImporter();
var result = await _exportImporter.ExcelExporter(dtos).ConfigureAwait(false);
result.ShouldNotBeNull();
await _excelImportService.SaveBlobAsync(new SaveExcelImportInputDto { Name = fileName, Content = result }).ConfigureAwait(false);
return fileName;
}
#endregion
#region CURD
/// <summary>
/// 获取列表
/// </summary>
[HttpPost]
public async Task<PagedResultDto<PriceListYinDuDto>> GetListAsync(RequestDto input)
{
var entities = await _repository.GetListByFilterAsync(input.Filters, input.Sorting, input.MaxResultCount, input.SkipCount, true).ConfigureAwait(false);
var totalCount = await _repository.GetCountByFilterAsync(input.Filters).ConfigureAwait(false);
var dtos = ObjectMapper.Map<List<PriceListYinDu>, List<PriceListYinDuDto>>(entities);
return new PagedResultDto<PriceListYinDuDto>(totalCount, dtos);
}
/// <summary>
/// 修改实体
/// </summary>
[HttpPost]
public async Task<PriceListYinDuDto> UpdateAsync(PriceListYinDuUpdateDto input)
{
var entity = await _settleAccountDbContext.Set<PriceListYinDu>().FindAsync(input.Id).ConfigureAwait(false);
entity.IsCancel = input.IsCancel;
if (entity.IsCancel == false)
{
var existPrices = _settleAccountDbContext.Set<PriceListYinDu>()
.Where(t => t.LU == entity.LU)
.Where(t => t.IsCancel == false)
.Where(t => t.Id != entity.Id)
.ToList();
var existPrice = existPrices.Find(t => (entity.BeginDate >= t.BeginDate && entity.BeginDate < t.EndDate) || (t.BeginDate >= entity.BeginDate && t.BeginDate < entity.EndDate));
if (existPrice != null)
{
throw new UserFriendlyException($"无法启用!此记录启用时间区间与区间【{existPrice.BeginDate:yyyy-MM-dd}至{existPrice.EndDate:yyyy-MM-dd}】存在交集", "400");
}
}
await _settleAccountDbContext.SaveChangesAsync().ConfigureAwait(false);
var dto = ObjectMapper.Map<PriceListYinDu, PriceListYinDuDto>(entity);
return dto;
}
#endregion
}
}

19
code/src/Modules/SettleAccount/src/SettleAccount.Application/SettleAccountApplicationAutoMapperProfile.cs

@ -104,6 +104,7 @@ namespace Win.Sfs.SettleAccount
CreateMapPriceListBJVersion(); CreateMapPriceListBJVersion();
CreateMapPriceListBJ(); CreateMapPriceListBJ();
CreateMapPriceListYinDu();
#endregion #endregion
#region 派格 #region 派格
@ -501,6 +502,24 @@ namespace Win.Sfs.SettleAccount
CreateMap<PriceListBJ, PriceListBJExportDto>().ReverseMap(); CreateMap<PriceListBJ, PriceListBJExportDto>().ReverseMap();
} }
/// <summary>
/// 印度价格
/// </summary>
private void CreateMapPriceListYinDu()
{
CreateMap<PriceListYinDuImportDto, PriceListYinDu>()
.ForMember(x => x.LU, y => y.MapFrom(y => y.PartNo))
.ForMember(x => x.Price, y => y.MapFrom(y => y.TotalPrice))
.ForMember(x => x.BeginDate, y => y.MapFrom(y => y.ValidFrom))
.ForMember(x => x.EndDate, y => y.MapFrom(y => y.ValidTo))
.ForMember(x => x.ClientCode, y => y.MapFrom(y => y.Plant))
.ForMember(x => x.Date, y => y.MapFrom(y => DateTime.ParseExact(y.Date, "dd.MM.yyyy", System.Globalization.CultureInfo.CurrentCulture))); ;
CreateMap<PriceListYinDu, PriceListYinDuDto>().ReverseMap();
CreateMap<PriceListYinDu, PriceListYinDuRequestDto>().ReverseMap();
CreateMap<PriceListYinDu, PriceListYinDuExportDto>().ReverseMap();
}
private void CreateMapInvoiceSettledDiff() private void CreateMapInvoiceSettledDiff()
{ {

Loading…
Cancel
Save