diff --git a/ds-wms-service/DS.WMS.Core/Code/Interface/IDataRuleTemplateService.cs b/ds-wms-service/DS.WMS.Core/Code/Interface/IDataRuleTemplateService.cs index ebb70279..88fc6e38 100644 --- a/ds-wms-service/DS.WMS.Core/Code/Interface/IDataRuleTemplateService.cs +++ b/ds-wms-service/DS.WMS.Core/Code/Interface/IDataRuleTemplateService.cs @@ -44,4 +44,12 @@ public interface IDataRuleTemplateService /// Task>> GetDataRuleTemplateSelectList(string id, string ruleType); + + /// + /// 数据权限模板复制 + /// + /// + /// + + public Task BatchCopyDataRuleTemplate(IdModel req); } \ No newline at end of file diff --git a/ds-wms-service/DS.WMS.Core/Code/Method/DataRuleTemplateService.cs b/ds-wms-service/DS.WMS.Core/Code/Method/DataRuleTemplateService.cs index 1790a474..431eade7 100644 --- a/ds-wms-service/DS.WMS.Core/Code/Method/DataRuleTemplateService.cs +++ b/ds-wms-service/DS.WMS.Core/Code/Method/DataRuleTemplateService.cs @@ -127,5 +127,25 @@ namespace DS.WMS.Core.Code.Method } return await Task.FromResult(DataResult.Successed("删除成功!", MultiLanguageConst.DataDelSuccess)); } + + public async Task BatchCopyDataRuleTemplate(IdModel req) + { + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + var list = await tenantDb.Queryable().Where(x => req.Ids.Contains(x.Id)).ToListAsync(); + var newList = new List(); + if (list.Count > 0) + { + foreach (var item in list) { + + var temp = item.Adapt(); + temp.Id = 0; + temp.TemplateName = item.TemplateName +"-复制"; + newList.Add(temp); + } + + await tenantDb.Insertable(newList).ExecuteCommandAsync(); + } + return await Task.FromResult(DataResult.Successed("复制成功!", MultiLanguageConst.DataCopySuccess)); + } } } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Dtos/ReportContext.cs b/ds-wms-service/DS.WMS.Core/Fee/Dtos/ReportContext.cs new file mode 100644 index 00000000..68cecea5 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/Fee/Dtos/ReportContext.cs @@ -0,0 +1,48 @@ +using DS.Module.Core; +using DS.Module.UserModule; +using DS.WMS.Core.Op.Entity; +using SqlSugar; + +namespace DS.WMS.Core.Fee.Dtos +{ + /// + /// 报表生成上下文 + /// + public class ReportContext + { + /// + /// 服务提供程序 + /// + public IServiceProvider ServiceProvider { get; internal set; } + + /// + /// 获取主库访问对象 + /// + public ISqlSugarClient Db { get; internal set; } + + /// + /// 获取租户库访问对象 + /// + public ISqlSugarClient TenantDb { get; internal set; } + + /// + /// 请求用户 + /// + public IUser User { get; internal set; } + + /// + /// 操作结果,用于记录错误信息 + /// + public DataResult? ErrorResult { get; set; } + + /// + /// 业务类型 + /// + public BusinessType BusinessType { get; set; } = BusinessType.OceanShippingExport; + + /// + /// 业务ID + /// + public long[] Ids { get; set; } = []; + } +} diff --git a/ds-wms-service/DS.WMS.Core/Fee/Interface/IFeeRecordService.cs b/ds-wms-service/DS.WMS.Core/Fee/Interface/IFeeRecordService.cs index 0c3b8950..57b0dee0 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Interface/IFeeRecordService.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Interface/IFeeRecordService.cs @@ -96,12 +96,13 @@ public interface IFeeRecordService Task WriteBackStatusAsync(long businessId, BusinessType businessType); /// - /// 获取费用核算单打印信息 + /// 获取费用打印信息 /// + /// 数据提供程序 /// 业务类型 /// 费用记录ID /// - Task> GetPrintInfoAsync(BusinessType businessType, params long[] idArray); + Task> GetPrintInfoAsync(string providerName, BusinessType businessType, params long[] idArray); /// /// 设置发票启用状态 diff --git a/ds-wms-service/DS.WMS.Core/Fee/Interface/IReportProvider.cs b/ds-wms-service/DS.WMS.Core/Fee/Interface/IReportProvider.cs new file mode 100644 index 00000000..81f69d00 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/Fee/Interface/IReportProvider.cs @@ -0,0 +1,17 @@ +using DS.WMS.Core.Fee.Dtos; + +namespace DS.WMS.Core.Fee.Interface +{ + /// + /// 用于输出报表的数据提供程序 + /// + public interface IReportProvider + { + /// + /// 返回所需的JSON格式的数据 + /// + /// 报表输出上下文 + /// + Task GetDataAsync(ReportContext context); + } +} diff --git a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeRecordService.cs b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeRecordService.cs index e1cb5cb2..09e3a304 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeRecordService.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeRecordService.cs @@ -222,7 +222,7 @@ namespace DS.WMS.Core.Fee.Method item.Quantity = ctn == null ? 0 : ctn.CtnNum.GetValueOrDefault(); break; } - } + } //计算税费 item.SetTax(); @@ -927,110 +927,33 @@ namespace DS.WMS.Core.Fee.Method } /// - /// 获取费用核算单打印信息 + /// 获取费用打印信息 /// + /// /// 业务类型 /// 费用记录ID /// - public async Task> GetPrintInfoAsync(BusinessType businessType, params long[] idArray) - { - CostAccountingForm form = null; - switch (businessType) - { - case BusinessType.OceanShippingExport: - form = await GetOceanShippingExportAsync(idArray); - break; - case BusinessType.OceanShippingImport: - - break; - default: - return DataResult.Failed(string.Format( - MultiLanguageConst.BusinessNotSupported, businessType.GetDescription())); - } - - if (form != null) - { - long UserId = long.Parse(User.UserId); - form.Creator = Db.Queryable().Where(x => x.Id == UserId).Select(x => x.UserName).First(); - - form.ReceivableRMB = form.Details.FindAll(x => x.Type == FeeType.Receivable && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.Amount); - form.PayableRMB = form.Details.FindAll(x => x.Type == FeeType.Payable && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.Amount); - form.ReceivableUSD = form.Details.FindAll(x => x.Type == FeeType.Receivable && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount); - form.PayableUSD = form.Details.FindAll(x => x.Type == FeeType.Payable && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount); - form.ReceivableOther = form.Details.FindAll(x => x.Type == FeeType.Receivable && (x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE)).Sum(x => x.Amount); - form.PayableOther = form.Details.FindAll(x => x.Type == FeeType.Payable && (x.Currency == FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE)).Sum(x => x.Amount); - - //获取美元汇率 - var fees = new List { - new FeeRecord { Currency = FeeCurrency.USD_CODE, FeeType = FeeType.Receivable }, - new FeeRecord { Currency = FeeCurrency.USD_CODE, FeeType = FeeType.Payable } - }; - await FetchExchangeRateAsync(fees); - form.ExchangeRate = fees[0].ExchangeRate.HasValue ? fees[0].ExchangeRate.Value : 1; - form.TotalReceivable = Math.Round(form.ReceivableUSD * form.ExchangeRate, 4, MidpointRounding.ToEven) + form.ReceivableRMB + form.ReceivableOther; - form.TotalPayable = Math.Round(form.PayableUSD * form.ExchangeRate, 4, MidpointRounding.ToEven) + form.PayableRMB + form.PayableOther; - } - - return DataResult.Success(form); - } - - //获取海运出口打印数据 - async Task GetOceanShippingExportAsync(params long[] idArray) + public async Task> GetPrintInfoAsync(string providerName, BusinessType businessType, params long[] idArray) { - CostAccountingForm form = null; - var list = await TenantDb.Queryable().InnerJoin((x, y) => x.BusinessId == y.Id) - .Where((x, y) => idArray.Contains(x.Id) - //&& x.FeeStatus == FeeStatus.SettlementCompleted - ).Select((x, y) => new - { - x.FeeType, - x.FeeName, - x.Currency, - x.ExchangeRate, - x.Amount, - x.CustomerName, - y.CustomerNo, //业务编号 - y.AccountDate, //会计期间 - y.ETA, - y.ETD, - y.Voyno, - y.MBLNO, - y.Carrier, - y.LoadPort, - y.DischargePort, - y.CntrTotal, //Volume - y.IssueType //放单方式 - }).ToListAsync(); - - if (list.Count == 0) - return form; + Type type = Type.GetType(providerName, false); + if (type == null) + return DataResult.Failed("未能找到数据提供程序"); - var item = list[0]; - form = new CostAccountingForm + var provider = Fasterflect.ConstructorExtensions.CreateInstance(type) as IReportProvider; + var context = new ReportContext { - BusinessNo = item.CustomerNo, - AccountingPeriod = item.AccountDate, - ETA = item.ETA, - ETD = item.ETD, - Voy = item.Voyno, - MBLNo = item.MBLNO, - Carrier = item.Carrier, - POL = item.LoadPort, - POD = item.DischargePort, - Volume = item.CntrTotal, - ReleaseType = item.IssueType, - PrintTime = DateTime.Now, - Details = list.Select(x => new CostAccountingDetail - { - Amount = x.Amount, - Currency = x.Currency, - CustomerName = x.CustomerName, - FeeName = x.FeeName, - Type = x.FeeType - }).ToList() + BusinessType = businessType, + Ids = idArray, + Db = Db, + TenantDb = TenantDb, + User = User, + ServiceProvider = ServiceProvider }; + var data = provider.GetDataAsync(context); + if (context.ErrorResult == null) + return DataResult.Success(data); - return form; + return DataResult.Failed(context.ErrorResult.Message, context.ErrorResult.MultiCode); } /// diff --git a/ds-wms-service/DS.WMS.Core/Fee/Method/ReportProviders/CostAccountingReport.cs b/ds-wms-service/DS.WMS.Core/Fee/Method/ReportProviders/CostAccountingReport.cs new file mode 100644 index 00000000..da389dca --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/Fee/Method/ReportProviders/CostAccountingReport.cs @@ -0,0 +1,123 @@ +using DS.Module.Core; +using DS.WMS.Core.Fee.Dtos; +using DS.WMS.Core.Fee.Entity; +using DS.WMS.Core.Fee.Interface; +using DS.WMS.Core.Op.Entity; +using DS.WMS.Core.Sys.Entity; +using Masuit.Tools.Systems; +using Microsoft.Extensions.DependencyInjection; +using SqlSugar; + +namespace DS.WMS.Core.Fee.Method.ReportProviders +{ + /// + /// 费用核算单 + /// + public class CostAccountingReport : IReportProvider + { + public async Task GetDataAsync(ReportContext context) + { + CostAccountingForm? form = null; + switch (context.BusinessType) + { + case BusinessType.OceanShippingExport: + form = await GetOceanShippingExportAsync(context.TenantDb, context.Ids); + break; + case BusinessType.OceanShippingImport: + + break; + default: + context.ErrorResult = DataResult.Failed(string.Format(MultiLanguageConst.GetDescription( + MultiLanguageConst.BusinessNotSupported), context.BusinessType.GetDescription())); + break; + } + + if (form != null) + { + long UserId = long.Parse(context.User.UserId); + form.Creator = context.Db.Queryable().Where(x => x.Id == UserId).Select(x => x.UserName).First(); + + form.ReceivableRMB = form.Details.FindAll(x => x.Type == FeeType.Receivable && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.Amount); + form.PayableRMB = form.Details.FindAll(x => x.Type == FeeType.Payable && x.Currency == FeeCurrency.RMB_CODE).Sum(x => x.Amount); + form.ReceivableUSD = form.Details.FindAll(x => x.Type == FeeType.Receivable && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount); + form.PayableUSD = form.Details.FindAll(x => x.Type == FeeType.Payable && x.Currency == FeeCurrency.USD_CODE).Sum(x => x.Amount); + form.ReceivableOther = form.Details.FindAll(x => x.Type == FeeType.Receivable && (x.Currency != FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE)).Sum(x => x.Amount); + form.PayableOther = form.Details.FindAll(x => x.Type == FeeType.Payable && (x.Currency == FeeCurrency.RMB_CODE && x.Currency != FeeCurrency.USD_CODE)).Sum(x => x.Amount); + + //获取美元汇率 + var currencyService = context.ServiceProvider.GetRequiredService(); + var exchange = new ExchangeRate + { + CurrencyFrom = FeeCurrency.USD_CODE, + CurrencyTo = FeeCurrency.RMB_CODE + }; + exchange = (await currencyService.GetExchangeRateAsync(exchange))?.Data; + + form.ExchangeRate = exchange.Rate; + form.TotalReceivable = Math.Round(form.ReceivableUSD * form.ExchangeRate, 4, MidpointRounding.ToEven) + form.ReceivableRMB + form.ReceivableOther; + form.TotalPayable = Math.Round(form.PayableUSD * form.ExchangeRate, 4, MidpointRounding.ToEven) + form.PayableRMB + form.PayableOther; + } + + return form; + } + + //获取海运出口打印数据 + static async Task GetOceanShippingExportAsync(ISqlSugarClient tenantDb, params long[] idArray) + { + CostAccountingForm form = null; + var list = await tenantDb.Queryable().InnerJoin((x, y) => x.BusinessId == y.Id) + .Where((x, y) => idArray.Contains(x.Id) + //&& x.FeeStatus == FeeStatus.SettlementCompleted + ).Select((x, y) => new + { + x.FeeType, + x.FeeName, + x.Currency, + x.ExchangeRate, + x.Amount, + x.CustomerName, + y.CustomerNo, //业务编号 + y.AccountDate, //会计期间 + y.ETA, + y.ETD, + y.Voyno, + y.MBLNO, + y.Carrier, + y.LoadPort, + y.DischargePort, + y.CntrTotal, //Volume + y.IssueType //放单方式 + }).ToListAsync(); + + if (list.Count == 0) + return form; + + var item = list[0]; + form = new CostAccountingForm + { + BusinessNo = item.CustomerNo, + AccountingPeriod = item.AccountDate, + ETA = item.ETA, + ETD = item.ETD, + Voy = item.Voyno, + MBLNo = item.MBLNO, + Carrier = item.Carrier, + POL = item.LoadPort, + POD = item.DischargePort, + Volume = item.CntrTotal, + ReleaseType = item.IssueType, + PrintTime = DateTime.Now, + Details = list.Select(x => new CostAccountingDetail + { + Amount = x.Amount, + Currency = x.Currency, + CustomerName = x.CustomerName, + FeeName = x.FeeName, + Type = x.FeeType + }).ToList() + }; + + return form; + } + } +} diff --git a/ds-wms-service/DS.WMS.Core/Op/Method/TaskInteraction/TaskService.cs b/ds-wms-service/DS.WMS.Core/Op/Method/TaskInteraction/TaskService.cs index c7757341..78dba382 100644 --- a/ds-wms-service/DS.WMS.Core/Op/Method/TaskInteraction/TaskService.cs +++ b/ds-wms-service/DS.WMS.Core/Op/Method/TaskInteraction/TaskService.cs @@ -463,7 +463,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction { BusinessTask task = await GetQuery(request.BusinessId, request.BusinessType, request.TaskType).FirstAsync(); if (task == null) - return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData)); + return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskNotExists)); if (task.TaskStatus == TaskStatusEnum.Complete) return DataResult.FailedWithDesc(nameof(MultiLanguageConst.TaskCompleted)); //if (task.TaskStatus == TaskStatusEnum.Cancel) @@ -869,16 +869,20 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction if (callback.FlowStatus == FlowStatusEnum.Reject) { var task = await GetQuery(callback.BusinessId, callback.BusinessType, callback.AuditType.Value).FirstAsync(); - //创建驳回任务以进行通知 - await CreateTaskAsync(new TaskCreationRequest + var request = new TaskCreationRequest { BusinessId = callback.BusinessId, BusinessType = callback.BusinessType, TaskTypeName = GetRejectedType(callback.AuditType.Value).ToString(), RecvUserIdList = [task.CreateBy] //通知任务发起人 - }); + }; + //创建驳回任务以进行通知 + await CreateTaskAsync(request); + + //更新任务描述为驳回原因 + await SetTaskBaseDescription(callback.BusinessId, request.TaskType, callback.RejectReason); - remark += ";驳回理由:" + callback.RejectReason; + remark += ";驳回原因:" + callback.RejectReason; } long userId = long.Parse(User.UserId); diff --git a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs index cdc86f1c..f73793fc 100644 --- a/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs +++ b/ds-wms-service/DS.WMS.FeeApi/Controllers/FeeRecordController.cs @@ -3,6 +3,7 @@ using DS.Module.Core.Data; using DS.WMS.Core.Fee.Dtos; using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Fee.Interface; +using DS.WMS.Core.Fee.Method.ReportProviders; using DS.WMS.Core.Op.Entity; using Microsoft.AspNetCore.Mvc; @@ -204,12 +205,16 @@ namespace DS.WMS.FeeApi.Controllers /// 费用记录ID /// [HttpPost, Route("GetPrintInfo")] - public async Task> GetPrintInfoAsync(IdModel model) + public async Task> GetPrintInfoAsync(IdModel model) { if (model == null || model.Ids?.Length == 0) - return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); + return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest); - return await _feeService.GetPrintInfoAsync((BusinessType)model.BusinessType.Value, model.Ids); + string providerName = model.Value?.ToString(); + if (string.IsNullOrEmpty(providerName)) + providerName = typeof(CostAccountingReport).AssemblyQualifiedName; + + return await _feeService.GetPrintInfoAsync(providerName, (BusinessType)model.BusinessType.Value, model.Ids); } /// diff --git a/ds-wms-service/DS.WMS.MainApi/Controllers/CodeDataRuleTemplateController.cs b/ds-wms-service/DS.WMS.MainApi/Controllers/CodeDataRuleTemplateController.cs index 3f2d3304..f8b3a916 100644 --- a/ds-wms-service/DS.WMS.MainApi/Controllers/CodeDataRuleTemplateController.cs +++ b/ds-wms-service/DS.WMS.MainApi/Controllers/CodeDataRuleTemplateController.cs @@ -87,4 +87,17 @@ public class CodeDataRuleTemplateController : ApiController var res =await _invokeService.BatchDelDataRuleTemplate(req); return res; } + + /// + /// 批量复制 + /// + /// Ids + /// + [HttpPost] + [Route("BatchCopyDataRuleTemplate")] + public async Task BatchCopyDataRuleTemplate([FromBody] IdModel req) + { + var res = await _invokeService.BatchCopyDataRuleTemplate(req); + return res; + } } \ No newline at end of file