diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/BeiSeSyncAppService.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/BeiSeSyncAppService.cs index b8aac923..0bf26980 100644 --- a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/BeiSeSyncAppService.cs +++ b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/BeiSeSyncAppService.cs @@ -1,28 +1,23 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using SettleAccount.Domain.BQ; -using Win.Sfs.SettleAccount.Entities.BQ.Managers; +using Volo.Abp.Uow; using Win.Sfs.SettleAccount.Entities.BQ.Vmi; using Win.Sfs.SettleAccount.EntityFrameworkCore; -using Win.Sfs.SettleAccount.MaterialRelationships; -using Win.Sfs.Shared.RepositoryBase; namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs; /// /// 备件发运同步 /// -[AllowAnonymous] -[Route("api/settleaccount/[controller]/[action]")] +[ApiExplorerSettings(IgnoreApi = true)] public class BeiSeSyncAppService : JitSeSyncAppService, IJobService { /// /// 构造 /// - public BeiSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext) : base(wmsBJBMPTContext, settleAccountDbContext) + public BeiSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext, SyncExtendManager syncExtendManager) : base(wmsBJBMPTContext, settleAccountDbContext, syncExtendManager) { base.SeSyncConfigInfo = new SeSyncConfig() { @@ -36,8 +31,9 @@ public class BeiSeSyncAppService : JitSeSyncAppService, IJobService }; } - public async Task Invoke(IServiceProvider serviceProvider) + [UnitOfWork(IsDisabled = true)] + public virtual async Task Invoke(IServiceProvider serviceProvider) { - await this.Invoke(); + await this.Invoke().ConfigureAwait(false); } } diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/HandSeSyncAppService.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/HandSeSyncAppService.cs index c767583d..8d2779f8 100644 --- a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/HandSeSyncAppService.cs +++ b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/HandSeSyncAppService.cs @@ -1,11 +1,13 @@ using System; using System.Threading.Tasks; using Coravel.Invocable; +using DocumentFormat.OpenXml.Vml.Spreadsheet; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Volo.Abp.Application.Services; +using Volo.Abp.Uow; namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs; @@ -27,7 +29,8 @@ public class HandSeSyncAppService : ApplicationService /// 同步 /// [HttpPost] - public async Task SyncAsync([FromBody] EnumBusinessType businessType) + [UnitOfWork(IsDisabled = true)] + public virtual async Task SyncAsync([FromBody] EnumBusinessType businessType) { using var scope = this._applicationServices.CreateScope(); IInvocable jitSeSyncAppService = businessType switch diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/HomeAppService.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/HomeAppService.cs deleted file mode 100644 index 6d9619e7..00000000 --- a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/HomeAppService.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Threading.Tasks; -using DocumentFormat.OpenXml.Wordprocessing; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using SettleAccount.Job.Services.Report; -using TaskJob.EventArgs; -using TaskJob.Interfaces; -using Volo.Abp.Application.Services; -using Win.Sfs.SettleAccount.Entities.BQ.Dtos; - -namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs; - -/// -/// 手动同步 -/// -[AllowAnonymous] -[Route("api/settleaccount/[controller]/[action]")] -[ApiExplorerSettings(IgnoreApi = true)] -public class HomeAppService : ApplicationService -{ - private readonly IServiceProvider _applicationServices; - - public HomeAppService(IHost host) - { - _applicationServices = host.Services; - } - - /// - /// 同步 - /// - [HttpPost] - public async Task SyncAsync(JobRequestDto jobRequestDto) - { - await Task.CompletedTask.ConfigureAwait(false); - return "ddd"; - //using var scope = this._applicationServices.CreateScope(); - //IExportJob exportJob = jobDto.businessType switch - //{ - // EnumBusinessType.JisBBAC => scope.ServiceProvider.GetRequiredService(), - // EnumBusinessType.JisHBPO => scope.ServiceProvider.GetRequiredService(), - // EnumBusinessType.MaiDanJianBBAC => scope.ServiceProvider.GetRequiredService(), - // EnumBusinessType.MaiDanJianHBPO => scope.ServiceProvider.GetRequiredService(), - // EnumBusinessType.ZhiGongJianBBAC => scope.ServiceProvider.GetRequiredService(), - // EnumBusinessType.ZhiGongJianHBPO => scope.ServiceProvider.GetRequiredService(), - // EnumBusinessType.BeiJian => scope.ServiceProvider.GetRequiredService(), - // EnumBusinessType.YinDuJian => scope.ServiceProvider.GetRequiredService(), - // _ => throw new ArgumentOutOfRangeException(nameof(jobDto.businessType), $"Not expected direction value: {jobDto.businessType}"), - //}; - //exportJob.ExportFile(jobDto.Id, jobDto.ExportName, jobDto.Propert); - } -} diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/JitSeSyncAppService.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/JitSeSyncAppService.cs index ef43435d..2af2e7d6 100644 --- a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/JitSeSyncAppService.cs +++ b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/JitSeSyncAppService.cs @@ -7,10 +7,8 @@ using Coravel.Invocable; using EFCore.BulkExtensions; using LinqToDB; using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; using SettleAccount.Domain.BQ; using Volo.Abp.Application.Services; -using Win.Sfs.SettleAccount.Entities.BQ.Vmi; using Win.Sfs.SettleAccount.EntityFrameworkCore; using Win.Sfs.SettleAccount.MaterialRelationships; using Win.Sfs.Shared.RepositoryBase; @@ -31,14 +29,20 @@ public class JitSeSyncAppService : ApplicationService, IInvocable /// 数据上下文 /// private readonly SettleAccountDbContext _settleAccountDbContext; + /// + /// 数据上下文 + /// + private readonly SyncExtendManager _syncExtendManager; /// /// 构造 /// - public JitSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext) + public JitSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext, SyncExtendManager syncExtendManager) { _wmsBJBMPTContext = wmsBJBMPTContext; _settleAccountDbContext = settleAccountDbContext; + _syncExtendManager = syncExtendManager; + _syncExtendManager._settleAccountDbContext = settleAccountDbContext; } /// @@ -88,26 +92,6 @@ public class JitSeSyncAppService : ApplicationService, IInvocable } #region 私有方法 - /// - /// 添加零件关系 - /// - private async Task AddNewMaterialRelationshipsAsync(IEnumerable materialRelationships) - { - //新客户零件号和厂内零件号 - var noHaveLuRePartCodes = from item1 in materialRelationships - join item2 in _settleAccountDbContext.Set() - on new { item1.ErpMaterialCode, item1.SettleMaterialCode } equals new { item2.ErpMaterialCode, item2.SettleMaterialCode } - into temp - from item3 in temp.DefaultIfEmpty() - where item3 == null - select item1; - - if (noHaveLuRePartCodes.Any()) - { - await _settleAccountDbContext.BulkInsertAsync(noHaveLuRePartCodes.ToList()).ConfigureAwait(false); - } - } - /// /// 发运数据入库 /// @@ -125,7 +109,7 @@ public class JitSeSyncAppService : ApplicationService, IInvocable if (luRePartCodes.Any()) { var materialRelationships = luRePartCodes.Select(t => new MaterialRelationship(GuidGenerator.Create(), t.FactoryPartCode, "", t.LU, businessType)); - await this.AddNewMaterialRelationshipsAsync(materialRelationships).ConfigureAwait(false); + await _syncExtendManager.AddNewMaterialRelationshipsAsync(materialRelationships).ConfigureAwait(false); } } @@ -161,7 +145,7 @@ public class JitSeSyncAppService : ApplicationService, IInvocable _settleAccountDbContext.Add(syncPositionFlag); } await _settleAccountDbContext.BulkInsertAsync(seDetails).ConfigureAwait(false); - await SaveVmiLogsAsync(seDetails).ConfigureAwait(false); + await _syncExtendManager.SaveVmiLogsAsync(seDetails).ConfigureAwait(false); await _settleAccountDbContext.SaveChangesAsync().ConfigureAwait(false); await transaction.CommitAsync().ConfigureAwait(false); } @@ -172,69 +156,5 @@ public class JitSeSyncAppService : ApplicationService, IInvocable } } } - - /// - /// 保存寄售库Log - /// - private async Task SaveVmiLogsAsync(List seDetails) - { - var deliverSeDetails = seDetails.FindAll(t => t.TransType == EnumDelTransType.发货); - var returnSeDetails = seDetails.FindAll(t => t.TransType == EnumDelTransType.退货); - var dateTimeNow = DateTime.Now; - - var vmiLogList = deliverSeDetails.Select(t => new VmiLog(Guid.NewGuid()) - { - LogType = VmiLogType.Type100, - ChangedQty = t.Qty, - ChangedType = VmiType.In, - ChangedBy = "WMS", - ChangedNumber = t.PN, - ChangedTime = dateTimeNow, - AssembleData = t.AssembleData, - BillTime = t.BillTime, - CustPartCode = t.CustPartCode, - DeliverBillType = t.DeliverBillType, - DeliverSubBillType = t.DeliverSubBillType, - ErpToLoc = t.ToErpLocCode, - OrderNum = t.DnBillNum, - Qty = t.Qty, - ReMark = t.Remark, - RealCode = t.PartCode - }).ToList(); - var returnVmiLogList = returnSeDetails.Select(t => new VmiLog(Guid.NewGuid()) - { - LogType = VmiLogType.Type400, - ChangedQty = t.Qty, - ChangedType = VmiType.In, - ChangedBy = "WMS", - ChangedNumber = t.PN, - ChangedTime = dateTimeNow, - AssembleData = t.AssembleData, - BillTime = t.BillTime, - CustPartCode = t.CustPartCode, - DeliverBillType = t.DeliverBillType, - DeliverSubBillType = t.DeliverSubBillType, - ErpToLoc = t.ToErpLocCode, - OrderNum = t.DnBillNum, - Qty = -t.Qty, - ReMark = t.Remark, - RealCode = t.PartCode - }).ToList(); - vmiLogList.AddRange(returnVmiLogList); - await SaveVmiMessagesAsync(vmiLogList).ConfigureAwait(false); - await _settleAccountDbContext.BulkInsertAsync(vmiLogList).ConfigureAwait(false); - } - - /// - /// 保存寄售库Message - /// - public async Task SaveVmiMessagesAsync(List vmiLogs) - { - var vmiMessages = vmiLogs.Select(t => new VmiMessage(Guid.NewGuid()) - { - Message = JsonConvert.SerializeObject(t) - }).ToList(); - await _settleAccountDbContext.BulkInsertAsync(vmiMessages).ConfigureAwait(false); - } #endregion } diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/SyncExtendManager.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/SyncExtendManager.cs new file mode 100644 index 00000000..ad9534f4 --- /dev/null +++ b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/SyncExtendManager.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EFCore.BulkExtensions; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using SettleAccount.Domain.BQ; +using Volo.Abp.Domain.Services; +using Win.Sfs.SettleAccount.Entities.BQ.Vmi; +using Win.Sfs.SettleAccount.MaterialRelationships; + +namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs; + +/// +/// 同步扩展 +/// +[ApiExplorerSettings(IgnoreApi = true)] +public class SyncExtendManager : DomainService +{ + /// + /// DbContext + /// + public SettleAccountDbContext _settleAccountDbContext; + + public SyncExtendManager(SettleAccountDbContext settleAccountDbContext) + { + _settleAccountDbContext = settleAccountDbContext; + } + + /// + /// 添加零件关系 + /// + public async Task AddNewMaterialRelationshipsAsync(IEnumerable materialRelationships) + { + //新客户零件号和厂内零件号 + var noHaveLuRePartCodes = from item1 in materialRelationships + join item2 in _settleAccountDbContext.Set() + on new { item1.ErpMaterialCode, item1.SettleMaterialCode } equals new { item2.ErpMaterialCode, item2.SettleMaterialCode } + into temp + from item3 in temp.DefaultIfEmpty() + where item3 == null + select item1; + + if (noHaveLuRePartCodes.Any()) + { + await _settleAccountDbContext.BulkInsertAsync(noHaveLuRePartCodes.ToList()).ConfigureAwait(false); + } + } + + /// + /// 保存寄售库Log + /// + public async Task SaveVmiLogsAsync(List seDetails) + { + var deliverSeDetails = seDetails.FindAll(t => t.TransType == EnumDelTransType.发货); + var returnSeDetails = seDetails.FindAll(t => t.TransType == EnumDelTransType.退货); + var dateTimeNow = DateTime.Now; + + var vmiLogList = deliverSeDetails.Select(t => new VmiLog(Guid.NewGuid()) + { + LogType = VmiLogType.Type100, + ChangedQty = t.Qty, + ChangedType = VmiType.In, + ChangedBy = "WMS", + ChangedNumber = t.PN, + ChangedTime = dateTimeNow, + AssembleData = t.AssembleData, + BillTime = t.BillTime, + CustPartCode = t.CustPartCode, + DeliverBillType = t.DeliverBillType, + DeliverSubBillType = t.DeliverSubBillType, + ErpToLoc = t.ToErpLocCode, + OrderNum = t.DnBillNum, + Qty = t.Qty, + ReMark = t.Remark, + RealCode = t.PartCode + }).ToList(); + var returnVmiLogList = returnSeDetails.Select(t => new VmiLog(Guid.NewGuid()) + { + LogType = VmiLogType.Type400, + ChangedQty = t.Qty, + ChangedType = VmiType.In, + ChangedBy = "WMS", + ChangedNumber = t.PN, + ChangedTime = dateTimeNow, + AssembleData = t.AssembleData, + BillTime = t.BillTime, + CustPartCode = t.CustPartCode, + DeliverBillType = t.DeliverBillType, + DeliverSubBillType = t.DeliverSubBillType, + ErpToLoc = t.ToErpLocCode, + OrderNum = t.DnBillNum, + Qty = -t.Qty, + ReMark = t.Remark, + RealCode = t.PartCode + }).ToList(); + vmiLogList.AddRange(returnVmiLogList); + await SaveVmiMessagesAsync(vmiLogList).ConfigureAwait(false); + await _settleAccountDbContext.BulkInsertAsync(vmiLogList).ConfigureAwait(false); + } + + /// + /// 保存寄售库Message + /// + public async Task SaveVmiMessagesAsync(List vmiLogs) + { + var vmiMessages = vmiLogs.Select(t => new VmiMessage(Guid.NewGuid()) + { + Message = JsonConvert.SerializeObject(t) + }).ToList(); + await _settleAccountDbContext.BulkInsertAsync(vmiMessages).ConfigureAwait(false); + } +} diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/YinDuSeSyncAppService.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/YinDuSeSyncAppService.cs index 2ddb2bbb..21f5adc6 100644 --- a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/YinDuSeSyncAppService.cs +++ b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/YinDuSeSyncAppService.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Uow; using Win.Sfs.SettleAccount.Entities.BQ.Vmi; using Win.Sfs.SettleAccount.EntityFrameworkCore; @@ -11,14 +11,13 @@ namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs; /// /// 印度件发运同步 /// -[AllowAnonymous] -[Route("api/settleaccount/[controller]/[action]")] +[ApiExplorerSettings(IgnoreApi = true)] public class YinDuSeSyncAppService : JitSeSyncAppService, IJobService { /// /// 构造 /// - public YinDuSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext) : base(wmsBJBMPTContext, settleAccountDbContext) + public YinDuSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext, SyncExtendManager syncExtendAppService) : base(wmsBJBMPTContext, settleAccountDbContext, syncExtendAppService) { base.SeSyncConfigInfo = new SeSyncConfig() { @@ -32,7 +31,8 @@ public class YinDuSeSyncAppService : JitSeSyncAppService, IJobService }; } - public async Task Invoke(IServiceProvider serviceProvider) + [UnitOfWork(IsDisabled = true)] + public virtual async Task Invoke(IServiceProvider serviceProvider) { await this.Invoke().ConfigureAwait(false); } diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongBBACSeSyncAppService.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongBBACSeSyncAppService.cs index 17d355e0..f9cc921a 100644 --- a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongBBACSeSyncAppService.cs +++ b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongBBACSeSyncAppService.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Uow; using Win.Sfs.SettleAccount.Entities.BQ.Vmi; using Win.Sfs.SettleAccount.EntityFrameworkCore; @@ -11,14 +11,13 @@ namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs; /// /// 直供件BBAC发运同步 /// -[AllowAnonymous] -[Route("api/settleaccount/[controller]/[action]")] +[ApiExplorerSettings(IgnoreApi = true)] public class ZhiGongBBACSeSyncAppService : JitSeSyncAppService, IJobService { /// /// 构造 /// - public ZhiGongBBACSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext) : base(wmsBJBMPTContext, settleAccountDbContext) + public ZhiGongBBACSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext, SyncExtendManager syncExtendManager) : base(wmsBJBMPTContext, settleAccountDbContext, syncExtendManager) { base.SeSyncConfigInfo = new SeSyncConfig() { @@ -32,8 +31,8 @@ public class ZhiGongBBACSeSyncAppService : JitSeSyncAppService, IJobService }; } - [HttpPost] - public async Task Invoke(IServiceProvider serviceProvider) + [UnitOfWork(IsDisabled = true)] + public virtual async Task Invoke(IServiceProvider serviceProvider) { await this.Invoke().ConfigureAwait(false); } diff --git a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongHBPOSeSyncAppService.cs b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongHBPOSeSyncAppService.cs index 3dfb6e9c..ecec0468 100644 --- a/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongHBPOSeSyncAppService.cs +++ b/code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/Syncs/ZhiGongHBPOSeSyncAppService.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Uow; using Win.Sfs.SettleAccount.Entities.BQ.Vmi; using Win.Sfs.SettleAccount.EntityFrameworkCore; @@ -11,14 +11,13 @@ namespace Win.Sfs.SettleAccount.Entities.BQ.Syncs; /// /// 直供件HBPO发运同步 /// -[AllowAnonymous] -[Route("api/settleaccount/[controller]/[action]")] +[ApiExplorerSettings(IgnoreApi = true)] public class ZhiGongHBPOSeSyncAppService : JitSeSyncAppService, IJobService { /// /// 构造 /// - public ZhiGongHBPOSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext) : base(wmsBJBMPTContext, settleAccountDbContext) + public ZhiGongHBPOSeSyncAppService(WMSBJBMPTDbContext wmsBJBMPTContext, SettleAccountDbContext settleAccountDbContext, SyncExtendManager syncExtendManager) : base(wmsBJBMPTContext, settleAccountDbContext, syncExtendManager) { base.SeSyncConfigInfo = new SeSyncConfig() { @@ -32,7 +31,8 @@ public class ZhiGongHBPOSeSyncAppService : JitSeSyncAppService, IJobService }; } - public async Task Invoke(IServiceProvider serviceProvider) + [UnitOfWork(IsDisabled = true)] + public virtual async Task Invoke(IServiceProvider serviceProvider) { await base.Invoke().ConfigureAwait(false); }