From 1b3dce9bb6023ed6e450a7883dc71328a8e51ab5 Mon Sep 17 00:00:00 2001 From: cjy Date: Fri, 11 Oct 2024 16:49:14 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E8=81=94=E5=8A=A8=E6=9B=B4=E6=96=B0=E4=B8=BB=E5=8D=95VGM\?= =?UTF-8?q?=E8=88=B1=E5=8D=95=E3=80=81=E6=8A=A5=E5=85=B3=E3=80=81=E6=B4=BE?= =?UTF-8?q?=E8=BD=A6=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Op/Interface/ISeaExportCommonService.cs | 8 +++ .../Op/Method/SeaExportCommonService.cs | 68 ++++++++++++++++++- .../Controllers/DjyServiceStatusController.cs | 12 ++++ 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/ds-wms-service/DS.WMS.Core/Op/Interface/ISeaExportCommonService.cs b/ds-wms-service/DS.WMS.Core/Op/Interface/ISeaExportCommonService.cs index 46681410..9331d697 100644 --- a/ds-wms-service/DS.WMS.Core/Op/Interface/ISeaExportCommonService.cs +++ b/ds-wms-service/DS.WMS.Core/Op/Interface/ISeaExportCommonService.cs @@ -14,6 +14,14 @@ namespace DS.WMS.Core.Op.Interface { public interface ISeaExportCommonService { + + /// + /// 更新手动更新海运出口派车报关标识 + /// + /// + /// + /// 类型 true 勾选保存 false 勾选取消 + public void UpdateSeaExportTag(long id, string code, bool type = true); /// /// 海运出口差异日志 /// diff --git a/ds-wms-service/DS.WMS.Core/Op/Method/SeaExportCommonService.cs b/ds-wms-service/DS.WMS.Core/Op/Method/SeaExportCommonService.cs index 22b21b74..285dad2d 100644 --- a/ds-wms-service/DS.WMS.Core/Op/Method/SeaExportCommonService.cs +++ b/ds-wms-service/DS.WMS.Core/Op/Method/SeaExportCommonService.cs @@ -33,6 +33,8 @@ using DS.Module.Core.Data; using Masuit.Tools.Models; using System.ComponentModel; using DS.Module.DjyServiceStatus; +using DS.WMS.Core.Invoice.Dtos; +using NPOI.SS.Formula.Functions; namespace DS.WMS.Core.Op.Method { @@ -62,6 +64,59 @@ namespace DS.WMS.Core.Op.Method _djyServiceStatusService = _serviceProvider.GetRequiredService(); } + + /// + /// 更新手动更新海运出口派车报关标识 + /// + /// + /// + /// 类型 true 勾选保存 false 勾选取消 + public async void UpdateSeaExportTag(long id,string code,bool type = true) { + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + var order = tenantDb.Queryable().Filter(null, true).First(x => x.Id == id); + var oldOrder = order.Adapt(); + + if (type) + { + if (code == "YPC") + { + order.IsLand = true; + } + if (code == "BG") + { + order.IsCustoms = true; + } + } + else + { + if (code == "YPC") + { + order.IsLand = false; + } + if (code == "BG") + { + order.IsCustoms = false; + } + } + + //order.Note = "更新主单货物状态"; + await tenantDb.Updateable(order) + .UpdateColumnsIF(code == "YPC", x => new { x.IsLand }) + .UpdateColumnsIF(code == "BG", x => new { x.IsCustoms }) + .EnableDiffLogEvent().ExecuteCommandAsync(); + // 记录日志 + await SaveSeaExportLogAsync(new SeaExportSaveLog() + { + OperateType = "Update", + OldOrder = oldOrder, + NewOrder = order, + SourceCode = "UpdateSeaExportTag", + SourceName = "手动更新海运出口标识", + }, tenantDb); + + } + + #region 海运出口差异日志 /// /// 忽略的字段 @@ -1001,13 +1056,20 @@ namespace DS.WMS.Core.Op.Method var oldOrder = order.Adapt(); order.BusinessStatusName = status.StatusName; order.BusinessStatus = status.SystemCode; - order.IsVGM = status.SystemCode == "YFVGM" ? true : false; - order.IsBooking = status.SystemCode == "YFCD" ? true : false; - + if (status.SystemCode == "YPC") + order.IsLand = true; + if(status.SystemCode == "BG") + order.IsCustoms = true; + if (status.SystemCode == "YFVGM") + order.IsVGM = true; + if (status.SystemCode == "YFCD") + order.IsBooking = true; //order.Note = "更新主单货物状态"; await tenantDb.Updateable(order).UpdateColumns(x => new { x.BusinessStatusName, x.BusinessStatus }) .UpdateColumnsIF(status.SystemCode == "YFVGM", x => new { x.IsVGM }) .UpdateColumnsIF(status.SystemCode == "YFCD", x => new { x.IsBooking }) + .UpdateColumnsIF(status.SystemCode == "YPC", x => new { x.IsLand }) + .UpdateColumnsIF(status.SystemCode == "BG", x => new { x.IsCustoms }) .EnableDiffLogEvent().ExecuteCommandAsync(); // 记录日志 await SaveSeaExportLogAsync(new SeaExportSaveLog() diff --git a/ds-wms-service/DS.WMS.OpApi/Controllers/DjyServiceStatusController.cs b/ds-wms-service/DS.WMS.OpApi/Controllers/DjyServiceStatusController.cs index ac1dfb28..392b3fe2 100644 --- a/ds-wms-service/DS.WMS.OpApi/Controllers/DjyServiceStatusController.cs +++ b/ds-wms-service/DS.WMS.OpApi/Controllers/DjyServiceStatusController.cs @@ -6,6 +6,7 @@ using DS.Module.PrintModule; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.Core.Code.Interface; +using DS.WMS.Core.Op.Interface; using DS.WMS.Core.TaskPlat.Entity; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -23,6 +24,8 @@ namespace DS.WMS.OpApi.Controllers private readonly IUser user; private readonly ISaasDbService saasDbService; + private readonly ISeaExportCommonService _seaComService; + /// /// 构造函数 /// @@ -35,6 +38,7 @@ namespace DS.WMS.OpApi.Controllers this.serviceProvider = serviceProvider; this.user = user; this.saasDbService = saasDbService; + this._seaComService = serviceProvider.GetRequiredService(); } /// @@ -129,6 +133,10 @@ namespace DS.WMS.OpApi.Controllers [Route("SaveServiceStatus")] public async Task SaveServiceStatus([FromBody] EmbedServiceProjectStatusDto req) { + if (req.StatusCodes[0].StatusCode.Contains("BG")|| req.StatusCodes[0].StatusCode.Contains("YPC")) + { + _seaComService.UpdateSeaExportTag(long.Parse(req.businessId), req.StatusCodes[0].StatusCode,true); + } return await _invokeService.SaveServiceStatus(req); } @@ -142,6 +150,10 @@ namespace DS.WMS.OpApi.Controllers [Route("CancelServiceStatus")] public async Task CancelServiceStatus([FromBody] EmbedServiceProjectStatusDto req) { + if (req.StatusCodes[0].StatusCode.Contains("BG") || req.StatusCodes[0].StatusCode.Contains("YPC")) + { + _seaComService.UpdateSeaExportTag(long.Parse(req.businessId), req.StatusCodes[0].StatusCode, false); + } return await _invokeService.CancelServiceStatus(req); } From 5d119664400727ec2f7d069cc2ebae6c5b5b0c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B5=87=E6=96=87=E9=BE=99?= Date: Fri, 11 Oct 2024 15:08:39 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=BE=80=E6=9D=A5=E5=8D=95=E4=BD=8D?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Info/Dtos/InfoClientBankModel.cs | 83 ++++++++ .../Info/Dtos/InfoClientContactModel.cs | 53 +++++ .../DS.WMS.Core/Info/Dtos/InfoClientModel.cs | 5 + .../Info/Interface/IClientBankService.cs | 7 + .../Info/Interface/IClientContactService.cs | 7 + .../Info/Method/ClientBankService.cs | 92 +++++++++ .../Info/Method/ClientContactService.cs | 74 +++++++ .../Info/Method/ClientInfoService.cs | 48 +++-- .../Controllers/FeeCustTemplateController.cs | 24 +-- .../Controllers/FeeRecordController.cs | 9 +- .../Controllers/ClientInfoController.cs | 188 ++++++++++++++++-- 11 files changed, 537 insertions(+), 53 deletions(-) create mode 100644 ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientBankModel.cs create mode 100644 ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientContactModel.cs diff --git a/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientBankModel.cs b/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientBankModel.cs new file mode 100644 index 00000000..d286b6f9 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientBankModel.cs @@ -0,0 +1,83 @@ +namespace DS.WMS.Core.Info.Dtos +{ + /// + /// 往来单位银行与发票导入模型 + /// + public class InfoClientBankModel + { + /// + /// 公司名称 + /// + public string? CompanyName { get; set; } + + /// + /// 币种 + /// + public string? Currency { get; set; } + + /// + /// 银行名称 + /// + public string? BankName { get; set; } + + /// + /// 银行账号 + /// + public string? BankAccount { get; set; } + + /// + /// 银行地址 + /// + public string? BankAddress { get; set; } + + /// + /// 发票地址 + /// + public string? InvoiceAddress { get; set; } + + /// + /// 发票收件人 + /// + public string? InvoiceRecevier { get; set; } + + /// + /// 联系电话 + /// + public string? Tel { get; set; } + + /// + /// 纳税人识别号 + /// + public string? TaxId { get; set; } + + /// + /// 开票电话 + /// + public string? InvoiceTel { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + /// + /// 发票抬头 + /// + public string? InvoiceHeader { get; set; } + + /// + /// 默认应付 + /// + public bool IsDefaultP { get; set; } + + /// + /// 默认应收 + /// + public bool IsDefaultR { get; set; } + + /// + /// 默认银行 + /// + public bool IsDefault { get; set; } + } +} diff --git a/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientContactModel.cs b/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientContactModel.cs new file mode 100644 index 00000000..180ad6e0 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientContactModel.cs @@ -0,0 +1,53 @@ +namespace DS.WMS.Core.Info.Dtos +{ + /// + /// 往来单位联系人导入模型 + /// + public class InfoClientContactModel + { + /// + /// 所属公司 + /// + public string? CompanyName { get; set; } + + /// + /// 联系人名称 + /// + public string? ContactName { get; set; } + + /// + /// 联系人英文名 + /// + public string? ContactEnName { get; set; } + + /// + /// 电话 + /// + public string? Tel { get; set; } + + /// + /// 手机 + /// + public string? Mobile { get; set; } + + /// + /// 邮箱 + /// + public string? Email { get; set; } + + /// + /// QQ + /// + public string? QQ { get; set; } + + /// + /// 职务 + /// + public string? Job { get; set; } + + /// + /// 是否默认联系人 + /// + public bool IsDefault { get; set; } + } +} diff --git a/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientModel.cs b/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientModel.cs index 10870d44..661e74f0 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientModel.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Dtos/InfoClientModel.cs @@ -75,6 +75,11 @@ /// public string? Attribute { get; set; } + /// + /// 客户属性 + /// + public string[] AttributeNames => Attribute == null ? [] : Attribute.Split(',', StringSplitOptions.RemoveEmptyEntries); + /// /// 商务 /// diff --git a/ds-wms-service/DS.WMS.Core/Info/Interface/IClientBankService.cs b/ds-wms-service/DS.WMS.Core/Info/Interface/IClientBankService.cs index 62819407..4ded04e7 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Interface/IClientBankService.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Interface/IClientBankService.cs @@ -33,4 +33,11 @@ public interface IClientBankService /// /// Task DeleteAsync(IdModel req); + + /// + /// 导入客户银行 + /// + /// + /// + Task ImportAsync(List list); } \ No newline at end of file diff --git a/ds-wms-service/DS.WMS.Core/Info/Interface/IClientContactService.cs b/ds-wms-service/DS.WMS.Core/Info/Interface/IClientContactService.cs index 7da1f9f5..0ff8537b 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Interface/IClientContactService.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Interface/IClientContactService.cs @@ -35,4 +35,11 @@ public interface IClientContactService /// /// Task DeleteAsync(IdModel model); + + /// + /// 导入客户联系人 + /// + /// + /// + Task ImportAsync(List list); } \ No newline at end of file diff --git a/ds-wms-service/DS.WMS.Core/Info/Method/ClientBankService.cs b/ds-wms-service/DS.WMS.Core/Info/Method/ClientBankService.cs index 56055d00..b94e63f7 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Method/ClientBankService.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Method/ClientBankService.cs @@ -1,6 +1,8 @@ +using System.Text; using DS.Module.Core; using DS.Module.Core.Data; using DS.Module.Core.Extensions; +using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Info.Dtos; using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Info.Interface; @@ -111,4 +113,94 @@ public class ClientBankService : ServiceBase, IClientBankService int rows = await TenantDb.Deleteable().Where(x => req.Ids.Contains(x.Id)).ExecuteCommandAsync(); return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } + + /// + /// 导入客户银行 + /// + /// + /// + public async Task ImportAsync(List list) + { + long userId = long.Parse(User.UserId); + DateTime dtNow = DateTime.Now; + + var clientNames = list.Select(x => x.CompanyName).Distinct(); + var clients = await TenantDb.Queryable().Where(x => clientNames.Contains(x.ShortName)) + .Select(x => new + { + x.Id, + x.ShortName, + x.OrgId + }).ToListAsync(); + + StringBuilder sb = new(); + List banks = new List(list.Count); + foreach (var model in list) + { + var client = clients.Find(x => x.ShortName == model.CompanyName); + if (client == null) + { + sb.Append("," + model.CompanyName); + continue; + } + + InfoClientBank bank = new() + { + ClientId = client.Id, + OrgId = client.OrgId, + BankName = model.BankName, + Account = model.BankAccount, + BankAddress = model.BankAddress, + BankAccountNo = model.BankAccount, + IsInvoiceDefault = model.IsDefault, + CreateBy = userId, + CreateUserName = User.UserName, + CreateTime = dtNow, + InvoiceHeaders = [] + }; + + if (model.Currency == "人民币") + bank.Currency = FeeCurrency.RMB_CODE; + else if (model.Currency == "美元") + bank.Currency = FeeCurrency.USD_CODE; + + bank.InvoiceHeaders.Add(new InvoiceHeader + { + Header = model.InvoiceHeader, + AddressTel = model.InvoiceAddress + " " + model.InvoiceTel + }); + + banks.Add(bank); + } + + if (sb.Length > 0) + { + sb.Remove(0, 1); + return DataResult.Failed("下列【公司名称】匹配不到客户/供应商:" + sb.ToString()); + } + + await TenantDb.Ado.BeginTranAsync(); + try + { + await TenantDb.Fastest().BulkMergeAsync(banks); + + foreach (var bank in banks) + { + foreach (var item in bank.InvoiceHeaders) + item.RelativeId = bank.Id; + } + + var invoiceHeaders = banks.SelectMany(x => x.InvoiceHeaders).ToList(); + await TenantDb.Fastest().BulkMergeAsync(invoiceHeaders); + + await TenantDb.Ado.CommitTranAsync(); + return DataResult.Success; + } + catch (Exception ex) + { + await TenantDb.Ado.RollbackTranAsync(); + await ex.LogAsync(Db); + return DataResult.Failed("导入失败:" + ex.Message); + } + } } \ No newline at end of file diff --git a/ds-wms-service/DS.WMS.Core/Info/Method/ClientContactService.cs b/ds-wms-service/DS.WMS.Core/Info/Method/ClientContactService.cs index 0a5e3487..a17d776a 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Method/ClientContactService.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Method/ClientContactService.cs @@ -1,10 +1,13 @@ +using System.Text; using DS.Module.Core; using DS.Module.Core.Data; using DS.Module.Core.Extensions; +using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Info.Dtos; using DS.WMS.Core.Info.Entity; using DS.WMS.Core.Info.Interface; using Mapster; +using Masuit.Tools.Models; namespace DS.WMS.Core.Info.Method; @@ -87,4 +90,75 @@ public class ClientContactService : ServiceBase, IClientContactService int rows = await TenantDb.Deleteable().Where(x => model.Ids.Contains(x.Id)).ExecuteCommandAsync(); return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed)); } + + /// + /// 导入客户联系人 + /// + /// + /// + public async Task ImportAsync(List list) + { + long userId = long.Parse(User.UserId); + DateTime dtNow = DateTime.Now; + + var clientNames = list.Select(x => x.CompanyName).Distinct(); + var clients = await TenantDb.Queryable().Where(x => clientNames.Contains(x.ShortName)) + .Select(x => new + { + x.Id, + x.ShortName, + x.OrgId + }).ToListAsync(); + + StringBuilder sb = new(); + List contacts = new List(list.Count); + foreach (var model in list) + { + var client = clients.Find(x => x.ShortName == model.CompanyName); + if (client == null) + { + sb.Append("," + model.CompanyName); + continue; + } + + InfoClientContact contact = new() + { + ClientId = client.Id, + OrgId = client.OrgId, + CreateBy = userId, + CreateUserName = User.UserName, + CreateTime = dtNow, + Name = model.ContactName, + EnName = model.ContactEnName, + Job = model.Job, + Email = model.Email, + Mobile = model.Mobile, + Tel = model.Tel, + QQ = model.QQ, + IsDefault = model.IsDefault + }; + + contacts.Add(contact); + } + + if (sb.Length > 0) + { + sb.Remove(0, 1); + return DataResult.Failed("下列【所属公司】匹配不到客户/供应商:" + sb.ToString()); + } + + await TenantDb.Ado.BeginTranAsync(); + try + { + await TenantDb.Fastest().BulkMergeAsync(contacts); + await TenantDb.Ado.CommitTranAsync(); + return DataResult.Success; + } + catch (Exception ex) + { + await TenantDb.Ado.RollbackTranAsync(); + await ex.LogAsync(Db); + return DataResult.Failed("导入失败:" + ex.Message); + } + } } \ No newline at end of file diff --git a/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs b/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs index 2127e236..058379d6 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs @@ -261,7 +261,7 @@ public class ClientInfoService : ServiceBase, IClientInfoService long userId = long.Parse(User.UserId); DateTime dtNow = DateTime.Now; - var attrbutes = list.Select(x => x.Attribute).Where(x => !string.IsNullOrEmpty(x)).Distinct(); + var attrbutes = list.SelectMany(x => x.AttributeNames).Where(x => !string.IsNullOrEmpty(x)).Distinct(); var dicList = await Db.Queryable().InnerJoin((d, t) => d.TypeId == t.Id) .Where((d, t) => t.Code == "infoclient-ArrclientTag" && attrbutes.Contains(d.Name)) .Select((d, t) => new @@ -306,12 +306,12 @@ public class ClientInfoService : ServiceBase, IClientInfoService IsSupplier = model.IsSupplier, OperatorId = users.Find(x => x.UserName == model.OP)?.Id, OperatorName = model.OP, - Name = model.CNName, OrgId = (users.Find(x => x.UserName == model.Sale)?.DefaultOrgId).GetValueOrDefault(), Sale = model.Sale, SaleId = users.Find(x => x.UserName == model.Sale)?.Id, QQ = model.QQ, ShortName = model.CNName, + Description = model.CNName, Tel = model.Tel, Note = "系统导入", ClientTag = new InfoClientTag(), @@ -337,17 +337,17 @@ public class ClientInfoService : ServiceBase, IClientInfoService CreateTime = dtNow, }); - client.Contacts.Add(new InfoClientContact - { - Name = model.ContactName, - Address = model.Address, - Email = model.Email, - Mobile = model.Phone, - Tel = model.Tel, - QQ = model.QQ, - IsDefault = true, - OrgId = client.OrgId - }); + //client.Contacts.Add(new InfoClientContact + //{ + // Name = model.ContactName, + // Address = model.Address, + // Email = model.Email, + // Mobile = model.Phone, + // Tel = model.Tel, + // QQ = model.QQ, + // IsDefault = true, + // OrgId = client.OrgId + //}); clients.Add(client); } @@ -355,13 +355,23 @@ public class ClientInfoService : ServiceBase, IClientInfoService await TenantDb.Ado.BeginTranAsync(); try { - await TenantDb.Storageable(clients).WhereColumns(x => new { x.ShortName, x.Description }).ExecuteCommandAsync(); + await TenantDb.Fastest().BulkMergeAsync(clients); + foreach (var client in clients) + { + client.ClientTag.ClientId = client.Id; + + foreach (var item in client.AccountDates) + item.ClientId = client.Id; + + //foreach (var item in client.Contacts) + // item.ClientId = client.Id; + } + + var accountDates = clients.SelectMany(x => x.AccountDates).ToList(); + await TenantDb.Fastest().BulkMergeAsync(accountDates); - //await TenantDb.InsertNav(clients) - //.Include(x => x.ClientTag) - //.Include(x => x.AccountDates) - //.Include(x => x.Contacts) - //.ExecuteCommandAsync(); + //var contacts = clients.SelectMany(x => x.Contacts).ToList(); + //await TenantDb.Fastest().BulkMergeAsync(contacts); await TenantDb.Ado.CommitTranAsync(); return DataResult.Success; diff --git a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeCustTemplateController.cs b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeCustTemplateController.cs index dd8b57bc..eb3a78ac 100644 --- a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeCustTemplateController.cs +++ b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeCustTemplateController.cs @@ -10,7 +10,7 @@ using MiniExcelLibs; namespace DS.WMS.FeeApi.Controllers { /// - /// 往来单位费用模板API + /// 自动费用模板API /// public class FeeCustTemplateController : ApiController { @@ -53,24 +53,13 @@ namespace DS.WMS.FeeApi.Controllers /// /// [HttpPost, Route("Import")] - public async Task ImportAsync() + public async Task ImportAsync(IFormFile file) { - Stream? stream; - try - { - if (Request.Form.Files.Count == 0) - return BadRequest("请求不包含文件流"); - - stream = Request.Form.Files[0].OpenReadStream(); - } - catch (InvalidOperationException) - { - stream = Request.Body; - } + if (file == null) + return BadRequest("请求未包含文件流"); - MemoryStream ms = new(); - await stream.CopyToAsync(ms); - var query = await MiniExcel.QueryAsync(ms, excelType: ExcelType.XLSX, startCell: "A4"); + var stream = file.OpenReadStream(); + var query = await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A4"); List list = []; try { @@ -116,7 +105,6 @@ namespace DS.WMS.FeeApi.Controllers } var result = await _invokeService.ImportAsync(list); - ms.Dispose(); return Ok(result); } diff --git a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs index 9bf0de32..937ace45 100644 --- a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs +++ b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs @@ -191,7 +191,7 @@ namespace DS.WMS.FeeApi.Controllers /// 业务ID和类型 /// [HttpPost, Route("ApplyBusinessAudit")] - public async Task ApplyBusinessAuditAsync(IdModel model) + public async Task ApplyBusinessAuditAsync([FromBody] IdModel model) { if (!long.TryParse(model.Id, out long bid) || model.BusinessType == null) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); @@ -204,7 +204,8 @@ namespace DS.WMS.FeeApi.Controllers /// /// 业务ID和类型 /// - public async Task WithdrawBusinessAsync(IdModel model) + [HttpPost, Route("WithdrawBusiness")] + public async Task WithdrawBusinessAsync([FromBody] IdModel model) { if (!long.TryParse(model.Id, out long bid) || model.BusinessType == null) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); @@ -218,7 +219,7 @@ namespace DS.WMS.FeeApi.Controllers /// 费用记录ID /// [HttpPost, Route("GetPrintInfo")] - public async Task> GetPrintInfoAsync(IdModel model) + public async Task> GetPrintInfoAsync([FromBody] IdModel model) { if (model == null || model.Ids?.Length == 0) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); @@ -236,7 +237,7 @@ namespace DS.WMS.FeeApi.Controllers /// 费用记录ID /// [HttpPost, Route("SetInvoiceEnabled")] - public async Task SetInvoiceEnabledAsync(IdModel model) + public async Task SetInvoiceEnabledAsync([FromBody] IdModel model) { if (model == null || model.Ids?.Length == 0) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); diff --git a/ds-wms-service/DS.WMS.MainApi/Controllers/ClientInfoController.cs b/ds-wms-service/DS.WMS.MainApi/Controllers/ClientInfoController.cs index 70d0d263..2d908ad9 100644 --- a/ds-wms-service/DS.WMS.MainApi/Controllers/ClientInfoController.cs +++ b/ds-wms-service/DS.WMS.MainApi/Controllers/ClientInfoController.cs @@ -196,13 +196,12 @@ public class ClientInfoController : ApiController #region 导入 /// - /// 导入客户/供应商 + /// 导入客户 /// - /// 类型:1=客户,2=供应商,3=客户+供应商 /// /// - [HttpPost, Route("Import")] - public async Task ImportAsync([FromForm] int type, IFormFile file) + [HttpPost, Route("ImportClient")] + public async Task ImportClientAsync(IFormFile file) { if (file == null) return DataResult.Failed("请求未包含文件流"); @@ -248,20 +247,76 @@ public class ClientInfoController : ApiController Email = item["AF"]?.ToString(), ContactName = item["AG"]?.ToString(), NFDS = item["AP"] == null ? null : int.Parse(item["AP"].ToString()), + IsCustomer = true }; //if (string.IsNullOrEmpty(model.DeptName)) // sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【所属部门】"); - if (type == 3) - { - model.IsCustomer = model.IsSupplier = true; - } - else + list.Add(model); + } + + if (sb.Length > 0) + return DataResult.Failed("导入失败:" + sb.ToString()); + } + catch (Exception ex) + { + return DataResult.Failed("读取文件失败:" + ex.Message); + } + + + return await _invokeService.ImportAsync(list); + } + + /// + /// 导入供应商 + /// + /// + /// + [HttpPost, Route("ImportSupplier")] + public async Task ImportSupplierAsync(IFormFile file) + { + if (file == null) + return DataResult.Failed("请求未包含文件流"); + + var stream = file.OpenReadStream(); + var rows = (await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A2")).ToList(); + + StringBuilder sb = new StringBuilder(); + List list = []; + try + { + foreach (IDictionary item in rows) + { + var model = new InfoClientModel { - model.IsCustomer = type == 1; - model.IsSupplier = type == 2; - } + ContactTel = item["A"]?.ToString(), + Contact = item["B"]?.ToString(), + AgreementTerm = item["C"] == null ? null : DateTime.Parse(item["C"].ToString()), + StatusText = item["D"]?.ToString(), + Address = item["E"]?.ToString(), + CNName = item["F"]?.ToString(), + ENName = item["G"]?.ToString(), + ShortName = item["H"]?.ToString(), + TaxID = item["I"]?.ToString(), + Code = item["J"]?.ToString(), + StlType = item["K"]?.ToString(), + Attribute = item["V"]?.ToString(), + Business = item["L"]?.ToString(), + OP = item["M"]?.ToString(), + Sale = item["N"]?.ToString(), + CustomerService = item["P"]?.ToString(), + Authenticator = item["Q"]?.ToString(), + PrepaidRMB = item["R"] == null ? 0 : decimal.Parse(item["R"].ToString()), + PrepaidUSD = item["S"] == null ? 0 : decimal.Parse(item["S"].ToString()), + Quota = item["T"] == null ? 0 : decimal.Parse(item["T"].ToString()), + RestQuota = item["U"] == null ? 0 : decimal.Parse(item["U"].ToString()), + ContactName = item["B"]?.ToString(), + IsSupplier = true + }; + + //if (string.IsNullOrEmpty(model.DeptName)) + // sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【所属部门】"); list.Add(model); } @@ -278,6 +333,115 @@ public class ClientInfoController : ApiController return await _invokeService.ImportAsync(list); } + /// + /// 导入银行与发票 + /// + /// + /// + /// + [HttpPost, Route("ImportBank")] + public async Task ImportBankAsync([FromServices] IClientBankService service, IFormFile file) + { + if (file == null) + return DataResult.Failed("请求未包含文件流"); + + var stream = file.OpenReadStream(); + var rows = (await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A2")).ToList(); + + StringBuilder sb = new StringBuilder(); + List list = []; + + try + { + foreach (IDictionary item in rows) + { + var model = new InfoClientBankModel + { + CompanyName = item["A"]?.ToString(), + Currency = item["B"]?.ToString(), + BankName = item["C"]?.ToString(), + BankAccount = item["E"]?.ToString(), + BankAddress = item["F"]?.ToString(), + InvoiceAddress = item["G"]?.ToString(), + InvoiceRecevier = item["H"]?.ToString(), + Tel = item["I"]?.ToString(), + TaxId = item["J"]?.ToString(), + InvoiceTel = item["K"]?.ToString(), + Remark = item["L"]?.ToString(), + InvoiceHeader = item["M"]?.ToString(), + IsDefaultP = int.TryParse(item["N"]?.ToString(), out int value1) && value1 == 1, + IsDefaultR = int.TryParse(item["O"]?.ToString(), out int value2) && value2 == 1, + IsDefault = int.TryParse(item["P"]?.ToString(), out int value3) && value3 == 1, + }; + + if (string.IsNullOrEmpty(model.CompanyName)) + sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【公司名称】"); + + list.Add(model); + } + + if (sb.Length > 0) + return DataResult.Failed("导入失败:" + sb.ToString()); + } + catch (Exception ex) + { + return DataResult.Failed("读取文件失败:" + ex.Message); + } + + return await service.ImportAsync(list); + } + + /// + /// 导入联系人 + /// + /// + /// + /// + [HttpPost, Route("ImportContact")] + public async Task ImportContactAsync([FromServices] IClientContactService service, IFormFile file) + { + if (file == null) + return DataResult.Failed("请求未包含文件流"); + + var stream = file.OpenReadStream(); + var rows = (await MiniExcel.QueryAsync(stream, excelType: ExcelType.XLSX, startCell: "A2")).ToList(); + + StringBuilder sb = new StringBuilder(); + List list = []; + + try + { + foreach (IDictionary item in rows) + { + var model = new InfoClientContactModel + { + CompanyName = item["A"]?.ToString(), + ContactName = item["B"]?.ToString(), + ContactEnName = item["C"]?.ToString(), + Tel = item["D"]?.ToString(), + Mobile = item["E"]?.ToString(), + Email = item["F"]?.ToString(), + QQ = item["G"]?.ToString(), + IsDefault = item["H"]?.ToString() == "是", + Job = item["I"]?.ToString() + }; + + if (string.IsNullOrEmpty(model.CompanyName)) + sb.Append($"行号:{rows.IndexOf(item) + 2} 未填写【公司名称】"); + + list.Add(model); + } + + if (sb.Length > 0) + return DataResult.Failed("导入失败:" + sb.ToString()); + } + catch (Exception ex) + { + return DataResult.Failed("读取文件失败:" + ex.Message); + } + + return await service.ImportAsync(list); + } #endregion } \ No newline at end of file From 4b5a39305ebc6188dcbd0068e2f3339258224146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B5=87=E6=96=87=E9=BE=99?= Date: Fri, 11 Oct 2024 16:53:01 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BE=80=E6=9D=A5?= =?UTF-8?q?=E5=8D=95=E4=BD=8D=E5=B9=B2=E7=B3=BB=E4=BA=BA=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Fee/Method/FeeCustTemplateService.cs | 1 + .../Method/FeeCustTemplateJobService.cs | 318 +++++++++++++++++- .../Info/Method/ClientInfoService.cs | 14 +- .../Info/Method/ClientStakeholderService.cs | 5 +- 4 files changed, 329 insertions(+), 9 deletions(-) diff --git a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeCustTemplateService.cs b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeCustTemplateService.cs index 791a0bfd..a159581e 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeCustTemplateService.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeCustTemplateService.cs @@ -365,6 +365,7 @@ namespace DS.WMS.Core.Fee.Method PODCode = g.Key.POD, CreateBy = userId, CreateTime = dtNow, + Note = "系统导入", Details = [] }; list.Add(template); diff --git a/ds-wms-service/DS.WMS.Core/HangfireJob/Method/FeeCustTemplateJobService.cs b/ds-wms-service/DS.WMS.Core/HangfireJob/Method/FeeCustTemplateJobService.cs index 224ba38f..e195766f 100644 --- a/ds-wms-service/DS.WMS.Core/HangfireJob/Method/FeeCustTemplateJobService.cs +++ b/ds-wms-service/DS.WMS.Core/HangfireJob/Method/FeeCustTemplateJobService.cs @@ -1,5 +1,13 @@ -using DS.Module.SqlSugar; +using DS.Module.Core; +using DS.Module.Core.Condition; +using DS.Module.Core.Data; +using DS.Module.SqlSugar; +using DS.WMS.Core.Fee.Entity; +using DS.WMS.Core.Invoice.Dtos; +using DS.WMS.Core.Op.Dtos; +using DS.WMS.Core.Op.Entity; using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; using SqlSugar; namespace DS.WMS.Core.HangfireJob.Method @@ -9,7 +17,7 @@ namespace DS.WMS.Core.HangfireJob.Method /// public class FeeCustTemplateJobService { - ISqlSugarClient db; + ISqlSugarClient? db; /// /// 初始化 @@ -24,13 +32,313 @@ namespace DS.WMS.Core.HangfireJob.Method /// 生成费用 /// /// - public async Task GenerateFeesAsync() + public async Task GenerateFeesAsync() { var dbLinks = await db.Queryable().ToListAsync(); - foreach (var dbLink in dbLinks) + SqlSugarClient? tenantDb = null; + try { - + foreach (var dbLink in dbLinks) + { + string configId = dbLinks.IndexOf(dbLink).ToString(); + //if (db.IsAnyConnection(configId)) + //{ + // var config = new ConnectionConfig + // { + // ConfigId = configId, + // DbType = dbLink.DbType, + // IsAutoCloseConnection = true, + // ConnectionString = dbLink.Connection + // }; + // db.AddConnection(config); + //} + tenantDb = new SqlSugarClient(new ConnectionConfig + { + ConfigId = configId, + DbType = dbLink.DbType, + IsAutoCloseConnection = true, + ConnectionString = dbLink.Connection + }); + tenantDb.QueryFilter.Clear(); + tenantDb.QueryFilter.Clear(); + tenantDb.QueryFilter.Clear(); + + + } + } + finally + { + tenantDb?.Dispose(); + } + + } + + /// + /// 根据开船日生成费用 + /// + /// + /// 开船日 + /// + internal static async Task GenerateFeesCoreAsync(SqlSugarClient tenantDb, DateTime etd) + { + DateTime dt = DateTime.Now; + var list = await tenantDb.Queryable() + .Where(x => !x.IsDisabled && SqlFunc.Between(dt, x.StartTime, x.EndTime) && (x.IsShared || x.CustomerId != null)) + .Select(x => new FeeCustTemplate + { + Id = x.Id, + CustomerId = x.CustomerId, + FeeType = x.FeeType, + FeeCategoryId = x.FeeCategoryId, + FeeCategoryName = x.FeeCategoryName, + Priority = x.Priority, + IsShared = x.IsShared, + POLCode = x.POLCode, + PODCode = x.PODCode, + LaneId = x.LaneId, + SourceId = x.SourceId, + CarrierId = x.CarrierId, + ForwarderId = x.ForwarderId, + MBLFrtCode = x.MBLFrtCode, + Condition = x.Condition + }).ToListAsync(); + if (list.Count == 0) + return; + if (etd == default) + etd = DateTime.Now.Date; + + var tids = list.Select(x => x.Id); + var orders = await tenantDb.Queryable().Where(x => SqlFunc.DateIsSame(x.ETD, etd) && + SqlFunc.Subqueryable().Where(y => y.BusinessId == x.Id && y.BusinessType == BusinessType.OceanShippingExport && tids.Contains(y.TemplateId)).NotAny()) + .Select().ToListAsync(); + if (orders.Count == 0) + return; + + List feeList = []; + await tenantDb.Ado.BeginTranAsync(); + try + { + foreach (var order in orders) + { + var custList = list.Where(x => x.CustomerId == order.CustomerId).OrderBy(x => x.Priority); + foreach (var template in custList) //遍历客户费用模板,查找匹配项 + { + var fees = await CreateFeesIfMatchAsync(tenantDb,order, template); + if (fees != null) + { + feeList.AddRange(fees); + + var record = new FeeCustTemplateRecord + { + BusinessId = order.CustomerId, + BusinessType = BusinessType.OceanShippingExport, + CreateTime = dt, + FeeCategoryId = template.FeeCategoryId, + FeeType = template.FeeType, + TemplateId = template.Id + }; + await tenantDb.Insertable(record).ExecuteCommandAsync(); + } + } + + //未找到客户模板,开始匹配共享模板 + if (feeList.Count == 0) + { + var sharedList = list.Where(x => x.IsShared).OrderBy(x => x.Priority).ToList(); + foreach (var template in sharedList) + { + var fees = await CreateFeesIfMatchAsync(tenantDb, order, template); + if (fees != null) + { + feeList.AddRange(fees); + + var record = new FeeCustTemplateRecord + { + BusinessId = order.CustomerId, + BusinessType = BusinessType.OceanShippingExport, + CreateTime = dt, + FeeCategoryId = template.FeeCategoryId, + FeeType = template.FeeType, + TemplateId = template.Id + }; + await tenantDb.Insertable(record).ExecuteCommandAsync(); + } + } + } + + //写入当前业务的费用 + if (feeList.Count > 0) + { + //var result = await feeService.Value.SaveAsync(tenantDb, feeList, true, false); + //if (!result.Succeeded) + //{ + // //记录失败日志 + // //await new ApplicationException(result.Message).LogAsync(Db); + //} + + feeList.Clear(); + } + } + + await tenantDb.Ado.CommitTranAsync(); + } + catch (Exception ex) + { + await tenantDb.Ado.RollbackTranAsync(); + //await ex.LogAsync(Db); + } + } + + static async Task?> CreateFeesIfMatchAsync(SqlSugarClient tenantDb, SeaExportRes order, FeeCustTemplate template) + { + if (!string.IsNullOrEmpty(template.POLCode) && template.POLCode != order.LoadPortCode) + return null; + + if (!string.IsNullOrEmpty(template.PODCode) && template.PODCode != order.DischargePortCode) + return null; + + if (!string.IsNullOrEmpty(template.MBLFrtCode) && template.MBLFrtCode != order.MBLFrtCode) + return null; + + if (template.LaneId.HasValue && template.LaneId != order.LaneId) + return null; + + if (template.CarrierId.HasValue && template.CarrierId != order.CarrierId) + return null; + + if (template.SourceId.HasValue && template.SourceId != order.SourceId) + return null; + + if (template.ForwarderId.HasValue && template.ForwarderId != order.ForwarderId) + return null; + + if (!string.IsNullOrEmpty(template.Condition)) //设置了自定义匹配条件 + { + var conditionModel = JsonConvert.DeserializeObject(template.Condition); + if (!IsMatch(order, conditionModel)) + return null; + } + + if (await tenantDb.Queryable().AnyAsync(x => x.BusinessId == order.Id && x.BusinessType == BusinessType.OceanShippingExport && + x.FeeType == template.FeeType && x.FeeCategoryId == template.FeeCategoryId)) + return null; + + var details = await tenantDb.Queryable().Where(y => y.TemplateId == template.Id) + .Select(x => new FeeRecord + { + BusinessId = order.Id, + BusinessType = BusinessType.OceanShippingExport, + FeeType = template.FeeType, + FeeId = x.FeeId, + FeeCode = x.FeeCode, + FeeName = x.FeeName, + CustomerId = x.CustomerId, + CustomerName = x.CustomerName, + CustomerType = x.CustomerType, + Unit = x.Unit, + UnitPrice = SqlFunc.IsNull(x.UnitPrice.Value, 0), + //Quantity = x.IsCtn ? 1 : 0, + Currency = x.Currency, + ExchangeRate = x.ExchangeRate, + TaxRate = SqlFunc.IsNull(x.TaxRate.Value, 0), + AccTaxRate = SqlFunc.IsNull(x.AccTaxRate.Value, 0), + Tax = SqlFunc.IsNull(x.Tax.Value, 0), + TaxUnitPrice = SqlFunc.IsNull(x.TaxUnitPrice.Value, 0), + IsInvoice = x.IsInvoice, + IsAdvancedPay = x.IsAdvancedPay, + Remark = template.FeeCategoryName, + TemplateId = x.TemplateId, + InputMethod = InputMethod.Automatic + }).ToListAsync(); + + foreach (var detail in details) + { + if (detail.CustomerId == 0) + { + switch (detail.CustomerType) + { + case "controller": + detail.CustomerId = order.CustomerId; + detail.CustomerName = order.CustomerName; + break; + + case "yard": + detail.CustomerId = order.YardId; + detail.CustomerName = order.Yard; + break; + + case "custom": + detail.CustomerId = order.CustomserId; + detail.CustomerName = order.Customser; + break; + + case "contract": + detail.CustomerId = order.ContractClientId; + detail.CustomerName = order.ContractClientName; + break; + + case "shipagency": + detail.CustomerId = order.ShipAgencyId; + detail.CustomerName = order.ShipAgency; + break; + + case "shipper": + detail.CustomerId = order.ShipperId.GetValueOrDefault(); + detail.CustomerName = order.Shipper; + break; + + case "truck": + detail.CustomerId = order.TruckerId; + detail.CustomerName = order.Trucker; + break; + + case "booking": + detail.CustomerId = order.ForwarderId; + detail.CustomerName = order.Forwarder; + break; + + case "carrier": + detail.CustomerId = order.CarrierId; + detail.CustomerName = order.Carrier; + break; + + case "wareHouse": + detail.CustomerId = order.WareHouseId; + detail.CustomerName = order.WareHouse; + break; + + case "shippercn": + detail.CustomerId = order.ShipperCnId.GetValueOrDefault(); + detail.CustomerName = order.ShipperCn; + break; + + case "agent": + detail.CustomerId = order.AgentId.GetValueOrDefault(); + detail.CustomerName = order.Agent; + break; + } + } } + + return details; + } + + /// + /// 根据指定条件返回是否匹配的结果 + /// + /// 要对比的数据源 + /// 匹配条件 + /// + static bool IsMatch(object source, ConditionContent condition) + { + if (source == null || condition == null) + return false; + + TaskFlowDataContext dataContext = new((TaskFlowDataNameConst.Business, source)); + if (string.IsNullOrEmpty(condition.SourceName)) + condition.SourceName = TaskFlowDataNameConst.Business; + + return ConditionHelper.IsPass(condition, dataContext); } } } diff --git a/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs b/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs index 058379d6..bfc72a5a 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Method/ClientInfoService.cs @@ -558,8 +558,18 @@ public class ClientInfoService : ServiceBase, IClientInfoService .And(x => x.ShortName == req.ShortName.Trim() || x.Description == req.Description.Trim()) .AndIF(req.Id > 0, x => x.Id != req.Id); - if (await TenantDb.Queryable().Where(expr.ToExpression()).AnyAsync()) - return DataResult.Failed("客户信息已存在,请检查客户全称/简称是否重复!", MultiLanguageConst.ClientInfoExist); + var client = await TenantDb.Queryable().Where(expr.ToExpression()).Select(x => new + { + ClientId = x.Id, + x.ShortName, + x.Description + }).FirstAsync(); + if (client != null) + { + var result = DataResult.Failed("客户信息已存在,请检查客户全称/简称是否重复!", MultiLanguageConst.ClientInfoExist); + result.Code = ResultCode.Fail; + result.Data = client; + } return DataResult.Success; } diff --git a/ds-wms-service/DS.WMS.Core/Info/Method/ClientStakeholderService.cs b/ds-wms-service/DS.WMS.Core/Info/Method/ClientStakeholderService.cs index 6130e96f..78b6110e 100644 --- a/ds-wms-service/DS.WMS.Core/Info/Method/ClientStakeholderService.cs +++ b/ds-wms-service/DS.WMS.Core/Info/Method/ClientStakeholderService.cs @@ -266,9 +266,10 @@ namespace DS.WMS.Core.Info.Method public async Task EditAsync(InfoClientStakeholder stakeholder) { await TenantDb.Storageable(stakeholder).DefaultAddElseUpdate().ExecuteCommandAsync(); - return DataResult.Success; + var result = DataResult.Success; + result.Data = stakeholder; + return result; } - } }