合并代码

usertest
cjy 3 months ago
commit c30289dc28

@ -581,7 +581,8 @@ public static class MultiLanguageConst
public const string FeeRecordNotExist = "Fee_Record_NotExist";
[Description("没有找到费用记录")]
public const string FeeRecordNone = "Fee_Record_None";
[Description("每次只能提交同一笔业务的费用")]
public const string FeeBusinessIdOnlyOne = "Fee_BusinessId_OnlyOne";
[Description("只能删除状态为‘录入’或‘驳回提交’的费用")]
public const string FeeRecordDelete = "Fee_Record_Delete";
[Description("费用已锁定,禁止提交")]

@ -583,7 +583,7 @@ public class CM_BuyCtnService : CMServiceBase, ICM_BuyCtnService
newFee.Quantity = (decimal)groupdetail.PickupFee / (decimal)groupdetail.CtnValue_BuyingPrice;
newFee.Unit = groupdetail.CtnCode;
var feecurrencyinfo = feeCurrencyExchangeService.GetExchangeRate(new ExchangeRate
var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = newFee.Currency,
CurrencyTo = "",

@ -395,7 +395,7 @@ public class CM_CustFeeDuiService : CMServiceBase, ICM_CustFeeDuiService
newfee.Amount = .Amount == null ? 0 : (decimal).Amount;
var feecurrencyinfo = feeCurrencyExchangeService.GetExchangeRate(new ExchangeRate
var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = newfee.Currency,
CurrencyTo = "",

@ -696,7 +696,7 @@ public class CM_RentInService : CMServiceBase, ICM_RentInService
newFee.Unit = groupdetail.CtnCode;
newFee.UnitText = groupdetail.Ctnall;
var feecurrencyinfo = feeCurrencyExchangeService.GetExchangeRate(new ExchangeRate
var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = newFee.Currency,
CurrencyTo = "",
@ -774,7 +774,7 @@ public class CM_RentInService : CMServiceBase, ICM_RentInService
newFee.Quantity = (decimal)groupdetail.DailyRate / (decimal)groupdetail.DropoffFee;
newFee.Unit = groupdetail.CtnCode;
var feecurrencyinfo = feeCurrencyExchangeService.GetExchangeRate(new ExchangeRate
var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = newFee.Currency,
CurrencyTo = "",

@ -699,7 +699,7 @@ public class CM_RentOutService : CMServiceBase, ICM_RentOutService
newFee.Quantity = (decimal)groupdetail.DailyRate / (decimal)groupdetail.PickupFee;
newFee.Unit = groupdetail.CtnCode;
var feecurrencyinfo = feeCurrencyExchangeService.GetExchangeRate(new ExchangeRate
var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = newFee.Currency,
CurrencyTo = "",
@ -777,7 +777,7 @@ public class CM_RentOutService : CMServiceBase, ICM_RentOutService
newFee.Quantity = (decimal)groupdetail.DailyRate / (decimal)groupdetail.DropoffFee;
newFee.Unit = groupdetail.CtnCode;
var feecurrencyinfo = feeCurrencyExchangeService.GetExchangeRate(new ExchangeRate
var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = newFee.Currency,
CurrencyTo = "",

@ -535,7 +535,7 @@ public class CM_SellCtnService : CMServiceBase, ICM_SellCtnService
newFee.Quantity = (decimal)groupdetail.PickupFee / (decimal)groupdetail.CtnValue_SellPrice;
newFee.Unit = groupdetail.CtnCode;
var feecurrencyinfo = feeCurrencyExchangeService.GetExchangeRate(new ExchangeRate
var feecurrencyinfo = await feeCurrencyExchangeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = newFee.Currency,
CurrencyTo = "",

@ -4,6 +4,9 @@ using Masuit.Tools.Systems;
namespace DS.WMS.Core.Fee.Dtos
{
/// <summary>
/// 按票审核查询结果
/// </summary>
public class FeeAuditBusiness
{
/// <summary>
@ -347,9 +350,97 @@ namespace DS.WMS.Core.Fee.Dtos
}
/// <summary>
/// 费用记录查询结果
/// 待审核费用
/// </summary>
public class PendingAuditFee
{
/// <summary>
/// 业务类型
/// </summary>
public BusinessType BusinessType { get; set; }
/// <summary>
/// 业务类型描述
/// </summary>
public string BusinessTypeText => BusinessType.GetDescription();
/// <summary>
/// 委托编号
/// </summary>
public string CustomerNo { get; set; }
/// <summary>
/// 会计期间
/// </summary>
public string? AccountDate { get; set; }
/// <summary>
/// 船公司
/// </summary>
public string Carrier { get; set; }
/// <summary>
/// 主提单号
/// </summary>
public string MBLNO { get; set; }
/// <summary>
/// 开船日期
/// </summary>
public DateTime? ETD { get; set; }
/// <summary>
/// 预抵日期
/// </summary>
public DateTime? ETA { get; set; }
/// <summary>
/// 装货港
/// </summary>
public string LoadPort { get; set; }
/// <summary>
/// 卸货港
/// </summary>
public string DischargePort { get; set; }
/// <summary>
/// 船名
/// </summary>
public string Vessel { get; set; }
/// <summary>
/// 航次
/// </summary>
public string Voyno { get; set; }
/// <summary>
/// 待审核费用组
/// </summary>
public List<AuditItemGroup>? ItemGroups { get; set; }
}
/// <summary>
/// 待审核费用项分组
/// </summary>
public class AuditItemGroup
{
/// <summary>
/// 费用名称
/// </summary>
public string FeeName { get; set; }
/// <summary>
/// 待审核费用
/// </summary>
public List<AuditItem> Items { get; set; }
}
/// <summary>
/// 待审核费用项
/// </summary>
public class FeeAuditItem
public class AuditItem
{
/// <summary>
/// 费用记录ID

@ -2,7 +2,7 @@
namespace DS.WMS.Core.Fee.Dtos
{
public class FeeAuditItemQuery : FeeAuditItem
public class FeeAuditItemQuery : AuditItem
{
/// <summary>
/// 业务类型

@ -140,7 +140,7 @@ namespace DS.WMS.Core.Fee.Entity
/// 驳回原因
/// </summary>
[SugarColumn(ColumnDescription = "驳回原因", Length = 100, IsNullable = true)]
public string Reason { get; set; }
public string? Reason { get; set; }
/// <summary>
/// 备注
@ -184,7 +184,7 @@ namespace DS.WMS.Core.Fee.Entity
/// 审核人
/// </summary>
[SugarColumn(ColumnDescription = "审核人", IsNullable = true, Length = 50)]
public string AuditOperator { get; set; }
public string? AuditOperator { get; set; }
/// <summary>
/// 审核日期
/// </summary>
@ -322,8 +322,8 @@ namespace DS.WMS.Core.Fee.Entity
/// <summary>
/// 本位币
/// </summary>
[SugarColumn(ColumnDescription = "本位币", IsNullable = true, Length = 30)]
public string? LocalCurrency { get; set; }
[SugarColumn(ColumnDescription = "本位币", IsNullable = true, Length = 30, IsOnlyIgnoreUpdate = true)]
public string LocalCurrency { get; set; }
/// <summary>
/// 责任人
@ -414,8 +414,8 @@ namespace DS.WMS.Core.Fee.Entity
}
}
NoTaxAmount = UnitPrice * Quantity;
Amount = TaxUnitPrice * Quantity;
NoTaxAmount = Math.Round(UnitPrice * Quantity, 2, MidpointRounding.AwayFromZero);
Amount = Math.Round(TaxUnitPrice * Quantity, 2, MidpointRounding.AwayFromZero);
}
}
}

@ -31,7 +31,7 @@ namespace DS.WMS.Core.Fee.Interface
/// <param name="businessType">业务类型</param>
/// <param name="query"></param>
/// <returns></returns>
Task<DataResult<List<FeeAuditItem>>> GetFeesAsync(long id, BusinessType businessType, string query);
Task<DataResult<PendingAuditFee>> GetFeesAsync(long id, BusinessType businessType, string query);
/// <summary>
/// 获取业务相关联的费用统计

@ -33,5 +33,5 @@ public interface IFeeCurrencyExchangeService
/// </summary>
/// <param name="exchange">币别信息</param>
/// <returns></returns>
DataResult<ExchangeRate> GetExchangeRate(ExchangeRate exchange);
Task<DataResult<ExchangeRate>> GetExchangeRateAsync(ExchangeRate exchange);
}

@ -322,12 +322,28 @@ namespace DS.WMS.Core.Fee.Method
/// </summary>
/// <param name="id">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <param name="query"></param>
/// <param name="query">自定义查询条件</param>
/// <returns></returns>
public async Task<DataResult<List<FeeAuditItem>>> GetFeesAsync(long id, BusinessType businessType, string query)
public async Task<DataResult<PendingAuditFee>> GetFeesAsync(long id, BusinessType businessType, string query)
{
var query1 = TenantDb.Queryable<FeeRecord>().Where(f => f.BusinessId == id &&
f.BusinessType == businessType && AuditStatusArray.Contains(f.FeeStatus))
var pendingAudit = await TenantDb.Queryable<SeaExport>().Where(x => x.Id == id).Select(x => new PendingAuditFee
{
AccountDate = x.AccountDate,
BusinessType = businessType,
Carrier = x.Carrier,
CustomerNo = x.CustomerNo,
DischargePort = x.DischargePort,
ETA = x.ETA,
ETD = x.ETD,
LoadPort = x.LoadPort,
MBLNO = x.MBLNO,
Vessel = x.Vessel,
Voyno = x.Voyno
}).FirstAsync();
if (pendingAudit != null)
{
var query1 = TenantDb.Queryable<FeeRecord>().Where(f => f.BusinessId == id && f.BusinessType == businessType && AuditStatusArray.Contains(f.FeeStatus))
.InnerJoin<SeaExport>((f, s) => f.BusinessId == s.Id)
.LeftJoin<InfoClient>((f, s, i) => f.CustomerId == i.Id)
.Select((f, s, i) => new FeeAuditItemQuery
@ -384,28 +400,61 @@ namespace DS.WMS.Core.Fee.Method
OperatorId = s.OperatorId
}).MergeTable();
var queryList = TenantDb.UnionAll(new List<ISugarQueryable<FeeAuditItemQuery>> { query1 });
var queryList = TenantDb.UnionAll(new List<ISugarQueryable<FeeAuditItemQuery>> { query1 });
if (!query.IsNullOrEmpty())
{
var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(query);
queryList = queryList.Where(whereList);
}
var list = await queryList.Select<FeeAuditItem>().ToListAsync();
if (!query.IsNullOrEmpty())
{
var whereList = Db.ConfigQuery.Context.Utilities.JsonToConditionalModels(query);
queryList = queryList.Where(whereList);
}
var list = await queryList.Select<AuditItem>().ToListAsync();
if (list.Count > 0)
{
//关联用户名称
var UserIds = list.Select(x => x.CreateBy).Distinct();
var Users = Db.Queryable<SysUser>().Where(x => UserIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToList();
foreach (var item in list)
{
item.CreateByName = Users.Find(x => x.Id == item.CreateBy)?.UserName;
}
}
if (list.Count > 0)
{
//关联用户名称
var UserIds = list.Select(x => x.CreateBy).Distinct();
var Users = Db.Queryable<SysUser>().Where(x => UserIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToList();
//将查询结果组装成按费用分组的结构
pendingAudit.ItemGroups = [];
foreach (var item in list)
{
item.CreateByName = Users.Find(x => x.Id == item.CreateBy)?.UserName;
AuditItemGroup? group;
var groups = pendingAudit.ItemGroups.FindAll(x => x.FeeName == item.FeeName);
if (groups.Count == 0)
{
group = new AuditItemGroup
{
FeeName = item.FeeName,
Items = [item]
};
pendingAudit.ItemGroups.Add(group);
continue;
}
group = groups.Find(x => x.Items != null && x.Items.Count(y => y.FeeType == item.FeeType) == 1);
if (group != null)
{
group.Items.Add(item);
}
else
{
group = new AuditItemGroup
{
FeeName = item.FeeName,
Items = [item]
};
pendingAudit.ItemGroups.Add(group);
}
}
}
var result = DataResult<List<FeeAuditItem>>.Success(list);
result.Count = list.Count;
var result = DataResult<PendingAuditFee>.Success(pendingAudit);
return result;
}

@ -87,7 +87,7 @@ namespace DS.WMS.Core.Fee.Method
/// </summary>
/// <param name="exchange">币别信息</param>
/// <returns></returns>
public DataResult<ExchangeRate> GetExchangeRate(ExchangeRate exchange)
public async Task<DataResult<ExchangeRate>> GetExchangeRateAsync(ExchangeRate exchange)
{
if (exchange.CurrencyFrom == exchange.CurrencyTo)
{
@ -97,7 +97,7 @@ namespace DS.WMS.Core.Fee.Method
long id = User.OrgId;
//获取本位币,默认=人民币
string localCurrency = Db.Queryable<SysOrg>().Where(x => x.Id == id).Select(x => x.LocalCurrency).First() ?? FeeCurrency.RMB_CODE;
string localCurrency = await Db.Queryable<SysOrg>().Where(x => x.Id == id).Select(x => x.LocalCurrency).FirstAsync() ?? FeeCurrency.RMB_CODE;
if (string.IsNullOrWhiteSpace(exchange.CurrencyTo))
{
@ -108,18 +108,18 @@ namespace DS.WMS.Core.Fee.Method
if (exchange.CurrencyFrom != localCurrency && exchange.CurrencyTo != localCurrency)
{
//获取中间汇率
var middleRate = GetLocalRate(exchange.CurrencyFrom, localCurrency, exchange.FeeType);
var middleRate = await GetLocalRateAsync(exchange.CurrencyFrom, localCurrency, exchange.FeeType);
if (middleRate == null)
return DataResult<ExchangeRate>.FailedData(exchange, message: $"{MultiLanguageConst.FeeCurrencyNotFound}{exchange.CurrencyFrom}");
var rate = GetLocalRate(exchange.CurrencyTo, localCurrency, exchange.FeeType);
var rate = await GetLocalRateAsync(exchange.CurrencyTo, localCurrency, exchange.FeeType);
exchange.Rate = Math.Round(1 / (rate ?? 1m) * middleRate.GetValueOrDefault(), 4, MidpointRounding.AwayFromZero);
exchange.ReverseRate = Math.Round(1 / exchange.Rate, 4, MidpointRounding.AwayFromZero);
}
else
{
string currency = exchange.CurrencyFrom == FeeCurrency.RMB_CODE ? exchange.CurrencyTo : exchange.CurrencyFrom;
var rate = GetLocalRate(currency, localCurrency, exchange.FeeType);
var rate = await GetLocalRateAsync(currency, localCurrency, exchange.FeeType);
if (currency == exchange.CurrencyFrom)
{
@ -137,9 +137,9 @@ namespace DS.WMS.Core.Fee.Method
}
internal decimal? GetLocalRate(string currency, string localCurrency, FeeType? type)
internal async Task<decimal?> GetLocalRateAsync(string currency, string localCurrency, FeeType? type)
{
var entity = TenantDb.Queryable<FeeCurrency>().Where(x => x.CodeName == currency).Includes(x => x.Exchanges).First();
var entity = await TenantDb.Queryable<FeeCurrency>().Where(x => x.CodeName == currency).Includes(x => x.Exchanges).FirstAsync();
if (entity == null)
return null;

@ -89,14 +89,6 @@ namespace DS.WMS.Core.Fee.Method
if (data == null)
return;
//获取订单箱型箱量
string bsNo = bsId.ToString();
var ctns = await TenantDb.Queryable<OpCtn>().Where(y => y.BSNO == bsNo).Select(x => new
{
x.CtnCode,
x.CtnNum
}).ToListAsync();
List<FeeRecord> feeList = [];
foreach (var item in list)
{
@ -116,7 +108,8 @@ namespace DS.WMS.Core.Fee.Method
CustomerType = x.CustomerType?.ToString(),
Unit = x.Unit,
UnitPrice = x.UnitPrice.GetValueOrDefault(),
Quantity = x.IsCtn ? 0 : 1, //非箱型默认数量为1
Quantity = x.IsCtn ? 1 : 0,
Note = x.IsCtn.ToString().ToLowerInvariant(), //临时存储
Currency = x.Currency,
ExchangeRate = x.ExchangeRate,
TaxRate = x.TaxRate.GetValueOrDefault(),
@ -127,25 +120,7 @@ namespace DS.WMS.Core.Fee.Method
IsAdvancedPay = x.IsAdvancedPay,
});
//根据箱型箱量提取数量以计算总价
foreach (var fe in fees)
{
if (fe.Quantity > 0)
continue;
if (fe.Unit.IsNullOrEmpty()) //未设置费用标准则数量则为0
{
fe.Quantity = 0;
}
else
{
var ctn = ctns.Find(x => x.CtnCode == fe.Unit);
fe.Quantity = ctn == null ? 0 : ctn.CtnNum.GetValueOrDefault();
}
}
//过滤掉数量为0的费用项
feeList.AddRange(fees.Where(x => x.Quantity > 0));
feeList.AddRange(fees);
}
}

@ -51,7 +51,7 @@ namespace DS.WMS.Core.Fee.Method
//关联用户名称
var UserIds = data.Data.Where(x => x.UpdateBy.HasValue).Select(x => x.UpdateBy.Value)
//.Union(data.Data.Where(x => x.SubmitBy.HasValue).Select(x => x.SubmitBy.Value))
.Union(data.Data.Where(x => x.SubmitBy.HasValue).Select(x => x.SubmitBy.Value))
.Union(data.Data.Select(x => x.CreateBy)).Distinct();
var Users = await Db.Queryable<SysUser>().Where(x => UserIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToListAsync();
foreach (var item in data.Data)
@ -59,14 +59,10 @@ namespace DS.WMS.Core.Fee.Method
item.CreateByName = Users.Find(x => x.Id == item.CreateBy)?.UserName;
if (item.UpdateBy.HasValue)
{
item.UpdateByName = Users.Find(x => x.Id == item.UpdateBy.Value)?.UserName;
}
//if (item.SubmitBy.HasValue)
//{
// item.SubmitByName = Users.Find(x => x.Id == item.SubmitBy.Value)?.UserName;
//}
if (item.SubmitBy.HasValue)
item.SubmitByName = Users.Find(x => x.Id == item.SubmitBy.Value)?.UserName;
}
return data;
@ -138,12 +134,110 @@ namespace DS.WMS.Core.Fee.Method
{
ArgumentNullException.ThrowIfNull(items, nameof(items));
if (items.GroupBy(x => new { x.BusinessId, x.BusinessType }).Count() > 1)
return DataResult.Failed(MultiLanguageConst.FeeBusinessIdOnlyOne);
var first = items.Select(x => new { x.BusinessType, x.BusinessId }).FirstOrDefault();
if (await IsFeeLockedAsync(first.BusinessId, first.BusinessType))
return DataResult.Failed(MultiLanguageConst.FeeLocked);
var order = await TenantDb.Queryable<SeaExport>().Where(x => x.Id == first.BusinessId).Select(x => new
{
x.TEU,
x.KGS, //毛重
x.PKGS, //件数
x.CBM //尺码
}).FirstAsync();
if (order == null)
return DataResult.Failed(MultiLanguageConst.EmptyData);
//获取订单箱型箱量
string bsNo = first.BusinessId.ToString();
var ctns = await TenantDb.Queryable<OpCtn>().Where(y => y.BSNO == bsNo).Select(x => new
{
x.CtnCode,
x.CtnNum
}).ToListAsync();
foreach (var item in items)
{
//-----根据箱型箱量提取数量以计算总价-----
//如果为箱型标准
if (string.Equals(item.Note, bool.TrueString, StringComparison.OrdinalIgnoreCase))
{
if (item.Unit.IsNullOrEmpty()) //未设置箱型则数量则为0
{
item.Quantity = 0;
}
else
{
var ctn = ctns.Find(x => x.CtnCode == item.Unit);
item.Quantity = ctn == null ? 0 : ctn.CtnNum.GetValueOrDefault();
}
continue;
}
//逐个判定处理标准
switch (item.Unit)
{
//case "HOUR": //小时
// goto default;
//case "GE": //个
// goto default;
//case "DAY": //天
// goto default;
//case "XX": //箱型
// goto default;
case "JJZL": //计价重量
goto case "Z";
//case "ZJ": //总价
// goto default;
case "JZ": //净重
item.Quantity = 0;
break;
case "TEU": //TEU
item.Quantity = order.TEU;
break;
case "JF": //计费吨
item.Quantity = order.KGS.GetValueOrDefault() / 1000 > order.CBM.GetValueOrDefault() ? order.KGS.GetValueOrDefault() : order.CBM.GetValueOrDefault();
break;
case "J": //件数
item.Quantity = order.PKGS.GetValueOrDefault();
break;
case "C": //尺码
item.Quantity = order.CBM.GetValueOrDefault();
break;
case "Z": //重量
item.Quantity = order.KGS.GetValueOrDefault();
break;
case "P": //单票
goto default;
default:
item.Quantity = 1;
break;
}
//计算税费
item.SetTax();
}
//过滤掉数量为0的费用
items = items.Where(x => x.Quantity > 0);
DateTime dtNow = DateTime.Now;
await TenantDb.Ado.BeginTranAsync();

@ -3,8 +3,10 @@ using DS.Module.Core;
using DS.Module.Core.Extensions;
using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Fee.Interface;
using DS.WMS.Core.Flow.Entity;
using DS.WMS.Core.Op.Entity;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
namespace DS.WMS.Core.Fee.Method
@ -14,12 +16,15 @@ namespace DS.WMS.Core.Fee.Method
/// </summary>
public class FeeServiceBase : ServiceBase
{
readonly Lazy<IFeeCurrencyExchangeService> exchangeService;
/// <summary>
/// 初始化
/// </summary>
/// <param name="serviceProvider">服务提供程序</param>
public FeeServiceBase(IServiceProvider serviceProvider) :base(serviceProvider)
public FeeServiceBase(IServiceProvider serviceProvider) : base(serviceProvider)
{
exchangeService = new Lazy<IFeeCurrencyExchangeService>(serviceProvider.GetRequiredService<IFeeCurrencyExchangeService>);
}
/// <summary>
@ -200,29 +205,55 @@ namespace DS.WMS.Core.Fee.Method
/// <returns></returns>
protected internal async Task FetchExchangeRateAsync(IEnumerable<FeeRecord> items)
{
var exRecords = items.Where(x => !x.ExchangeRate.HasValue && x.Currency != x.LocalCurrency).ToList();
if (exRecords.Count > 0)
var exRecords = items.Where(x => x.ExchangeRate == null && x.Currency != x.LocalCurrency);
if (exRecords.Any())
{
var codes = exRecords.Select(x => x.Currency).Distinct().ToList();
var currencies = await TenantDb.Queryable<FeeCurrency>().Where(x => codes.Contains(x.CodeName)).Includes(x => x.Exchanges).ToListAsync();
DateTime dtNow = DateTime.Now;
foreach (var item in exRecords)
var exchanges = exRecords.GroupBy(x => new
{
var currency = currencies.Find(x => x.CodeName == item.Currency);
if (currency != null)
{
item.ExchangeRate = currency.DefaultRate;
if (currency.Exchanges != null && currency.Exchanges.Count > 0)
{
//取当前时间范围内的最新一条
var exchange = currency.Exchanges.FindAll(x => x.Status == StatusEnum.Enable &&
x.StartDate >= dtNow && x.EndDate <= dtNow).OrderByDescending(x => x.UpdateTime).FirstOrDefault();
x.Currency,
x.LocalCurrency,
x.FeeType,
}).Select(x => new ExchangeRate
{
CurrencyFrom = x.Key.Currency,
CurrencyTo = x.Key.LocalCurrency,
FeeType = x.Key.FeeType
});
if (exchange != null)
item.ExchangeRate = item.FeeType == FeeType.Receivable ? exchange.DRValue : exchange.CRValue;
}
}
List<ExchangeRate> exchangeRates = [];
foreach (var item in exchanges)
{
var result = await exchangeService.Value.GetExchangeRateAsync(item);
if (result.Succeeded && result.Data != null)
exchangeRates.Add(result.Data);
}
foreach (var item in items)
{
item.ExchangeRate = exchangeRates.Find(x => x.CurrencyFrom == item.Currency &&
x.CurrencyTo == item.LocalCurrency && x.FeeType == item.FeeType)?.Rate;
}
//var codes = exRecords.Select(x => x.Currency).Distinct().ToList();
//var currencies = await TenantDb.Queryable<FeeCurrency>().Where(x => codes.Contains(x.CodeName)).Includes(x => x.Exchanges).ToListAsync();
//DateTime dtNow = DateTime.Now;
//foreach (var item in exRecords)
//{
// var currency = currencies.Find(x => x.CodeName == item.Currency);
// if (currency != null)
// {
// item.ExchangeRate = currency.DefaultRate;
// if (currency.Exchanges != null && currency.Exchanges.Count > 0)
// {
// //取当前时间范围内的最新一条
// var exchange = currency.Exchanges.FindAll(x => x.Status == StatusEnum.Enable &&
// x.StartDate >= dtNow && x.EndDate <= dtNow).OrderByDescending(x => x.UpdateTime).FirstOrDefault();
// if (exchange != null)
// item.ExchangeRate = item.FeeType == FeeType.Receivable ? exchange.DRValue : exchange.CRValue;
// }
// }
//}
}
}

@ -38,6 +38,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
{
config = provider.GetRequiredService<IConfiguration>();
TenantDb.QueryFilter.Clear<IOrgId>();
Db.QueryFilter.Clear<ITenantId>();
}
static async Task<string> RenderTemplateAsync(string name, string templateText, object model, IRazorEngine? razorEngine = null)

@ -296,7 +296,7 @@ namespace DS.WMS.Core.Op.Method.TaskInteraction
if (useTransaction)
await TenantDb.Ado.CommitTranAsync();
return result;
return DataResult.Success;
}
catch (Exception ex)
{

@ -0,0 +1,126 @@
@* @model DS.WMS.Core.Op.Entity.MailTemplateModel<DS.WMS.Core.TaskPlat.Dtos.TaskCutDateChangeShowDto> *@
@{
var item = Model.Primary;
}
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title class="head-title">邮件模板</title>
</head>
<body style="margin: 0; padding: 0;">
<table border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#EDF9F5" style="font-size: 12px;font-family: Arial;">
<tr>
<td height="30"></td>
</tr>
<tr>
<td>
<table class="out-table" border="0" cellpadding="8" cellspacing="0" width="800" bgcolor="#FFFFFF" align="center" style="font-size: 12px;font-family: Arial;">
<tr>
<td>
<p>Dear customer,</p>
</td>
</tr>
<tr>
<td>
<p>Please kindly note SI/Voucher/CY cut-off change of @item.Vessel/@item.VoyNo, bookings were arranged below:</p>
</td>
</tr>
@if (item.PortloadArea == "SOUTH_PORT")
{
<tr>
<td>
<table id="show-table" border="1" cellpadding="8" cellspacing="0" width="100%" align="left" style="border-collapse: collapse;border-color: #ebeef5;font-size: 12px;font-family: Arial;">
<tr>
<th style="text-align: left;">Shipment</th>
<th style="text-align: left;">Container</th>
<th style="text-align: left;">Load Port</th>
<th style="text-align: left;">ETB</th>
<th style="text-align: left;">ETD</th>
</tr>
<tr>
<td>@item.MBLNo</td>
<td>@item.ContaNo</td>
<td>@item.LoadPort</td>
<td>@item.ETBTxt</td>
<td>@item.ETDTxt</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<p class="south_port">Reason: @item.Reason</p>
<p class="south_port">New SI cut-off: @item.SICutDateTxt</p>
<p class="south_port">New VGM Submission Deadline: @item.VGMCutoffTimeTxt</p>
<p class="south_port">New Closing Time of CY cut-off: @item.CYCutoffTimeTxt</p>
<p class="south_port">New Closing Time of Voucher cut: @item.VoucherCutoffTimeTxt</p>
<p class="south_port">New CY Open Date: @item.CYOpenDateTxt</p>
<p><font style="color: #f70f0f; font-weight: 500;">请注意,以上开仓日期仅供参考,为避免产生额外费用,请参考码头网站信息、约定免费时间或其他标准协议时间,并按相应时间提箱、还柜.</font></p>
</td>
</tr>
}
else
{
<tr>
<td>
<table id="show-table" border="1" cellpadding="8" cellspacing="0" width="100%" align="left" style="border-collapse: collapse;border-color: #ebeef5;font-size: 12px;font-family: Arial;">
<tr>
<th style="text-align: left;">Shipment Number</th>
<th style="text-align: left;">Vessel - voyage</th>
<th style="text-align: left;">样单截止时间 SI Cut Off</th>
<th style="text-align: left;">开港时间 CY Open</th>
<th style="text-align: left;">截港时间 CY cut off</th>
<th style="text-align: left;">舱单-入港清单截止时间</th>
<th style="text-align: left;">MDGF提交截止时间 - 危险品货物</th>
<th style="text-align: left;">船代VGM截止时间</th>
<th style="text-align: left;">海关放行截止时间(Customs Clearance Deadline)</th>
</tr>
<tr>
<td>@item.MBLNo</td>
<td>@item.Vessel/@item.VoyNo</td>
<td>@item.SICutDateTxt</td>
<td>@item.CYOpenDateTxt</td>
<td>@item.CYCutoffTimeTxt</td>
<td>@item.ManifestCutDateTxt</td>
<td>@item.MDGFCutDateTxt</td>
<td>@item.VGMCutoffTimeTxt</td>
<td>@item.ClosingDateTxt</td>
</tr>
</table>
</td>
</tr>
}
<tr>
<td>
<p>对于出口至埃及或加蓬但由非MSK船舶承运:</p>
<p>1)如是危险品, 提单样本截止时间与MDGF截止时间一致</p>
<p>2)如是冷箱和/或其他特种柜货物, 提单样本截止时间与最晚提箱时间保持一致。</p>
<p><font style="color: #f70f0f; font-weight: 500;">In case youre exporting DG shipment, MDGF deadline will be indicated on new booking confirmation which will be sent to you within 8 working hours.</font></p>
</td>
</tr>
<tr>
<td>
<p>For Export shipment</p>
<p>Please kindly submit SI/ gate-in laden container as per new closing time.</p>
<p>We thank you for your continuous support and regret for any inconvenience caused by this changed.</p>
<p>Please do not hesitate to contact your local customer service representatives for any questions.</p>
</td>
</tr>
<tr class="email-noreply">
<td>
<p class="notice2-val"><font style="color: #4051f0; font-weight: 500;">注意: 本邮箱不具备收件功能,如对本通知有疑问,</font><font style="background-color: #f1de2f; font-weight: 500;">请联系 @Model.Sender.DisplayName邮箱 @Model.Sender.MailAddress电话 @Model.Sender.Phone谢谢</font></p>
<p>Best Regards,</p>
<p class="notice-comp-val">@item.TenantCompanyName</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

@ -11,6 +11,16 @@ namespace DS.WMS.Core.TaskPlat.Dtos
/// </summary>
public class TaskCutDateChangeShowDto
{
/// <summary>
/// 装货港区域 NORTH_PORT-华北港口 SOUTH-华南港口
/// </summary>
public string PortloadArea { get; set; }
/// <summary>
/// 订单ID
/// </summary>
public long BookingId { get; set; }
/// <summary>
/// 提单号
/// </summary>
@ -126,14 +136,44 @@ namespace DS.WMS.Core.TaskPlat.Dtos
/// </summary>
public Nullable<DateTime> ETD { get; set; }
/// <summary>
/// 预计离港时间文本
/// </summary>
public string ETDTxt { get; set; }
/// <summary>
/// 预计靠泊时间
/// </summary>
public Nullable<DateTime> ETB { get; set; }
/// <summary>
/// 预计靠泊时间文本
/// </summary>
public string ETBTxt { get; set; }
/// <summary>
/// 截补料时间
/// </summary>
public Nullable<DateTime> VoucherCutoffTime { get; set; }
/// <summary>
/// 截补料时间文本
/// </summary>
public string VoucherCutoffTimeTxt { get; set; }
/// <summary>
/// 邮件标题
/// </summary>
public string EmailTitle { get; set; }
/// <summary>
/// 租户ID
/// </summary>
public long TenantId { get; set; }
/// <summary>
/// 租户名称
/// </summary>
public string TenantCompanyName { get; set; }
}
}

@ -209,24 +209,27 @@ namespace DS.WMS.Core.TaskPlat.Dtos.Mapper
.Map(dest => dest.Vessel, src => src.VESSEL)
.Map(dest => dest.VoyNo, src => src.VOYNO)
.Map(dest => dest.SICutDate, src => src.SI_CUTOFF)
.Map(dest => dest.SICutDateTxt, src => src.SI_CUTOFF_TXT)
.Map(dest => dest.SICutDateTxt, src => src.SI_CUTOFF.HasValue? src.SI_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm") : src.SI_CUTOFF_TXT)
.Map(dest => dest.CYOpenDate, src => src.CY_OPEN)
.Map(dest => dest.CYOpenDateTxt, src => src.CY_OPEN_TXT)
.Map(dest => dest.CYOpenDateTxt, src => src.CY_OPEN.HasValue ? src.CY_OPEN.Value.ToString("yyyy-MM-dd HH:mm") : src.CY_OPEN_TXT)
.Map(dest => dest.CYCutoffTime, src => src.CY_CUTOFF)
.Map(dest => dest.CYCutoffTimeTxt, src => src.CY_CUTOFF_TXT)
.Map(dest => dest.CYCutoffTimeTxt, src => src.CY_CUTOFF.HasValue ? src.CY_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm") : src.CY_CUTOFF_TXT)
.Map(dest => dest.ManifestCutDate, src => src.MANIFEST_CUT)
.Map(dest => dest.ManifestCutDateTxt, src => src.MANIFEST_CUT_TXT)
.Map(dest => dest.ManifestCutDateTxt, src => src.MANIFEST_CUT.HasValue ? src.MANIFEST_CUT.Value.ToString("yyyy-MM-dd HH:mm") : src.MANIFEST_CUT_TXT)
.Map(dest => dest.MDGFCutDate, src => src.MDGF_CUT)
.Map(dest => dest.MDGFCutDateTxt, src => src.MDGF_CUT_TXT)
.Map(dest => dest.MDGFCutDateTxt, src => src.MDGF_CUT.HasValue ? src.MDGF_CUT.Value.ToString("yyyy-MM-dd HH:mm") : src.MDGF_CUT_TXT)
.Map(dest => dest.VGMCutoffTime, src => src.VGM_CUT)
.Map(dest => dest.VGMCutoffTimeTxt, src => src.VGM_CUT_TXT)
.Map(dest => dest.VGMCutoffTimeTxt, src => src.VGM_CUT.HasValue ? src.VGM_CUT.Value.ToString("yyyy-MM-dd HH:mm") : src.VGM_CUT_TXT)
.Map(dest => dest.ClosingDate, src => src.CLOSING_DATE)
.Map(dest => dest.ClosingDateTxt, src => src.CLOSING_DATE_TXT)
.Map(dest => dest.ClosingDateTxt, src => src.CLOSING_DATE.HasValue ? src.CLOSING_DATE.Value.ToString("yyyy-MM-dd HH:mm") : src.CLOSING_DATE_TXT)
.Map(dest => dest.ContaNo, src => src.CONTA_NO)
.Map(dest => dest.LoadPort, src => src.LOAD_PORT)
.Map(dest => dest.ETB, src => src.ETB)
.Map(dest => dest.ETBTxt, src => src.ETB.HasValue ? src.ETB.Value.ToString("yyyy-MM-dd HH:mm") : "")
.Map(dest => dest.ETD, src => src.ETD)
.Map(dest => dest.VoucherCutoffTime, src => src.VOUCHER_CUT_DATE);
.Map(dest => dest.ETDTxt, src => src.ETD.HasValue ? src.ETD.Value.ToString("yyyy-MM-dd HH:mm") : "")
.Map(dest => dest.VoucherCutoffTime, src => src.VOUCHER_CUT_DATE)
.Map(dest => dest.VoucherCutoffTimeTxt, src => src.VOUCHER_CUT_DATE.HasValue ? src.VOUCHER_CUT_DATE.Value.ToString("yyyy-MM-dd HH:mm") : "");
}
{

@ -5,6 +5,11 @@
/// </summary>
public sealed class QueryTaskManageDto
{
/// <summary>
/// 业务编号(提单号或委托编号)
/// </summary>
public string BusinessNo { get; set; }
/// <summary>
/// 提单号
/// </summary>

@ -6,5 +6,11 @@
/// 查询条件
/// </summary>
public string QueryCondition { get; set; } = string.Empty;
/// <summary>
/// 业务编号(提单号或委托编号)
/// </summary>
public string BusinessNo { get; set; }
}
}

@ -89,7 +89,35 @@ namespace DS.WMS.Core.TaskPlat.Entity
[SugarColumn(ColumnDescription = "任务批次号", IsNullable = true, Length = 64)]
public string? TASK_BATCH_NO { get; set; }
/// <summary>
/// 是否已转发客户 1-是 0-否
/// </summary>
[SugarColumn(ColumnDescription = "是否已转发客户 1-是 0-否", IsNullable = true, Length = 1)]
public Nullable<bool> IS_TRANSFER_USER { get; set; }
/// <summary>
/// 最后转发客户邮件时间
/// </summary>
[SugarColumn(ColumnDescription = "最后转发客户邮件时间", IsNullable = true)]
public DateTime? LST_TRANSFER_USER_DATE { get; set; }
/// <summary>
/// 最后转发客户邮件结果
/// </summary>
[SugarColumn(ColumnDescription = "最后转发客户邮件结果", IsNullable = true, Length = 500)]
public string? LST_TRANSFER_NOTES { get; set; }
/// <summary>
/// 最后转发客户邮件状态 TEMP-暂存 SUCC-发送成功 FAILURE-发送失败
/// </summary>
[SugarColumn(ColumnDescription = "最后转发客户邮件状态 TEMP-暂存 SUCC-发送成功 FAILURE-发送失败", IsNullable = true, Length = 20)]
public string? LST_STATUS { get; set; }
/// <summary>
/// 最后转发客户邮件状态名称
/// </summary>
[SugarColumn(ColumnDescription = "最后转发客户邮件状态名称", IsNullable = true, Length = 50)]
public string? LST_STATUS_NAME { get; set; }
}
}

@ -1,4 +1,5 @@
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.DjyServiceStatus;
using DS.WMS.Core.Op.Dtos;
using DS.WMS.Core.TaskPlat.Dtos;
@ -36,12 +37,28 @@ namespace DS.WMS.Core.TaskPlat.Interface
/// <returns>返回回执</returns>
Task<DataResult> AutoUpdateOrderCutDateAndTranmitToCustomer(long taskPKId);
/// <summary>
/// 发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">截止时间变更主键</param>
/// <param name="taskPKId">起运港未提箱任务主键</param>
/// <param name="businessTaskMailId">邮件模板主键</param>
/// <returns>返回回执</returns>
Task<DataResult<TaskTransferMsgDto>> InnerSendEmailToCustomer(long taskPKId, long businessTaskMailId);
/// <summary>
/// 发送邮件通知给客户(任务自动机调取)
/// </summary>
/// <param name="dataContext">数据上下文</param>
/// <returns>返回回执</returns>
Task<DataResult<TaskTransferMsgDto>> SendEmailToCustomerTask(TaskFlowDataContext dataContext);
/// <summary>
/// 手工发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">起运港未提箱任务主键</param>
/// <returns>返回回执</returns>
Task<DataResult> SendEmailToCustomer(long taskPKId);
Task<DataResult<TaskTransferMsgDto>> ManualSendEmailToCustomer(long taskPKId);
}
}

@ -39,35 +39,38 @@ using DS.WMS.Core.Op.EDI;
using DS.WMS.Core.Sys.Dtos;
using DS.WMS.Core.Code.Dtos;
using DS.Module.Core.Data;
using DS.WMS.Core.Op.Entity.TaskInteraction;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using DS.WMS.Core.Op.Method.TaskInteraction;
namespace DS.WMS.Core.TaskPlat.Method
{
/// <summary>
/// 截止时间变更
/// </summary>
public class TaskManageCutDateChangeService: ITaskManageCutDateChangeService
public class TaskManageCutDateChangeService: TaskManageBaseService<TaskManageCutDateChangeService>,ITaskManageCutDateChangeService
{
private readonly IServiceProvider _serviceProvider;
private readonly ISqlSugarClient db;
private readonly IUser user;
private readonly ISaasDbService saasService;
private readonly ISeaExportService _seaExportService;
private readonly IConfigService _configService;
private readonly IUserService _userService;
private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
const string EMAIL_API_URL = "email_api_url";
public TaskManageCutDateChangeService(IServiceProvider serviceProvider)
private readonly ITaskLogService _logService;
private readonly ITaskMailService _taskMailService;
private readonly ITaskAllocationService _taskAllocationService;
public TaskManageCutDateChangeService(IUser user, ILogger<TaskManageCutDateChangeService> logger,
ISaasDbService saasDbService,
IServiceProvider serviceProvider,
IWebHostEnvironment environment) : base(user, logger, saasDbService, serviceProvider, environment)
{
_serviceProvider = serviceProvider;
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
_seaExportService = _serviceProvider.GetRequiredService<ISeaExportService>();
_configService = _serviceProvider.GetRequiredService<IConfigService>();
_userService = _serviceProvider.GetRequiredService<IUserService>();
user = serviceProvider.GetRequiredService<IUser>();
_seaExportService = serviceProvider.GetRequiredService<ISeaExportService>();
_configService = serviceProvider.GetRequiredService<IConfigService>();
_userService = serviceProvider.GetRequiredService<IUserService>();
_taskMailService = serviceProvider.GetRequiredService<ITaskMailService>();
_taskAllocationService = serviceProvider.GetRequiredService<ITaskAllocationService>();
}
#region 通过任务主键获取截止时间变更详情
@ -80,7 +83,7 @@ namespace DS.WMS.Core.TaskPlat.Method
{
List<TaskCutDateChangeShowDto> list = new List<TaskCutDateChangeShowDto>();
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
@ -89,7 +92,7 @@ namespace DS.WMS.Core.TaskPlat.Method
.Where((a, b) => a.Id == taskPKId)
.Select((a, b) => new { Base = a, Cut = b })
.ToListAsync();
//任务主键{taskPkId}无法获取业务信息
if (queryList.Count == 0)
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseInfoFromTaskIdNull)), taskPKId));
@ -99,7 +102,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var detailList = await tenantDb.Queryable<TaskCutDateChangeDetailInfo>()
.Where(a => parentIdList.Contains(a.P_ID)).ToListAsync();
if (detailList.Count > 0)
if (queryList.Count > 0)
{
list = detailList.OrderBy(p => p.MBL_NO).Select(p =>
{
@ -127,7 +130,7 @@ namespace DS.WMS.Core.TaskPlat.Method
SeaExportOrderExtension orderInfo = null;
try
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
@ -198,7 +201,7 @@ namespace DS.WMS.Core.TaskPlat.Method
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 检索截止时间变更订舱记录 处理异常,原因:{ex.Message}");
logger.LogError($"taskPKId={taskPKId} 检索截止时间变更订舱记录 处理异常,原因:{ex.Message}");
return DataResult<SeaExportOrderExtension>.FailedData(orderInfo,$"检索失败,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
@ -235,14 +238,14 @@ namespace DS.WMS.Core.TaskPlat.Method
var slotRlt = UpdateBookingSlotCutDate(taskPKId, orderInfo);
//如果没有配置批量,则按单票发送邮件
var rlt = await SendEmailToCustomer(taskPKId);
//var rlt = await SendEmailToCustomer(taskPKId);
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 推送邮件完成,结果:{JsonConvert.SerializeObject(rlt)}");
//logger.LogInformation($"taskPKId={taskPKId} 推送邮件完成,结果:{JsonConvert.SerializeObject(rlt)}");
}
catch(Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期并转发失败异常,原因:{ex.Message}");
//Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期并转发失败异常,原因:{ex.Message}");
return DataResult.Failed( $"自动更新订单的截单日期并转发失败,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
@ -260,7 +263,7 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <returns>返回回执</returns>
private async Task<DataResult> UpdateBookingOrderCutDate(long taskPKId, SeaExportOrderExtension orderInfo)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
@ -287,7 +290,7 @@ namespace DS.WMS.Core.TaskPlat.Method
if (orderInfo.otherOrderList.Count > 0)
ids.AddRange(orderInfo.otherOrderList.Select(a => a.Id).ToList());
Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} MBLNO={cutDetail.MBL_NO} 检索海运出口订单匹配到拆票信息 ids={string.Join(",", ids.ToArray())}");
//Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} MBLNO={cutDetail.MBL_NO} 检索海运出口订单匹配到拆票信息 ids={string.Join(",", ids.ToArray())}");
}
foreach (var id in ids)
@ -325,13 +328,13 @@ namespace DS.WMS.Core.TaskPlat.Method
it.CloseDocDate
}).ExecuteCommand();
Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} id={id} mblno={bookingInfo.MBLNO} 更新订舱完毕 详情 {doBuilder.ToString()}");
//Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} id={id} mblno={bookingInfo.MBLNO} 更新订舱完毕 详情 {doBuilder.ToString()}");
}
}
}
catch(Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新订舱异常,原因:{ex.Message}");
//Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新订舱异常,原因:{ex.Message}");
return DataResult.Failed($"自动更新订单的截单日期更新订舱,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
@ -349,7 +352,7 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <returns>返回回执</returns>
private async Task<DataResult> UpdateBookingSlotCutDate(long taskPKId, SeaExportOrderExtension orderInfo)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
//任务不考虑OrgId,这里去掉
tenantDb.QueryFilter.Clear<IOrgId>();
@ -410,13 +413,13 @@ namespace DS.WMS.Core.TaskPlat.Method
it.ManifestCutDate
}).ExecuteCommand();
Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} id={cutBase.Id} mblno={slotOrder.SlotBookingNo} 更新舱位完毕 详情 {doBuilder.ToString()}");
//Logger.Log(NLog.LogLevel.Info, $"截止时间变更主键{taskPKId} id={cutBase.Id} mblno={slotOrder.SlotBookingNo} 更新舱位完毕 详情 {doBuilder.ToString()}");
}
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新舱位异常,原因:{ex.Message}");
//Logger.Log(NLog.LogLevel.Info, $"taskPKId={taskPKId} 自动更新订单的截单日期更新舱位异常,原因:{ex.Message}");
return DataResult.Failed($"自动更新订单的截单日期更新舱位,原因:{ex.Message}", MultiLanguageConst.Operation_Failed);
}
@ -426,475 +429,302 @@ namespace DS.WMS.Core.TaskPlat.Method
#endregion
#region 发送邮件通知给客户
/// <summary>
/// 发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">截止时间变更主键</param>
/// <param name="taskPKId">起运港未提箱主键</param>
/// <param name="businessTaskMailId">邮件模板主键</param>
/// <returns>返回回执</returns>
public async Task<DataResult> SendEmailToCustomer(long taskPKId)
{
return null;
}
#endregion
#region 生成并转发通知邮件
/// <summary>
/// 生成并转发通知邮件
/// </summary>
/// <param name="model"></param>
/// <param name="bookingOrderList"></param>
/// <param name="bookingContactList"></param>
/// <param name="taskBaskInfo"></param>
/// <returns></returns>
[NonAction]
private async Task<TaskManageOrderResultDto> GenerateSendEmail(TaskCutDateChangeInfo model, List<TaskCutDateChangeDetailInfo> rowList, List<SeaExportRes> bookingOrderList, List<BusinessOrderContactRes> bookingContactList)
public async Task<DataResult<TaskTransferMsgDto>> InnerSendEmailToCustomer(long taskPKId, long businessTaskMailId)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
try
{
//TO 邮件接收人
string toEmail = string.Empty;
//订舱OP的邮箱
string opEmail = string.Empty;
//去重客户联系人的邮箱
toEmail = string.Join(";", bookingContactList.Select(x => x.Email.Trim()).Distinct().ToArray());
List<string> opEmailList = new List<string>();
UserViewModel opUserInfo = null;
bookingOrderList.ForEach(bk =>
{
//获取操作OP的邮箱
if (bk.OperatorId > 0)
{
var opUser = _userService.GetUserInfo(bk.OperatorId.ToString());
if (opUser.Succeeded && opUser.Data != null)
{
if (opUserInfo == null)
opUserInfo = opUser.Data;
if (!string.IsNullOrWhiteSpace(opUserInfo.Email))
{
opEmailList.Add(opUserInfo.Email.Trim());
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取操作OP的邮箱opEmail={opEmail} opid={bk.OperatorId} name={opUserInfo.UserName}");
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取操作OP的邮箱失败opEmail={opUserInfo.Email} opid={bk.OperatorId} name={opUserInfo.UserName}");
}
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 检索操作OP信息失败opid={bk.OperatorId} name={opUserInfo.UserName}");
}
}
//获取客服的邮箱
if (bk.CustomerService > 0)
{
var opUser = _userService.GetUserInfo(bk.CustomerService.ToString());
if (opUser.Succeeded && opUser.Data != null)
{
if (!string.IsNullOrWhiteSpace(opUser.Data.Email))
{
opEmailList.Add(opUser.Data.Email.Trim());
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取客服的邮箱opEmail={opEmail} opid={bk.CustomerService} name={opUser.Data.UserName}");
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 获取客服的邮箱失败opEmail={opUser.Data.Email} opid={bk.CustomerService} name={opUser.Data.UserName}");
}
}
else
{
Logger.Log(NLog.LogLevel.Info, $"id={bk.Id} mblno={bk.MBLNO} 检索客服信息失败opid={bk.CustomerService} name={opUser.Data.UserName}");
}
}
});
if (opEmailList.Count > 0)
opEmail = string.Join(";", opEmailList.Distinct().ToArray());
/*
1
2( task_base_allocation)
3
4
5
6
*/
string emailTitle = $"{model.MBL_NO} Cut-off Details {model.VESSEL}/{model.VOYNO}/";
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
if (model.PORTLOAD_AREA.Equals("NORTH_PORT", StringComparison.OrdinalIgnoreCase))
{
emailTitle = $"{model.MBL_NO} 截止时间变更 {model.VESSEL}/{model.VOYNO}/";
}
////提取当前公共邮箱的配置
//DjyUserMailAccount publicMailAccount = _djyUserMailAccount.AsQueryable().Filter(null, true).First(x => x.TenantId == UserManager.TENANT_ID && x.ShowName == "PublicSend"
// && x.SmtpPort > 0 && x.SmtpServer != null && x.SmtpServer != "");
//Logger.Log(NLog.LogLevel.Info, $"提取当前公共邮箱的配置完成id={publicMailAccount.Id}");
//if (publicMailAccount == null)
//{
// throw Oops.Oh($"提取公共邮箱配置失败请在用户邮箱账号管理增加配置显示名为PublicSend或者配置个人邮箱");
//}
////获取邮件模板
//var printTemplate = _repPrintTemplate.AsQueryable().Filter(null, true).First(x => x.CateCode.Contains("for_information_cutoff_detail") && x.TenantId == UserManager.TENANT_ID);
var entity = tenantDb.Queryable<TaskCutDateChangeInfo>().Filter(null, true).First(a => a.TASK_ID == taskPKId);
//if (printTemplate == null)
//{
// throw Oops.Bah(BookingErrorCode.BOOK115);
//}
var cutDetail = tenantDb.Queryable<TaskCutDateChangeDetailInfo>().Filter(null, true).First(a => a.P_ID == entity.Id);
CodeUserEmailRes publicMailAccount = new CodeUserEmailRes();
//读取邮件模板并填充数据
string emailHtml = "";//await GenerateSendEmailHtml(model, rowList, bookingOrderList, "", opUserInfo, user.TenantName).GetAwaiter().GetResult();
var baseInfo = tenantDb.Queryable<TaskBaseInfo>().Filter(null, true).First(a => a.Id == taskPKId);
EmailApiUserDefinedDto emailApiUserDefinedDto = new EmailApiUserDefinedDto
{
SendTo = toEmail,
//CCTo = opEmail,
Title = emailTitle,
Body = emailHtml,
Account = publicMailAccount.MailAccount?.Trim(),
Password = publicMailAccount.Password?.Trim(),
Server = publicMailAccount.SmtpServer?.Trim(),
Port = publicMailAccount.SmtpPort.HasValue ? publicMailAccount.SmtpPort.Value : 465,
UseSSL = publicMailAccount.SmtpSSL.HasValue ? publicMailAccount.SmtpSSL.Value : true,
Attaches = new List<AttachesInfo>()
};
//如果配置了租户参数AUTO_TRANS_EMAIL_OP_CCTO-自动转发是否默认抄送操作=ENABLE发送邮件时自动抄送操作
//DjyTenantParamValueOutput paramConfig = _djyTenantParamService.GetParaCodeWithValue(new[] { "AUTO_TRANS_EMAIL_OP_CCTO" }).GetAwaiter().GetResult().FirstOrDefault();
var queryRlt = await _seaExportService.SearchOrderInfo(entity.MBL_NO);
//if (paramConfig != null && paramConfig.ParaValue.Equals("ENABLE", StringComparison.OrdinalIgnoreCase))
//{
// emailApiUserDefinedDto.CCTo = opEmail;
//}
if (!queryRlt.Succeeded)
{
logger.LogInformation($"匹配订单信息失败 mblno={entity.MBL_NO},原因:{queryRlt.Message}");
Logger.Log(NLog.LogLevel.Info, $"生成请求邮件参数,结果:{JsonConvert.SerializeObject(emailApiUserDefinedDto)}");
return DataResult<TaskTransferMsgDto>.Failed($"匹配订单信息失败 mblno={entity.MBL_NO},原因:{queryRlt.Message}");
}
//推送邮件
var emailRlt = await PushEmail(emailApiUserDefinedDto);
var taskInfo = cutDetail.Adapt<TaskCutDateChangeShowDto>();
Logger.Log(NLog.LogLevel.Info, $"推送邮件完成,结果:{JsonConvert.SerializeObject(emailRlt)}");
taskInfo.PortloadArea = entity.PORTLOAD_AREA;
taskInfo.TenantCompanyName = user.TenantName;
if (emailRlt.Succeeded)
{
result.succ = true;
result.msg = "成功";
}
else
{
result.succ = false;
result.msg = emailRlt.Message;
//new EmailNoticeHelper().SendEmailNotice($"taskid={model.TASK_ID} 截止时间变更 转发通知邮件失败", $"taskid={model.TASK_ID} 转发通知邮件失败,原因:{emailRlt.msg}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
}
//生成标题
if (!string.IsNullOrWhiteSpace(taskInfo.PortloadArea) && taskInfo.PortloadArea.Equals("NORTH_PORT", StringComparison.OrdinalIgnoreCase))
{
taskInfo.EmailTitle = $"{taskInfo.MBLNo} 截止时间变更 {taskInfo.Vessel}/{taskInfo.VoyNo}/";
}
catch (Exception ex)
else
{
result.succ = false;
result.msg = $"失败,原因:{ex.Message}";
//new EmailNoticeHelper().SendEmailNotice($"taskid={model.TASK_ID} 截止时间变更 转发通知邮件失败", $"taskid={model.TASK_ID} 转发通知邮件失败,原因:{ex.Message}", App.Configuration["EmailNoticeDefaultUser"].GetUserEmailList());
taskInfo.EmailTitle = $"{taskInfo.MBLNo} Cut-off Details {taskInfo.Vessel}/{taskInfo.VoyNo}/";
}
return result;
}
#endregion
BusinessTaskMail? mailConfig = _taskMailService.GetAsync(businessTaskMailId).GetAwaiter().GetResult().Data;
#region 通过邮件模板生成HTML
/// <summary>
/// 通过邮件模板生成HTML
/// </summary>
/// <param name="model">截止时间变更详情</param>
/// <param name="seaExportRes">海运出口详情</param>
/// <param name="filePath">文件路径</param>
/// <param name="opUserInfo">相关操作OP</param>
/// <param name="tenantName">租户全称</param>
/// <returns>返回HTML字符串邮件正文</returns>
[NonAction]
private async Task<string> GenerateSendEmailHtml(TaskCutDateChangeInfo model, List<TaskCutDateChangeDetailInfo> rowList, SeaExportRes seaExportRes,
string filePath, SysUser opUserInfo, string tenantName,string fileAbsPath)
{
string result = string.Empty;
string baseHtml = string.Empty;
try
if (mailConfig == null)
{
//var opt = App.GetOptions<PrintTemplateOptions>();
//var dirAbs = opt.basePath;
//if (string.IsNullOrEmpty(dirAbs))
//{
// dirAbs = App.WebHostEnvironment.WebRootPath;
//}
await _logService.WriteLogAsync(new Op.Dtos.TaskInteraction.TaskUpdateRequest
{
BusinessId = taskPKId,
BusinessType = BusinessType.OceanShippingExport,
AutoCreateNext = true,
TaskTypeName = TaskBaseTypeEnum.CUT_MODIFY.ToString(),
//var fileAbsPath = Path.Combine(dirAbs, filePath);
//_logger.LogInformation($"查找模板文件:{fileAbsPath}");
}, $"未能根据任务配置值获取邮件模板设置");
//if (!File.Exists(fileAbsPath))
//{
// throw Oops.Bah(BookingErrorCode.BOOK115);
//}
return DataResult<TaskTransferMsgDto>.Failed("未能根据任务配置值获取邮件模板设置");
}
var orderInfo = queryRlt.Data;
baseHtml = File.ReadAllText(fileAbsPath);
logger.LogInformation($"获取订单详情成功 bookid={orderInfo.currOrder.Id}");
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.UserName))
{
baseHtml = baseHtml.Replace("#opname#", opUserInfo.UserName);
}
else
{
baseHtml = baseHtml.Replace("#opname#", "操作");
}
DateTime nowDate = DateTime.Now;
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Email))
{
baseHtml = baseHtml.Replace("#opemail#", opUserInfo.Email);
}
else
{
baseHtml = baseHtml.Replace("#opemail#", "");
}
List<long> orderIdList = new List<long> { orderInfo.currOrder.Id };
if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Phone))
{
baseHtml = baseHtml.Replace("#optel#", opUserInfo.Phone);
}
else if (opUserInfo != null && !string.IsNullOrWhiteSpace(opUserInfo.Tel))
{
baseHtml = baseHtml.Replace("#optel#", opUserInfo.Tel);
}
else
{
baseHtml = baseHtml.Replace("#optel#", "");
}
if (orderInfo.otherOrderList != null && orderInfo.otherOrderList.Count > 0)
orderIdList.AddRange(orderInfo.otherOrderList.Select(t => t.Id).ToList());
if (!string.IsNullOrWhiteSpace(model.MBL_NO))
{
baseHtml = baseHtml.Replace("#BillNo#", model.MBL_NO);
}
else
{
baseHtml = baseHtml.Replace("#BillNo#", "");
}
//如果是拆票需要处理,处理所以分票记录
if (orderInfo.currOrder.SplitOrMergeFlag == 1)
{
bool isHasAlloc = false;
if (!string.IsNullOrWhiteSpace(model.VESSEL))
{
string s = $"{model.VESSEL}/{model.VOYNO}";
baseHtml = baseHtml.Replace("#VesselVoyno#", s);
}
else
foreach (var id in orderIdList)
{
baseHtml = baseHtml.Replace("#VesselVoyno#", "");
}
var taskAllocList = tenantDb.Queryable<TaskBaseAllocation>().Where(a => a.TaskId == taskPKId).ToList();
var detailInfo = rowList.FirstOrDefault();
var searchAllotUserRlt = _taskAllocationService.GetAllotUserBySeaExportId(TaskBaseTypeEnum.CUT_MODIFY, id, new TaskFlowDataContext()).GetAwaiter().GetResult();
if (detailInfo.SI_CUTOFF.HasValue)
{
baseHtml = baseHtml.Replace("#SICutDate#", detailInfo.SI_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#SICutDate#", "");
}
if (searchAllotUserRlt.Succeeded && searchAllotUserRlt.Data?.Count > 0)
{
isHasAlloc = true;
if (detailInfo.VGM_CUT.HasValue)
{
baseHtml = baseHtml.Replace("#VGMCutDate#", detailInfo.VGM_CUT.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#VGMCutDate#", "");
}
var addUserList = searchAllotUserRlt.Data.GroupJoin(taskAllocList, l => l.RecvUserId, r => r.UserId, (l, r) =>
{
if (r.ToList().Count == 0)
return new { add = true, obl = l };
if (detailInfo.CY_CUTOFF.HasValue)
{
baseHtml = baseHtml.Replace("#CYCutDate#", detailInfo.CY_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#CYCutDate#", "");
}
return new { add = false, obl = l };
}).Where(a => a.add).Select(a => a.obl).ToList();
if (detailInfo.VOUCHER_CUT_DATE.HasValue)
{
baseHtml = baseHtml.Replace("#VoucherCutDate#", detailInfo.VOUCHER_CUT_DATE.Value.ToString("yyyy-MM-dd HH:mm"));
}
else
{
baseHtml = baseHtml.Replace("#VoucherCutDate#", "");
}
if (detailInfo.CY_OPEN.HasValue)
{
baseHtml = baseHtml.Replace("#CYOpenDate#", detailInfo.CY_OPEN.Value.ToString("yyyy-MM-dd"));
}
else
{
baseHtml = baseHtml.Replace("#CYOpenDate#", "");
if (addUserList.Count > 0)
{
//写入
addUserList.ForEach(b =>
{
var alloc = new TaskBaseAllocation
{
Status = baseInfo.STATUS,
StatusName = baseInfo.STATUS_NAME,
TaskId = taskPKId,
StatusTime = nowDate,
UserId = b.RecvUserId,
UserName = b.RecvUserName
};
tenantDb.Insertable<TaskBaseAllocation>(alloc).ExecuteCommand();
});
}
}
}
if (!string.IsNullOrWhiteSpace(detailInfo.REASON))
{
baseHtml = baseHtml.Replace("#Reason#", model.REASON);
}
else
if (isHasAlloc && baseInfo.IS_PUBLIC == 1)
{
baseHtml = baseHtml.Replace("#Reason#", "");
await tenantDb.Updateable<TaskBaseInfo>(baseInfo).UpdateColumns(x => new
{
x.IS_PUBLIC
}).ExecuteCommandAsync();
}
}
else
{
var taskAllocList = tenantDb.Queryable<TaskBaseAllocation>().Where(a => a.TaskId == taskPKId).ToList();
if (!string.IsNullOrWhiteSpace(tenantName))
if (taskAllocList.Count == 0)
{
baseHtml = baseHtml.Replace("#TenantCompanyName#", tenantName);
}
else
{
baseHtml = baseHtml.Replace("#TenantCompanyName#", "");
}
var searchAllotUserRlt = _taskAllocationService.GetAllotUserBySeaExportId(TaskBaseTypeEnum.CUT_MODIFY, orderInfo.currOrder.Id, new TaskFlowDataContext()).GetAwaiter().GetResult();
HtmlDocument html = new HtmlDocument();
html.LoadHtml(baseHtml);
var tableNode = html.DocumentNode.SelectSingleNode(".//table[@id='show-table']");
if (model.PORTLOAD_AREA.Equals("SOUTH_PORT", StringComparison.OrdinalIgnoreCase))
{
if (tableNode != null)
if (searchAllotUserRlt.Succeeded && searchAllotUserRlt.Data?.Count > 0)
{
StringBuilder tableBuilder = new StringBuilder();
//写入
searchAllotUserRlt.Data.ForEach(b =>
{
var alloc = new TaskBaseAllocation
{
Status = baseInfo.STATUS,
StatusName = baseInfo.STATUS_NAME,
TaskId = taskPKId,
StatusTime = nowDate,
UserId = b.RecvUserId,
UserName = b.RecvUserName
};
tenantDb.Insertable<TaskBaseAllocation>(alloc).ExecuteCommand();
});
for (int i = 0; i < rowList.Count; i++)
if (baseInfo.IS_PUBLIC == 1)
{
tableBuilder.Append($"<tr><td>{rowList[i].MBL_NO}</td><td>{rowList[i].CONTA_NO}</td><td>{rowList[i].LOAD_PORT}</td><td>{(rowList[i].ETB.HasValue ? rowList[i].ETB.Value.ToString("yyyy-MM-dd HH:mm") : "")}</td><td>{(rowList[i].ETD.HasValue ? rowList[i].ETD.Value.ToString("yyyy-MM-dd HH:mm") : "")}</td></tr>");
}
baseInfo.IS_PUBLIC = 0;
//生成From Vessel的table列表
tableNode.ChildNodes.Add(HtmlNode.CreateNode(tableBuilder.ToString()));
await tenantDb.Updateable<TaskBaseInfo>(baseInfo).UpdateColumns(x => new
{
x.IS_PUBLIC
}).ExecuteCommandAsync();
}
}
}
else
{
var southPNodes = html.DocumentNode.SelectNodes(".//p[@class='south_port']");
}
foreach (var node in southPNodes)
{
node.Remove();
}
TaskTransferMsgDto resultDto = new TaskTransferMsgDto
{
ExcuteDate = nowDate,
Detail = new List<TaskTransferMsgDataDto>()
};
tableNode.RemoveAllChildren();
Dictionary<long, Tuple<bool, string, string>> dict = new Dictionary<long, Tuple<bool, string, string>>();
var colArg = new string[] { "Shipment Number", "Vessel - voyage", "样单截止时间 SI Cut Off", "开港时间 CY Open", "截港时间 CY cut off", "舱单-入港清单截止时间", "MDGF提交截止时间 - 危险品货物", "船代VGM截止时间", "海关放行截止时间(Customs Clearance Deadline)" };
foreach (var id in orderIdList)
{
TaskTransferMsgDataDto detail = new TaskTransferMsgDataDto
{
BusinessId = id,
};
tableNode.ChildNodes.Add(HtmlNode.CreateNode($"<tr><th style=\"text-align: left;\">{(string.Join("</th><th style=\"text-align: left;\">", colArg))}</th></tr>"));
var model = new MailTemplateModel<TaskCutDateChangeShowDto>(taskInfo)
{
BusinessId = id,
BusinessType = BusinessType.OceanShippingExport,
};
StringBuilder tableBuilder = new StringBuilder();
MailService mailService = new MailService(serviceProvider);
var result = await mailService.SendAsync(mailConfig, model);
for (int i = 0; i < rowList.Count; i++)
if (!result.Succeeded)
{
await _logService.WriteLogAsync(new Op.Dtos.TaskInteraction.TaskUpdateRequest
{
tableBuilder.Append($"<tr><td>{rowList[i].MBL_NO}</td>");
tableBuilder.Append($"<td>{($"{rowList[i].VESSEL}/{rowList[i].VOYNO}")}</td>");
tableBuilder.Append($"<td>{(rowList[i].SI_CUTOFF.HasValue ? rowList[i].SI_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].SI_CUTOFF_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].CY_OPEN.HasValue ? rowList[i].CY_OPEN.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].CY_OPEN_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].CY_CUTOFF.HasValue ? rowList[i].CY_CUTOFF.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].CY_CUTOFF_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].MANIFEST_CUT.HasValue ? rowList[i].MANIFEST_CUT.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].MANIFEST_CUT_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].MDGF_CUT.HasValue ? rowList[i].MDGF_CUT.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].MDGF_CUT_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].VGM_CUT.HasValue ? rowList[i].VGM_CUT.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].VGM_CUT_TXT)}</td>");
tableBuilder.Append($"<td>{(rowList[i].CLOSING_DATE.HasValue ? rowList[i].CLOSING_DATE.Value.ToString("yyyy-MM-dd HH:mm") : rowList[i].CLOSING_DATE_TXT)}</td>");
tableBuilder.Append("</tr>");
}
BusinessId = taskPKId,
BusinessType = BusinessType.OceanShippingExport,
AutoCreateNext = true,
TaskTypeName = TaskBaseTypeEnum.CUT_MODIFY.ToString(),
//生成From Vessel的table列表
tableNode.ChildNodes.Add(HtmlNode.CreateNode(tableBuilder.ToString()));
}
}, result.Message);
//return DataResult.Failed(result.Message);
}
result = html.DocumentNode.OuterHtml;
detail.Status = result.Succeeded ? "SUCC" : "FAILURE";
detail.Message = result.Message;
detail.MBlNo = entity.MBL_NO;
resultDto.Detail.Add(detail);
dict.Add(id, new Tuple<bool, string, string>(result.Succeeded, result.Message, entity.MBL_NO));
}
catch (Exception ex)
//如果存在失败记录,不能置完成状态
if (!dict.Any(t => !t.Value.Item1))
{
Logger.Log(NLog.LogLevel.Info, $"生成截止时间变更转发邮件正文失败,原因:{ex.Message}");
entity.IS_TRANSFER_USER = true;
entity.LST_TRANSFER_USER_DATE = DateTime.Now;
entity.LST_STATUS = "SUCC";
entity.LST_STATUS_NAME = "发送成功";
//提单号 {0} 生成截止时间变更转发邮件正文失败,原因:{1}
throw new Exception(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TaskBaseCutDateTransmitGenerateEmailFail)), model.MBL_NO, ex.Message));
await tenantDb.Updateable<TaskCutDateChangeInfo>(entity).UpdateColumns(x => new
{
x.IS_TRANSFER_USER,
x.LST_TRANSFER_USER_DATE,
x.LST_STATUS,
x.LST_STATUS_NAME
}).ExecuteCommandAsync();
//发送完邮件,自动标记任务状态为完成
await SetTaskStatus(taskPKId, TaskBaseTypeEnum.CUT_MODIFY, TaskStatusEnum.Complete, DateTime.Now, null);
}
return result;
return DataResult<TaskTransferMsgDto>.Success(resultDto);
}
#endregion
#region 推送邮件
#region 发送邮件通知给客户(任务自动机调取)
/// <summary>
/// 推送邮件
/// 发送邮件通知给客户(任务自动机调取)
/// </summary>
/// <param name="emailApiUserDefinedDto">自定义邮件详情</param>
/// <param name="dataContext">数据上下文</param>
/// <returns>返回回执</returns>
private async Task<DataResult<string>> PushEmail(EmailApiUserDefinedDto emailApiUserDefinedDto)
public async Task<DataResult<TaskTransferMsgDto>> SendEmailToCustomerTask(TaskFlowDataContext dataContext)
{
List<EmailApiUserDefinedDto> emailList = new List<EmailApiUserDefinedDto>();
var emailUrl = _configService.GetConfig(EMAIL_API_URL, long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
var taskPKId = dataContext.Get<long>(TaskFlowDataNameConst.TaskPKId);
if (taskPKId == 0)
throw new ArgumentException($"缺少参数:{nameof(TaskFlowDataNameConst.TaskPKId)}");
if (emailUrl == null)
throw new Exception(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.CurrTenantEmailApiUrlNull)));
var businessTaskMailId = dataContext.Get<long>($"{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}");
if (businessTaskMailId == 0)
throw new ArgumentException($"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}");
emailList.Add(emailApiUserDefinedDto);
DateTime bDate = DateTime.Now;
string res = string.Empty;
var jsonBody = JsonConvert.SerializeObject(emailList, Formatting.Indented, new JsonSerializerSettings
if (businessTaskMailId == 0)
{
NullValueHandling = NullValueHandling.Ignore
});
await _logService.WriteLogAsync(new Op.Dtos.TaskInteraction.TaskUpdateRequest
{
BusinessId = taskPKId,
BusinessType = BusinessType.OceanShippingExport,
AutoCreateNext = true,
TaskTypeName = TaskBaseTypeEnum.CUT_MODIFY.ToString(),
Logger.Log(NLog.LogLevel.Info, $"发送邮件请求:{jsonBody}");
}, $"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}");
try
{
res = RequestHelper.Post(jsonBody, emailUrl);
return DataResult<TaskTransferMsgDto>.Failed($"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}");
}
catch (Exception ex)
{
Logger.Log(NLog.LogLevel.Info, $"发送邮件异常:{ex.Message}");
return DataResult<string>.Failed(string.Format(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.TransmitEmailFail)), ex.Message));
}
return await InnerSendEmailToCustomer(taskPKId, businessTaskMailId);
}
#endregion
DateTime eDate = DateTime.Now;
TimeSpan ts = eDate.Subtract(bDate);
var timeDiff = ts.TotalMilliseconds;
#region 手工发送邮件通知给客户
/// <summary>
/// 手工发送邮件通知给客户
/// </summary>
/// <param name="taskPKId">起运港未提箱任务主键</param>
/// <returns>返回回执</returns>
public async Task<DataResult<TaskTransferMsgDto>> ManualSendEmailToCustomer(long taskPKId)
{
var paramConfig = _configService.GetConfig("CutDateChangeEmailTemplateID", long.Parse(user.TenantId), false).GetAwaiter().GetResult()?.Data?.Value;
Logger.Log(NLog.LogLevel.Info, $"发送邮件返回:{res}");
long businessTaskMailId = 0;
if (!string.IsNullOrWhiteSpace(res))
if (!string.IsNullOrWhiteSpace(paramConfig))
{
var respObj = JsonConvert.DeserializeAnonymousType(res, new
{
Success = false,
Message = string.Empty,
Code = -9999,
});
if(respObj.Success)
{
return DataResult<string>.Success(respObj.Message);
}
return DataResult<string>.Failed(respObj.Message);
businessTaskMailId = long.Parse(paramConfig);
}
else
{
return DataResult<TaskTransferMsgDto>.Failed($"缺少系统参数参数:截止时间变更邮件模板ID-\tCutDateChangeEmailTemplateID");
}
return DataResult<string>.Failed(res);
return await InnerSendEmailToCustomer(taskPKId, businessTaskMailId);
}
#endregion
}

@ -352,8 +352,13 @@ namespace DS.WMS.Core.TaskPlat.Method
/// <returns>返回回执</returns>
public async Task<DataResult<TaskTransferMsgDto>> SendEmailToCustomerTask(TaskFlowDataContext dataContext)
{
var taskPKId = dataContext.Get<Nullable<long>>(TaskFlowDataNameConst.TaskPKId) ?? throw new ArgumentException($"缺少参数:{nameof(TaskFlowDataNameConst.TaskPKId)}");
var businessTaskMailId = dataContext.Get<Nullable<long>>($"{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}") ?? throw new ArgumentException();
var taskPKId = dataContext.Get<long>(TaskFlowDataNameConst.TaskPKId);
if (taskPKId == 0)
throw new ArgumentException($"缺少参数:{nameof(TaskFlowDataNameConst.TaskPKId)}");
var businessTaskMailId = dataContext.Get<long>($"{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}");
if (businessTaskMailId == 0)
throw new ArgumentException($"缺少参数:{nameof(BusinessTaskMail)}.{nameof(BusinessTaskMail.Id)}");
if (businessTaskMailId == 0)
{

@ -273,7 +273,7 @@ namespace DS.WMS.Core.TaskPlat.Method
// 查出涉及到的订单
SeaExportRes? order = null;
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
if (dataContext.ContainsKey(TaskFlowDataNameConst.Business))
if (dataContext != null && dataContext.ContainsKey(TaskFlowDataNameConst.Business))
{
order = dataContext.Get<SeaExportRes>(TaskFlowDataNameConst.Business);
}
@ -403,7 +403,7 @@ namespace DS.WMS.Core.TaskPlat.Method
// 查出涉及到的订单
SeaExportRes? order = null;
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
if (dataContext.ContainsKey(TaskFlowDataNameConst.Business))
if (dataContext != null && dataContext.ContainsKey(TaskFlowDataNameConst.Business))
{
order = dataContext.Get<SeaExportRes>(TaskFlowDataNameConst.Business);
}

@ -322,7 +322,7 @@ namespace DS.WMS.Core.TaskPlat.Method
// TaskBaseInfo.TASK_REQ_USERID 制单人只有一个人使用任务创建报文中传入的TaskUserId
// TaskBaseAllocation.UserId 任务关系任务属于谁谁能够查看并处理可能是多个人可能是多个人一起处理取值优先级info.Main.RecvUserInfoList>关联订单
// TaskBaseInfo.RealUserId 实际操作人:谁实际处理的,只有一个人(但是工作流过来的任务会由多个人处理)
// 创建人
taskInfo.CreateBy = long.Parse(user.UserId);
taskInfo.CreateUserName = user.UserName;
@ -1594,11 +1594,14 @@ namespace DS.WMS.Core.TaskPlat.Method
await tenantDb.Insertable(taskPOLContainerNotPickUpInfo).ExecuteCommandAsync();
////触发推送消息
//var name = _namedTaskPOLContainerNotPickUpServiceProvider
// .GetService<ITransient>(nameof(TaskPOLContainerNotPickUpService));
//出发任务流程
TaskFlowDataContext dataContext = new(
// 固定
(TaskFlowDataNameConst.TaskPKId, taskInfo.Id)
);
//await name.AutoTransferNotice(taskInfo.PK_ID);
TaskFlowRuner taskFlow = new TaskFlowRuner(tenantDb, serviceProvider);
await taskFlow.Run(info.Main.TaskType, taskInfo.Id, dataContext);
}
#endregion
@ -1662,13 +1665,13 @@ namespace DS.WMS.Core.TaskPlat.Method
// 格式化参数
TaskBaseTypeEnum? taskType = null;
if (Enum.TryParse(typeof(TaskBaseTypeEnum), querySearch.OtherQueryCondition?.TaskType, out object? temp))
if (Enum.TryParse(typeof(TaskBaseTypeEnum), querySearch.OtherQueryCondition.TaskType, out object? temp))
{
taskType = (TaskBaseTypeEnum)temp;
};
TaskStatLevelEnum? taskStatLevel = null;
//TaskStatLevelEnum? taskStatLevel = TaskStatLevelEnum.PUBLIC;
if (Enum.TryParse(typeof(TaskStatLevelEnum), querySearch.OtherQueryCondition?.TaskCategory, out object? tempStat))
if (Enum.TryParse(typeof(TaskStatLevelEnum), querySearch.OtherQueryCondition.TaskCategory, out object? tempStat))
{
taskStatLevel = (TaskStatLevelEnum)tempStat;
}
@ -1688,7 +1691,7 @@ namespace DS.WMS.Core.TaskPlat.Method
.LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskBCInfo>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -1781,7 +1784,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskSiSubmitted>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -1838,7 +1841,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskPerBillBase>((t, a, bc) => t.Id == bc.TASK_PKID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -1865,7 +1868,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskTruck>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -1933,7 +1936,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskCutDateChangeInfo>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -1956,7 +1959,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskRollingNomination>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -1976,8 +1979,7 @@ namespace DS.WMS.Core.TaskPlat.Method
//bc.REMARK,
bc.TASK_BATCH_TOTAL,
bc.TASK_BATCH_PER_TOTAL
})
.Distinct().ToQueryPageAsync(querySearch.PageCondition);
}).Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.DRAFT:
@ -1985,7 +1987,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskDraftInfo>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -2001,8 +2003,7 @@ namespace DS.WMS.Core.TaskPlat.Method
bc.IS_EMAIL_SEND,
bc.SEND_EMAIL_DATE,
bc.NOTICE_DATE,
})
.Distinct().ToQueryPageAsync(querySearch.PageCondition);
}).Distinct().ToQueryPageAsync(querySearch.PageCondition);
return result;
}
case TaskBaseTypeEnum.POD_DISCHARGE_FULL:
@ -2011,7 +2012,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskPodDischargeGateoutFull>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -2033,7 +2034,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskCautionNotice>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -2067,7 +2068,7 @@ namespace DS.WMS.Core.TaskPlat.Method
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId)
.LeftJoin<TaskRouteChangeAdvisory>((t, a, bc) => t.Id == bc.TASK_ID);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a, bc) => new
{
@ -2101,7 +2102,7 @@ namespace DS.WMS.Core.TaskPlat.Method
{
var queryable = tenantDb.Queryable<TaskBaseInfo>().LeftJoin<TaskBaseAllocation>((t, a) => t.Id == a.TaskId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition!.Status, userId);
SetCondition(queryable, whereList, taskType, taskStatLevel, querySearch.OtherQueryCondition, userId);
result = await queryable.Select<dynamic>((t, a) => new
{
@ -2183,6 +2184,7 @@ namespace DS.WMS.Core.TaskPlat.Method
.Where(whereList)
.Where((t, a) => t.STATUS != TaskStatusEnum.Cancel.ToString())
.Where((t, a) => t.IS_PUBLIC == 1 || (t.IS_PUBLIC == 0 && a.Status != null && (a.UserId == userId))) // 2024-8-14 boss提出只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
.WhereIF(!string.IsNullOrEmpty(querySearch.BusinessNo), (t, a) => t.MBL_NO == querySearch.BusinessNo || t.CUSTOMNER_NO == querySearch.BusinessNo)
.GroupBy((t, a) => new { t.TASK_TYPE, t.STATUS, a.Status, t.IS_PUBLIC })
.Select((t, a) => new
{
@ -2644,17 +2646,18 @@ namespace DS.WMS.Core.TaskPlat.Method
List<IConditionalModel>? whereList,
TaskBaseTypeEnum? taskType,
TaskStatLevelEnum? taskStatLevel,
string status,
QueryTaskManageDto queryTaskManageDto,
long userId)
{
queryable.ClearFilter(typeof(IOrgId))
.Where(whereList)
.Where((t, a) => t.STATUS != TaskStatusEnum.Cancel.ToString())
.WhereIF(taskType != null, (t, a) => t.TASK_TYPE == taskType.ToString())
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == status)
.WhereIF(!string.IsNullOrEmpty(queryTaskManageDto.BusinessNo), (t, a) => t.MBL_NO == queryTaskManageDto.BusinessNo || t.CUSTOMNER_NO == queryTaskManageDto.BusinessNo)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == queryTaskManageDto.Status)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0
&& (a.UserId == userId) // 2024-8-14 boss提出只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
&& a.Status == status)
&& a.Status == queryTaskManageDto.Status)
.OrderByDescending(t => t.Id);
}
@ -2665,17 +2668,18 @@ namespace DS.WMS.Core.TaskPlat.Method
List<IConditionalModel>? whereList,
TaskBaseTypeEnum? taskType,
TaskStatLevelEnum? taskStatLevel,
string status,
QueryTaskManageDto queryTaskManageDto,
long userId)
{
queryable.ClearFilter(typeof(IOrgId))
.Where(whereList)
.Where((t, a) => t.STATUS != TaskStatusEnum.Cancel.ToString())
.WhereIF(taskType != null, (t, a) => t.TASK_TYPE == taskType.ToString())
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == status)
.WhereIF(!string.IsNullOrEmpty(queryTaskManageDto.BusinessNo), (t, a) => t.MBL_NO == queryTaskManageDto.BusinessNo || t.CUSTOMNER_NO == queryTaskManageDto.BusinessNo)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PUBLIC, (t, a) => t.IS_PUBLIC == 1 && t.STATUS == queryTaskManageDto.Status)
.WhereIF(taskStatLevel == TaskStatLevelEnum.PERSON, (t, a) => t.IS_PUBLIC == 0
&& (a.UserId == userId) // 2024-8-14 boss提出只显示自己需要审批的任务自己创建的任务不显示所以去掉t.CreateBy == userId ||
&& a.Status == status)
&& a.Status == queryTaskManageDto.Status)
.OrderByDescending(t => t.Id);
}

@ -40,7 +40,7 @@ namespace DS.WMS.FeeApi.Controllers
/// <param name="request"></param>
/// <returns></returns>
[HttpPost, Route("GetFees")]
public async Task<DataResult<List<FeeAuditItem>>> GetFeesAsync([FromBody] AuditDetailRequest request)
public async Task<DataResult<PendingAuditFee>> GetFeesAsync([FromBody] AuditDetailRequest request)
{
return await _auditService.GetFeesAsync(request.Id, request.BusinessType, request.QueryCondition);
}

@ -71,9 +71,9 @@ namespace DS.WMS.FeeApi.Controllers
/// <param name="feeType">费用类型</param>
/// <returns></returns>
[HttpGet, Route("GetExchangeRate")]
public DataResult<ExchangeRate> GetExchangeRate([FromQuery] string currencyFrom, [FromQuery] string currencyTo, [FromQuery] FeeType? feeType)
public async Task<DataResult<ExchangeRate>> GetExchangeRateAsync([FromQuery] string currencyFrom, [FromQuery] string currencyTo, [FromQuery] FeeType? feeType)
{
return _invokeService.GetExchangeRate(new ExchangeRate
return await _invokeService.GetExchangeRateAsync(new ExchangeRate
{
CurrencyFrom = currencyFrom,
CurrencyTo = currencyTo,

@ -139,7 +139,7 @@ namespace DS.WMS.FeeApi.Controllers
if (model.Ids == null || model.Ids?.Length == 0)
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);
return await _feeService.SubmitForApprovalAsync(AuditType.FeeAudit, model.Remark, model.Ids);
return await _feeService.SubmitForApprovalAsync(TaskBaseTypeEnum.FEE_AUDIT, model.Remark, model.Ids);
}
/// <summary>
@ -153,7 +153,7 @@ namespace DS.WMS.FeeApi.Controllers
if (model == null || model.Ids?.Length == 0)
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);
return await _feeService.SubmitForApprovalAsync(AuditType.FeeDelete, model.Remark, model.Ids);
return await _feeService.SubmitForApprovalAsync(TaskBaseTypeEnum.FEE_DELETE_AUDIT, model.Remark, model.Ids);
}
/// <summary>

@ -152,7 +152,7 @@ namespace DS.WMS.FeeApi.Controllers
if (!ModelState.IsValid)
return DataResult.Failed(ModelState.GetErrorMessage(), MultiLanguageConst.IllegalRequest);
return await _service.SubmitApprovalAsync(AuditType.PaidApplication, model.Remark, model.Ids);
return await _service.SubmitApprovalAsync(TaskBaseTypeEnum.APPLICATION_INVOICE_AUDIT, model.Remark, model.Ids);
}
/// <summary>

@ -135,7 +135,7 @@ namespace DS.WMS.FeeApi.Controllers
if (model.Ids == null || model.Ids.Length == 0)
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);
return await _service.SubmitApprovalAsync(AuditType.PaidApplication, model.Remark, model.Ids);
return await _service.SubmitApprovalAsync(TaskBaseTypeEnum.APPLICATION_PAYMENT_AUDIT, model.Remark, model.Ids);
}
/// <summary>

@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project>
<PropertyGroup>
<_PublishTargetUrl>D:\Publish\DS8\FeeApi</_PublishTargetUrl>
<History>True|2024-08-09T01:18:05.8484398Z||;True|2024-08-09T08:45:38.7858906+08:00||;True|2024-08-05T11:37:07.3133020+08:00||;True|2024-07-24T16:45:58.2272340+08:00||;True|2024-07-24T15:48:52.0128987+08:00||;True|2024-07-23T17:41:01.7494842+08:00||;True|2024-07-23T17:25:11.8773492+08:00||;True|2024-07-23T17:07:16.5460273+08:00||;True|2024-07-22T08:59:23.3235603+08:00||;True|2024-07-12T17:35:11.1225017+08:00||;True|2024-07-11T11:40:17.3581147+08:00||;True|2024-07-04T17:20:50.0175739+08:00||;True|2024-07-02T11:26:14.2092751+08:00||;True|2024-07-02T09:21:51.3513605+08:00||;True|2024-07-01T17:47:56.0407256+08:00||;True|2024-07-01T16:42:55.7374984+08:00||;True|2024-07-01T15:49:58.9266967+08:00||;True|2024-07-01T14:35:48.1117178+08:00||;True|2024-07-01T11:41:52.2969338+08:00||;True|2024-07-01T11:13:02.6561160+08:00||;True|2024-06-28T15:28:43.1470725+08:00||;True|2024-06-28T15:16:20.1999596+08:00||;True|2024-06-28T15:14:56.2534743+08:00||;True|2024-06-28T15:02:41.3033806+08:00||;True|2024-06-28T13:37:28.2462742+08:00||;True|2024-06-28T11:06:30.7400535+08:00||;True|2024-06-26T15:24:17.1939896+08:00||;True|2024-06-26T14:33:06.3530466+08:00||;True|2024-06-26T09:45:24.4055568+08:00||;True|2024-06-25T15:45:57.6052473+08:00||;True|2024-06-25T10:17:17.7408916+08:00||;False|2024-06-25T10:16:23.5639654+08:00||;False|2024-06-25T10:15:28.3857721+08:00||;False|2024-06-25T10:10:59.5536995+08:00||;False|2024-06-25T10:07:10.4050937+08:00||;True|2024-06-24T15:22:18.2672769+08:00||;True|2024-06-24T15:01:04.8153621+08:00||;False|2024-06-24T15:00:29.9618848+08:00||;True|2024-06-24T14:07:19.9401637+08:00||;False|2024-06-24T14:06:36.1250570+08:00||;True|2024-06-21T15:13:57.4273503+08:00||;True|2024-06-21T15:04:37.8218608+08:00||;True|2024-06-21T14:12:48.0266638+08:00||;True|2024-06-21T13:52:30.0950155+08:00||;True|2024-06-20T11:02:42.9508506+08:00||;True|2024-06-19T11:43:01.1899282+08:00||;True|2024-06-19T11:23:01.2938141+08:00||;True|2024-06-18T08:51:21.6222152+08:00||;True|2024-06-17T09:20:35.0804494+08:00||;True|2024-06-17T08:41:58.1319484+08:00||;True|2024-06-17T08:38:09.0137102+08:00||;True|2024-06-14T15:19:45.7395180+08:00||;True|2024-06-14T14:38:49.7094421+08:00||;True|2024-06-14T14:27:39.2815370+08:00||;True|2024-06-14T09:42:21.5397525+08:00||;True|2024-06-13T16:03:39.8475642+08:00||;True|2024-06-13T14:12:10.1725629+08:00||;True|2024-06-13T10:46:52.6971321+08:00||;True|2024-06-11T17:03:44.8328978+08:00||;True|2024-06-06T17:41:51.1810315+08:00||;True|2024-06-06T10:57:27.8273617+08:00||;True|2024-06-04T14:23:21.3742450+08:00||;True|2024-05-31T17:01:42.4717460+08:00||;True|2024-05-31T13:56:03.0734064+08:00||;True|2024-05-31T08:45:52.3549394+08:00||;True|2024-05-30T17:16:32.8907958+08:00||;True|2024-05-30T16:18:06.9957657+08:00||;True|2024-05-29T15:44:18.4051203+08:00||;True|2024-05-29T15:11:03.1518632+08:00||;True|2024-05-29T14:52:26.0823495+08:00||;True|2024-05-29T11:17:20.2245101+08:00||;True|2024-05-29T08:36:28.9569161+08:00||;True|2024-05-28T08:44:31.4427261+08:00||;False|2024-05-28T08:44:02.5254826+08:00||;True|2024-05-27T15:16:32.9413631+08:00||;True|2024-05-27T15:03:42.9803879+08:00||;True|2024-05-27T08:49:54.3933663+08:00||;True|2024-05-27T08:46:13.5862236+08:00||;True|2024-05-23T17:19:32.8154451+08:00||;True|2024-05-23T17:19:01.4587615+08:00||;True|2024-05-22T16:52:42.2166228+08:00||;True|2024-05-22T15:19:49.1773202+08:00||;True|2024-05-22T15:13:31.9485525+08:00||;True|2024-05-22T13:29:02.1355808+08:00||;True|2024-05-22T09:48:40.8753914+08:00||;True|2024-05-22T09:25:06.2068137+08:00||;True|2024-05-22T09:18:53.0759815+08:00||;True|2024-05-21T17:13:36.4091775+08:00||;True|2024-05-21T14:41:18.8486299+08:00||;True|2024-05-21T11:04:27.3649637+08:00||;</History>
<History>True|2024-08-29T08:38:26.3491372Z||;True|2024-08-29T16:32:31.8580864+08:00||;False|2024-08-29T16:30:41.4763198+08:00||;True|2024-08-09T09:18:05.8484398+08:00||;True|2024-08-09T08:45:38.7858906+08:00||;True|2024-08-05T11:37:07.3133020+08:00||;True|2024-07-24T16:45:58.2272340+08:00||;True|2024-07-24T15:48:52.0128987+08:00||;True|2024-07-23T17:41:01.7494842+08:00||;True|2024-07-23T17:25:11.8773492+08:00||;True|2024-07-23T17:07:16.5460273+08:00||;True|2024-07-22T08:59:23.3235603+08:00||;True|2024-07-12T17:35:11.1225017+08:00||;True|2024-07-11T11:40:17.3581147+08:00||;True|2024-07-04T17:20:50.0175739+08:00||;True|2024-07-02T11:26:14.2092751+08:00||;True|2024-07-02T09:21:51.3513605+08:00||;True|2024-07-01T17:47:56.0407256+08:00||;True|2024-07-01T16:42:55.7374984+08:00||;True|2024-07-01T15:49:58.9266967+08:00||;True|2024-07-01T14:35:48.1117178+08:00||;True|2024-07-01T11:41:52.2969338+08:00||;True|2024-07-01T11:13:02.6561160+08:00||;True|2024-06-28T15:28:43.1470725+08:00||;True|2024-06-28T15:16:20.1999596+08:00||;True|2024-06-28T15:14:56.2534743+08:00||;True|2024-06-28T15:02:41.3033806+08:00||;True|2024-06-28T13:37:28.2462742+08:00||;True|2024-06-28T11:06:30.7400535+08:00||;True|2024-06-26T15:24:17.1939896+08:00||;True|2024-06-26T14:33:06.3530466+08:00||;True|2024-06-26T09:45:24.4055568+08:00||;True|2024-06-25T15:45:57.6052473+08:00||;True|2024-06-25T10:17:17.7408916+08:00||;False|2024-06-25T10:16:23.5639654+08:00||;False|2024-06-25T10:15:28.3857721+08:00||;False|2024-06-25T10:10:59.5536995+08:00||;False|2024-06-25T10:07:10.4050937+08:00||;True|2024-06-24T15:22:18.2672769+08:00||;True|2024-06-24T15:01:04.8153621+08:00||;False|2024-06-24T15:00:29.9618848+08:00||;True|2024-06-24T14:07:19.9401637+08:00||;False|2024-06-24T14:06:36.1250570+08:00||;True|2024-06-21T15:13:57.4273503+08:00||;True|2024-06-21T15:04:37.8218608+08:00||;True|2024-06-21T14:12:48.0266638+08:00||;True|2024-06-21T13:52:30.0950155+08:00||;True|2024-06-20T11:02:42.9508506+08:00||;True|2024-06-19T11:43:01.1899282+08:00||;True|2024-06-19T11:23:01.2938141+08:00||;True|2024-06-18T08:51:21.6222152+08:00||;True|2024-06-17T09:20:35.0804494+08:00||;True|2024-06-17T08:41:58.1319484+08:00||;True|2024-06-17T08:38:09.0137102+08:00||;True|2024-06-14T15:19:45.7395180+08:00||;True|2024-06-14T14:38:49.7094421+08:00||;True|2024-06-14T14:27:39.2815370+08:00||;True|2024-06-14T09:42:21.5397525+08:00||;True|2024-06-13T16:03:39.8475642+08:00||;True|2024-06-13T14:12:10.1725629+08:00||;True|2024-06-13T10:46:52.6971321+08:00||;True|2024-06-11T17:03:44.8328978+08:00||;True|2024-06-06T17:41:51.1810315+08:00||;True|2024-06-06T10:57:27.8273617+08:00||;True|2024-06-04T14:23:21.3742450+08:00||;True|2024-05-31T17:01:42.4717460+08:00||;True|2024-05-31T13:56:03.0734064+08:00||;True|2024-05-31T08:45:52.3549394+08:00||;True|2024-05-30T17:16:32.8907958+08:00||;True|2024-05-30T16:18:06.9957657+08:00||;True|2024-05-29T15:44:18.4051203+08:00||;True|2024-05-29T15:11:03.1518632+08:00||;True|2024-05-29T14:52:26.0823495+08:00||;True|2024-05-29T11:17:20.2245101+08:00||;True|2024-05-29T08:36:28.9569161+08:00||;True|2024-05-28T08:44:31.4427261+08:00||;False|2024-05-28T08:44:02.5254826+08:00||;True|2024-05-27T15:16:32.9413631+08:00||;True|2024-05-27T15:03:42.9803879+08:00||;True|2024-05-27T08:49:54.3933663+08:00||;True|2024-05-27T08:46:13.5862236+08:00||;True|2024-05-23T17:19:32.8154451+08:00||;True|2024-05-23T17:19:01.4587615+08:00||;True|2024-05-22T16:52:42.2166228+08:00||;True|2024-05-22T15:19:49.1773202+08:00||;True|2024-05-22T15:13:31.9485525+08:00||;True|2024-05-22T13:29:02.1355808+08:00||;True|2024-05-22T09:48:40.8753914+08:00||;True|2024-05-22T09:25:06.2068137+08:00||;True|2024-05-22T09:18:53.0759815+08:00||;True|2024-05-21T17:13:36.4091775+08:00||;True|2024-05-21T14:41:18.8486299+08:00||;True|2024-05-21T11:04:27.3649637+08:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NameOfLastUsedPublishProfile>D:\Code\DS\ds8-solution-pro\ds-wms-service\DS.WMS.OpApi\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
<NameOfLastUsedPublishProfile>D:\Code\ds8-solution-pro\ds-wms-service\DS.WMS.OpApi\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
<Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/MVC/Controller</Controller_SelectedScaffolderCategoryPath>
</PropertyGroup>

@ -73,9 +73,9 @@ namespace DS.WMS.TaskApi.Controllers
/// <returns>返回回执</returns>
[HttpGet]
[Route("SendEmailToCustomer")]
public async Task<DataResult> SendEmailToCustomer(long taskPKId)
public async Task<DataResult<TaskTransferMsgDto>> SendEmailToCustomer(long taskPKId)
{
return await _taskManageCutDateChangeService.SendEmailToCustomer(taskPKId);
return await _taskManageCutDateChangeService.ManualSendEmailToCustomer(taskPKId);
}
#endregion
}

Loading…
Cancel
Save