You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
16 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DS.Module.Core;
using DS.Module.Core.Data;
using DS.Module.Core.Helpers;
using DS.Module.SqlSugar;
using DS.Module.UserModule;
using DS.WMS.Core.Fee.Entity;
using DS.WMS.Core.Flow.Dtos;
using DS.WMS.Core.HangfireJob.Interface;
using DS.WMS.Core.Info.Entity;
using DS.WMS.Core.Op.Entity;
using DS.WMS.Core.Sys.Entity;
using DS.WMS.FeeBillRecvService.Dtos;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.OpenXmlFormats.Wordprocessing;
using Org.BouncyCastle.Ocsp;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using SqlSugar;
namespace DS.WMS.FeeBillRecvService
{
public class RecvFeeBillWorker : BackgroundService
{
private readonly ILogger<RecvFeeBillWorker> _logger;
private IConnection mqConn;
private IModel model;
private readonly IServiceProvider _serviceProvider;
private readonly ISqlSugarClient db;
private readonly IUser user;
private readonly ISaasDbService saasService;
public RecvFeeBillWorker(IServiceProvider serviceProvider,
ILogger<RecvFeeBillWorker> logger)
{
_logger = logger;
_serviceProvider = serviceProvider;
db = _serviceProvider.GetRequiredService<ISqlSugarClient>();
user = _serviceProvider.GetRequiredService<IUser>();
saasService = _serviceProvider.GetRequiredService<ISaasDbService>();
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("启动账单 ExecuteAsync");
return Task.Run(() =>
{
_logger.LogInformation("BookingAutoService ExecuteAsync RunTask");
//绑定队列
BindMQ();
});
}
private void BindMQ()
{
//string ExchangeName = "billcenter.output.ds7new.444c19c1-0bf5-4709-a08b-c9859ca775e6";
//string QueueName = $"billcenter.output.ds7new.444c19c1-0bf5-4709-a08b-c9859ca775e6";
string ExchangeName = AppSetting.app(new string[] { "FeeSettings", "ExchangeName" });
string QueueName = AppSetting.app(new string[] { "FeeSettings", "QueueName" });
var mqUrl = AppSetting.app(new string[] { "FeeSettings", "MQUrl" });
ConnectionFactory factory = new ConnectionFactory();
//var repoSysCfg = _serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysConfig>>();
//var mqUrl = "amqp://dongsheng8bill:dongsheng8bill@47.104.207.5:12567/billcenter";
//var mqUrl = repoSysCfg.FirstOrDefault(x => x.Code == "DjyBookingAutoMQUrl")?.Value;
if (string.IsNullOrEmpty(mqUrl))
{
_logger.LogError($"接收订舱自动化消息推送所需MQUrl未配置");
}
else
{
_logger.LogInformation($"准备连接订舱自动化消息队列:{mqUrl}");
factory.Uri = new Uri(mqUrl);
mqConn = factory.CreateConnection("东胜8接收账单邮件解析");
model = mqConn.CreateModel();
model.ExchangeDeclare(ExchangeName, ExchangeType.Topic);
model.QueueDeclare(QueueName, false, false, false, null);
model.QueueBind(QueueName, ExchangeName, "*", null);
var consumer = new EventingBasicConsumer(model);
consumer.Received += (obj, arg) =>
{
var body = arg.Body;
var strBody = Encoding.UTF8.GetString(body.ToArray());
_logger.LogInformation($"收到订舱自动化消息队列:{strBody}");
DoWork(strBody);
};
model.BasicConsume(QueueName, true, consumer);
}
}
public override void Dispose()
{
base.Dispose();
//_serviceScope.Dispose();
if (mqConn != null && mqConn.IsOpen)
mqConn.Close();
_logger.LogInformation("BookingAutoService Dispose");
}
private void DoWork(string json)
{
/*
1、反串行化报文转成对象
2、用提单号检索订单信息如果匹配不到订单信息需要生成待办任务。
3、入库费用并写入订单的应付费用表
*/
string msg = string.Empty;
try
{
var model = GetInfo(json, out msg);
_logger.LogInformation($"报文转换完成 GID={model.GID} BookingBill={model.BookingBill} 共【{model.DetailList.Count}】条");
//var tenantDb = saasService.GetBizJobDbScopeById(new JobDbInitConfig
//{
// UserId = 1819549542463442944,
// UserName = "东胜8测试",
// TenantId = 1819549542425694208,
// OrgId = 1819557001806614528
//});
var tenantDb = saasService.GetBizJobDbScopeExtById(new JobDbInitConfig
{
//UserId = long.Parse(AppSetting.app(new string[] { "FeeSettings", "UserId" })),
//UserName = AppSetting.app(new string[] { "FeeSettings", "UserName" }),
TenantId = long.Parse(AppSetting.app(new string[] { "FeeSettings", "TenantId" })),
//OrgId = long.Parse(AppSetting.app(new string[] { "FeeSettings", "OrgId" })),
});
_logger.LogInformation($"提取对应租户数据访问完成 GID={model.GID} BookingBill={model.BookingBill}");
string blno = model.BookingBill?.Trim();
_logger.LogInformation($"提取订单信息 GID={model.GID} BookingBill={model.BookingBill}");
var booking = tenantDb.Queryable<SeaExport>().ClearFilter(typeof(IOrgId)).First(a => a.MBLNO == blno && a.Deleted == false && (a.IsRefund == null || a.IsRefund.Value == false)
&& (a.IsChangeETD == null || a.IsChangeETD.Value == false));
var ctnList = tenantDb.Queryable<OpCtn>().ClearFilter(typeof(IOrgId)).Where(a => a.BSNO == booking.Id.ToString() && a.Deleted == false).ToList();
_logger.LogInformation($"提取订单完成 GID={model.GID} BookingBill={model.BookingBill} Order={JsonConvert.SerializeObject(booking)}");
if (booking != null)
{
DateTime etd = DateTime.MinValue;
if (booking.ETD.HasValue)
etd = booking.ETD.Value;
DateTime nowDate = DateTime.Now;
var custTypeDict = DS.Module.Core.EnumUtil.GetEnumDictionaryWithKey(typeof(CustomerTypeEnum));
var feeUnitDict = DS.Module.Core.EnumUtil.GetEnumDictionaryWithKey(typeof(FeeUnitEnum));
var codeCurrency = tenantDb.Queryable<FeeCurrency>().ToList();
long tenantId = long.Parse(AppSetting.app(new string[] { "FeeSettings", "TenantId" }));
var userInfo = db.Queryable<SysUser>().ClearFilter(typeof(ITenantId)).First(x => x.Id == booking.OperatorId && x.TenantId == tenantId);
List<string> errorMsgList = new List<string>();
int start = 1;
foreach (var fee in model.DetailList)
{
string qFee = fee.CustSysName?.Trim();
//if(string.IsNullOrWhiteSpace(qFee))
//{
// errorMsgList.Add("没有费用名称");
// continue;
//}
var feecode = tenantDb.Queryable<FeeCode>().First(x => x.Name == qFee);
if (feecode == null)
{
}
var newfee = new FeeRecord();
newfee.BusinessId = booking.Id;
newfee.FeeId = feecode.Id;
newfee.FeeName = feecode.Name;
newfee.FeeCode = feecode.Code;
newfee.TaxRate = feecode.TaxRate == null ? 0 : (decimal)feecode.TaxRate;
newfee.BusinessType = BusinessType.OceanShippingExport;
string custShortName = string.Empty;
string custType = string.Empty;
if (fee.CustSettleFor.IndexOf("#") >= 0)
{
var currArg = fee.CustSettleFor.Split(new char[] { '#' });
custShortName = currArg[0]?.Trim();
if (currArg.Length == 2)
{
custType = currArg.LastOrDefault().Trim();
}
}
else
{
custShortName = fee.CustSettleFor?.Trim();
}
var customerInfo = tenantDb.Queryable<InfoClient>().ClearFilter(typeof(ISharedOrgId)).First(x => x.ShortName == custShortName);
newfee.CustomerId = customerInfo.Id;
newfee.CustomerName = customerInfo.Description;
if (!string.IsNullOrWhiteSpace(custType))
{
var custTypeKey = custTypeDict.FirstOrDefault(x => x.Value == custType);
newfee.CustomerType = custTypeKey.Key;
newfee.CustomerTypeText = custTypeKey.Value;
}
newfee.FeeType = FeeType.Payable; //租箱月结明细.FeeType;
var feeUnitKey = feeUnitDict.FirstOrDefault(x => x.Value == fee.CustFeeStandard?.Trim());
newfee.Unit = feeUnitKey.Key;
newfee.UnitText = feeUnitKey.Value;
var currCurrCode = codeCurrency.First(a => a.CodeName == fee.CustCurrency);
newfee.Currency = currCurrCode.CodeName;
decimal qty = 0;
if (fee.CustFeeStandard.Equals("箱"))
{
var ctnSumList = ctnList.GroupBy(a => a.Ctn)
.Select(a => new { Key = a.Key, Code = a.ToList().FirstOrDefault().CtnCode, Num = a.Sum(b => b.CtnNum.HasValue ? b.CtnNum.Value : 1) }).ToList();
if (ctnSumList.Count == 1)
{
newfee.Unit = ctnSumList.FirstOrDefault().Code;
newfee.UnitText = ctnSumList.FirstOrDefault().Key;
}
if (!fee.Quantity.HasValue)
{
qty = ctnSumList.Sum(x => x.Num);
}
else
{
qty = fee.Quantity.Value;
}
}
else if (fee.CustFeeStandard.Equals("票"))
{
qty = 1;
}
if (!fee.UnitPrice.HasValue)
{
if (fee.Amount.HasValue)
{
var price = fee.Amount.Value / qty;
newfee.TaxUnitPrice = price;
}
else
{
newfee.TaxUnitPrice = 0;
}
}
else
{
newfee.TaxUnitPrice = fee.UnitPrice.Value;
}
if (newfee.Currency.Equals("RMB", StringComparison.OrdinalIgnoreCase) || newfee.Currency.Equals("CNY", StringComparison.OrdinalIgnoreCase))
{
newfee.ExchangeRate = 1;
}
else
{
if (etd != DateTime.MinValue)
{
var exchangeInfo = tenantDb.Queryable<FeeCurrencyExchange>().ClearFilter(typeof(IOrgId))
.First(x => x.CurrencyCode == newfee.Currency && x.OrgId == booking.OrgId
&& x.StartDate.Value <= etd && x.EndDate.Value >= etd && x.LocalCurrency == "RMB");
if(exchangeInfo == null)
{
exchangeInfo = tenantDb.Queryable<FeeCurrencyExchange>().ClearFilter(typeof(IOrgId))
.First(x => x.CurrencyCode == newfee.Currency && x.StartDate.Value <= etd && x.EndDate.Value >= etd && x.LocalCurrency == "RMB");
}
if (exchangeInfo != null)
{
newfee.ExchangeRate = exchangeInfo.CRValue;
}
}
}
newfee.Quantity = qty;
newfee.Amount = fee.Amount.HasValue ? fee.Amount.Value : 0;
newfee.CreateTime = nowDate;
newfee.CreateBy = userInfo.Id;
newfee.CreateUserName = userInfo.UserName;
newfee.UpdateTime = nowDate;
//2024-11-08 按照董怡含要求,先不要默认审批通过,暂时关闭
//newfee.FeeStatus = FeeStatus.AuditPassed;
newfee.Note = "大简云账单解析";
_logger.LogInformation($"写入账单开始 第【{start}】条 GID={model.GID} BookingBill={model.BookingBill} Order={JsonConvert.SerializeObject(newfee)}");
tenantDb.Insertable<FeeRecord>(newfee).ExecuteCommand();
_logger.LogInformation($"写入账单完成 第【{start}】条 GID={model.GID} BookingBill={model.BookingBill} Order={JsonConvert.SerializeObject(newfee)}");
//callbackList.Add()
start++;
}
}
List<SingleBillReceiveResult> callbackList = new List<SingleBillReceiveResult>();
//发送回执
//var jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(queryInfo, Formatting.Indented, new JsonSerializerSettings
//{
// NullValueHandling = NullValueHandling.Ignore
//});
//_logger.LogInformation($"请求MSK API查询船期请求{jsonBody}");
//var rlt = RequestHelper.Post(jsonBody, AppSetting.app(new string[] { "FeeSettings", "CallBackUrl" }));
////var rlt = await queryUrl.SetBody(jsonBody).PostAsStringAsync();
//_logger.LogInformation($"请求MSK API查询船期请求{jsonBody}");
}
catch (Exception ex)
{
_logger.LogInformation($"产生异常,原因:{ex.Message}");
}
}
private FeeBillReadDto GetInfo(string json,out string msg)
{
FeeBillReadDto model = null;
msg = string.Empty;
try
{
model = JsonConvert.DeserializeObject<FeeBillReadDto>(json);
}
catch(Exception ex)
{
msg = $"转换报文异常,原因:{ex.Message}";
}
return model;
}
}
}