AFR对接

master
zhangxiaofeng 11 months ago
parent cdd2dabcb0
commit 84326c754a

@ -116,6 +116,11 @@
ISF-bond使用费代码名称为“ISF-bond使用费”
</summary>
</member>
<member name="F:Common.Const.BusinessType.AFR_REPORT">
<summary>
AFR申报代码名称为“AFR申报”
</summary>
</member>
<member name="T:Common.Const.FlowInstanceStatus">
<summary>
流程状态

@ -19,5 +19,10 @@
/// ISF-bond使用费代码名称为“ISF-bond使用费”
/// </summary>
public const int ISF_BOUND = 26;
/// <summary>
/// AFR申报代码名称为“AFR申报”
/// </summary>
public const int AFR_REPORT = 999;
}
}

@ -25,6 +25,6 @@ namespace djy.IService.Afr
Task Delete(string ids);
Task<string> Send(string ids, string hids, int sendType);
Task SaveReceipt(AFRReceiptDto input);
Task<List<AFRMasterHistory>> GetHistory(string id);
Task<List<AFRMasterHistory>> GetHistory(string mid, string hid);
}
}

@ -53,9 +53,9 @@ namespace djy.Model.Afr
public bool StateIsMatched { get; set; }
/// <summary>
/// 最新状态内容
/// 最新通知
/// </summary>
public string StateContent { get; set; }
public string NewNotice { get; set; }
/// <summary>
/// 通知人地址

@ -145,7 +145,7 @@ namespace djy.Model.Afr
/// <summary>
/// 操作历史
/// </summary>
[Navigate(nameof(AFRMasterHistory.PID))]
[Navigate(nameof(AFRMasterHistory.MID))]
public AFRMasterHistory History { get; set; }
#endregion

@ -20,9 +20,13 @@ namespace djy.Model.Afr
public string Operator { get; set; }
/// <summary>
///
/// Master表主键
/// </summary>
public string MID { get; set; }
/// <summary>
/// House表主键
/// </summary>
public string PID { get; set; }
public string HID { get; set; }
/// <summary>
///

@ -1,4 +1,6 @@
using Common;
using AutoMapper;
using Common;
using Common.Const;
using Common.DJYModel;
using Common.Extensions;
using Common.Tools;
@ -17,14 +19,17 @@ using NETCore.Encrypt.Internal;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Ocsp;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using static NPOI.HSSF.Util.HSSFColor;
namespace djy.Service.AFR
{
@ -262,7 +267,7 @@ namespace djy.Service.AFR
.ToListAsync();
histories.ForEach(item =>
{
var master = result.FirstOrDefault(m => m.GID == item.PID);
var master = result.FirstOrDefault(m => m.GID == item.MID);
if (master == null) return;
master.History = item;
});
@ -334,8 +339,7 @@ namespace djy.Service.AFR
await DbAMS.Insert(input.HouseList).WithTransaction(tran).ExecuteAffrowsAsync();
await DbAMS.Insert(input.HouseList.SelectMany(h => h.CntrList)).WithTransaction(tran).ExecuteAffrowsAsync();
AFRMasterHistory history = BuildAFRMasterHistory(input.GID, "新增", 0, "创建了单据");
await DbAMS.Insert(history).WithTransaction(tran).ExecuteAffrowsAsync();
await BuildAFRMasterHistoryAsync(input.GID, input.HouseList.Select(h => h.GID), "新增", 0, "创建了单据", tran);
tran.Commit();
}
@ -448,6 +452,8 @@ namespace djy.Service.AFR
if (waitInsertHouseGids.Any())
{
await DbAMS.Insert(waitInsertHouseList).WithTransaction(tran).ExecuteAffrowsAsync();
await BuildAFRMasterHistoryAsync(input.GID, waitInsertHouseGids, "新增", 0, "新增了单据", tran);
}
if (waitDeleteHouseGids.Any())
{
@ -457,14 +463,18 @@ namespace djy.Service.AFR
.WithTransaction(tran)
.Where(h => waitDeleteHouseGids.Contains(h.GID))
.ExecuteAffrowsAsync();
await BuildAFRMasterHistoryAsync(input.GID, waitDeleteHouseGids, "删除", 0, "删除了单据", tran);
}
if (waitUpdateHouseGids.Any())
{
await DbAMS.Update<AFRHouse>()
.SetSource(waitUpdateHouseList)
.IgnoreColumns(h => new { h.StateIsMatched, h.StateIsAccept })
.IgnoreColumns(h => new { h.StateIsMatched, h.StateIsAccept, h.StateIsSend, h.NewNotice })
.WithTransaction(tran)
.ExecuteAffrowsAsync();
await BuildAFRMasterHistoryAsync(input.GID, waitUpdateHouseGids, "修改", 0, "修改了单据", tran);
}
// 箱子执行
@ -488,28 +498,38 @@ namespace djy.Service.AFR
}
#endregion
AFRMasterHistory history = BuildAFRMasterHistory(input.GID, "修改", 0, "修改了单据");
await DbAMS.Insert(history).WithTransaction(tran).ExecuteAffrowsAsync();
tran.Commit();
}
return await Get(input.GID);
}
private AFRMasterHistory BuildAFRMasterHistory(string pid, string state, int type, string remark)
private async Task BuildAFRMasterHistoryAsync(string mid, IEnumerable<string> hids, string state, int type, string remark, DbTransaction tran = null)
{
List<AFRMasterHistory> list = new(hids.Count());
foreach (string hid in hids)
{
var history = new AFRMasterHistory()
{
GID = Guid.NewGuid().ToString(),
CreateTime = DateTime.Now,
Operator = User.ShowName,
PID = pid,
MID = mid,
HID = hid,
State = state,
Type = Convert.ToByte(type)
};
history.Remark = $"{history.Operator}于{(DateTime)history.CreateTime:yyyy-MM-dd HH:mm:ss}{remark}";
return history;
list.Add(history);
}
if (tran == null)
{
await DbAMS.Insert(list).ExecuteAffrowsAsync();
}
else
{
await DbAMS.Insert(list).WithTransaction(tran).ExecuteAffrowsAsync();
}
}
public async Task Delete(string ids)
@ -545,7 +565,7 @@ namespace djy.Service.AFR
public async Task<string> Send(string ids, string hids, int sendType)
{
//return "发送成功";
#region 查询电子口岸的请求参数
var paramSets = await DbBus.Get(DbList.djydb).Select<ParamSet>().Where(x => x.PARAMNAME == "AFRURL" || x.PARAMNAME == "AFRAccount" || x.PARAMNAME == "AFRKey").ToListAsync(p => new
{
@ -582,7 +602,7 @@ namespace djy.Service.AFR
var houseGids = houseAll.Select(h => h.GID);
cntrAll = await DbAMS.Select<AFRCntrno>().Where(c => houseGids.Contains(c.PID)).ToListAsync();
}
else if (sendType is 2 or 3)
else if (sendType is 2 or 3 or 4)
{
if (string.IsNullOrEmpty(hids))
{
@ -602,20 +622,20 @@ namespace djy.Service.AFR
var housePids = houseAll.Select(h => h.PID);
masterAll = await DbAMS.Select<AFRMaster>().Where(m => m.IsDel == false && housePids.Contains(m.GID)).ToListAsync();
}
else if (sendType is 4)
{
if (string.IsNullOrEmpty(hids))
{
throw new ArgumentNullException(nameof(hids));
}
var hidArr = hids.Split(',');
//else if (sendType is 4)
//{
// if (string.IsNullOrEmpty(hids))
// {
// throw new ArgumentNullException(nameof(hids));
// }
// var hidArr = hids.Split(',');
houseAll = await DbAMS.Select<AFRHouse>().Where(h => h.IsDel == false && hidArr.Contains(h.GID)).ToListAsync();
if (houseAll.Count != hidArr.Length)
{
throw new Exception("所选记录有些已被删除,请刷新页面后重试");
}
}
// houseAll = await DbAMS.Select<AFRHouse>().Where(h => h.IsDel == false && hidArr.Contains(h.GID)).ToListAsync();
// if (houseAll.Count != hidArr.Length)
// {
// throw new Exception("所选记录有些已被删除,请刷新页面后重试");
// }
//}
#endregion
StringBuilder messageBuilder = new();
@ -630,13 +650,39 @@ namespace djy.Service.AFR
try
{
#region 发送前的参数验证
#region 发送前的各项校验
// 判断是否有分单数据
houseList = houseAll.Where(h => h.PID == masterItem.GID).ToList() ?? throw new Exception("分单为空");
// 验证接口要求
if (masterItem.FilingType == "Tranship" && (string.IsNullOrWhiteSpace(masterItem.LastForeignHarbourCode) || string.IsNullOrWhiteSpace(masterItem.LastForeignHarbour)))
{
throw new Exception("当【申报运输类型】为【Tranship】时【交货地全称】与【交货地五字码】为必填项");
}
// 验证账户余额是否充足
var fin = new FinanceService();
var getfinrs = fin.CheckBalance(new CustFee
{
CARRIER = masterItem.ShipCompanyCode,
//ETD = null,
//VOYNO = masterItem.Voyno,
//VESSEL = masterItem.Vessel,
//HBLNO = item.HBLNo,
//SENDUSERID = user.GID,
LURURENID = User.GID,
//CtnrCount = ,
//CtnrInfo = string.Empty,
BSTYPE = BusinessType.AFR_REPORT,
SENDTYPE = sendType switch { 1 or 2 => 0, 3 => 1, _ => throw new NotImplementedException() },
//BSNO = oid.ToString(),
//MBLNO = master.MBLNO.ToString(),
}, houseList.Count);
if (!getfinrs.Status)
{
throw new Exception(getfinrs.Message);
}
#endregion
AFRRequestDto requestDto = new AFRRequestDto()
@ -765,6 +811,47 @@ namespace djy.Service.AFR
{
string tip = $"发送成功!船东提单号:【{masterItem.MBLNO}】货代提单号:【{string.Join("", houseList.Select(h => h.HouseBillNo))}】{Environment.NewLine}";
messageBuilder.Append(tip);
#region 扣费、保存状态
foreach (AFRHouse dealHouseItem in houseList)
{
try
{
var expendResult = fin.Expend(new CustFee
{
CARRIER = masterItem.ShipCompanyCode,
ETD = null,
VOYNO = masterItem.Voyno,
VESSEL = masterItem.Vessel,
HBLNO = dealHouseItem.HouseBillNo,
SENDUSERID = User.GID,
LURURENID = User.GID,
CtnrCount = dealHouseItem.CntrList?.Count ?? 0,
CtnrInfo = string.Empty,
BSTYPE = BusinessType.AFR_REPORT,
SENDTYPE = sendType switch { 1 or 2 => 0, 3 => 1, _ => -1 },
BSNO = masterItem.GID,
MBLNO = masterItem.MBLNO,
}, 1);
if (!expendResult.Status)
{
logger.LogError($"执行扣费失败,{logGuid},异常信息:{expendResult.Message}");
}
}
catch (Exception ex)
{
logger.LogError($"执行扣费时发生未知异常,{logGuid},异常信息:{ex.Message}");
}
// 保存状态
}
// 记录历史
var state = sendType switch { 1 => "新增发送成功", 2 => "重发成功", 3 => "修改发送成功", _ => "" };
await BuildAFRMasterHistoryAsync(masterItem.GID, houseList.Select(h => h.GID), state, 0, "发送了单据");
#endregion
}
else
{
@ -778,6 +865,13 @@ namespace djy.Service.AFR
}
catch (Exception ex)
{
// 记录历史
var state = sendType switch { 1 => "新增发送失败", 2 => "重发失败", 3 => "修改发送失败", _ => "" };
await BuildAFRMasterHistoryAsync(masterItem.GID, houseList.Select(h => h.GID), state, 0, $"发送单据失败,失败原因:{ex.Message}");
// 保存状态
// 构建响应
string tip;
if (houseList == null)
{
@ -788,6 +882,8 @@ namespace djy.Service.AFR
tip = $"发送失败!船东提单号:【{masterItem.MBLNO}】货代提单号:【{string.Join("", houseList.Select(h => h.HouseBillNo))}】,原因:{ex.Message}{Environment.NewLine}";
}
messageBuilder.Append(tip);
// 继续处理下一单
continue;
}
}
@ -797,6 +893,22 @@ namespace djy.Service.AFR
{
try
{
#region 发送前的各项校验
// 验证账户余额是否充足
var fin = new FinanceService();
var getfinrs = fin.CheckBalance(new CustFee
{
LURURENID = User.GID,
BSTYPE = BusinessType.AFR_REPORT,
SENDTYPE = 5,
}, houseAll.Count);
if (!getfinrs.Status)
{
throw new Exception(getfinrs.Message);
}
#endregion
string hbnos = string.Join(',', houseAll.Select(h => h.HouseBillNo));
var businessParam = new Dictionary<string, string>()
{
@ -813,45 +925,88 @@ namespace djy.Service.AFR
logger.LogInformation($"请求宁波电子口岸API{logGuid},响应:{response}");
//JObject rlt = JObject.Parse(response);
//var code = rlt.GetValue("code")?.ToString();
//var msg = rlt.GetValue("msg")?.ToString();
//if (code == "T")
//{
// var data = rlt["data"] as JObject;
JObject rlt = JObject.Parse(response);
var code = rlt.GetValue("code")?.ToString();
var msg = rlt.GetValue("msg")?.ToString();
if (code == "T")
{
var data = rlt["data"] as JObject;
// var code2 = data.GetValue("code")?.ToString();
// var msg2 = data.GetValue("msg")?.ToString();
// var data2 = data.GetValue("data")?.ToString();
var code2 = data.GetValue("code")?.ToString();
var msg2 = data.GetValue("msg")?.ToString();
var data2 = data.GetValue("data")?.ToString();
// if (code2 == "1")
// {
// string tip = $"发送成功!船东提单号:【{masterItem.MBLNO}】货代提单号:【{string.Join("、", houseList.Select(h => h.HouseBillNo))}】{Environment.NewLine}";
// messageBuilder.Append(tip);
// }
// else
// {
// throw new Exception($"电子口岸接口返回失败结果(code:{code2},msg:{msg})");
// }
//}
//else
//{
// throw new Exception($"电子口岸接口调用失败(msg:{msg})");
//}
if (code2 == "1")
{
string tip = $"发送成功!货代提单号:【{string.Join("", houseAll.Select(h => h.HouseBillNo))}】{Environment.NewLine}";
messageBuilder.Append(tip);
#region 扣费、记录历史、保存状态
foreach (AFRHouse expendHouseItem in houseAll)
{
AFRMaster expendMasterItem = masterAll.First(m => m.GID == expendHouseItem.PID);
// 扣费
try
{
var expendResult = fin.Expend(new CustFee
{
CARRIER = expendMasterItem.ShipCompanyCode,
ETD = null,
VOYNO = expendMasterItem.Voyno,
VESSEL = expendMasterItem.Vessel,
HBLNO = expendHouseItem.HouseBillNo,
SENDUSERID = User.GID,
LURURENID = User.GID,
CtnrCount = cntrAll.Count(c => c.PID == expendHouseItem.GID),
CtnrInfo = string.Empty,
BSTYPE = BusinessType.AFR_REPORT,
SENDTYPE = 5,
BSNO = expendMasterItem.GID,
MBLNO = expendMasterItem.MBLNO,
}, 1);
if (!expendResult.Status)
{
logger.LogError($"执行扣费失败,{logGuid},异常信息:{expendResult.Message}");
}
}
catch (Exception ex)
{
//string tip;
//if (houseList == null)
//{
// tip = $"发送失败!船东提单号:【{masterItem.MBLNO}】,原因:{ex.Message}{Environment.NewLine}";
//}
//else
//{
// tip = $"发送失败!船东提单号:【{masterItem.MBLNO}】货代提单号:【{string.Join("、", houseList.Select(h => h.HouseBillNo))}】,原因:{ex.Message}{Environment.NewLine}";
//}
//messageBuilder.Append(tip);
//continue;
logger.LogError($"执行扣费时发生未知异常,{logGuid},异常信息:{ex.Message}");
continue;
}
// 记录历史
await BuildAFRMasterHistoryAsync(expendMasterItem.GID, new string[] { expendHouseItem.GID }, "删除发送成功", 0, "删除发送了单据");
// 保存状态
}
#endregion
}
else
{
throw new Exception($"电子口岸接口返回失败结果(code:{code2},msg:{msg})");
}
}
else
{
throw new Exception($"电子口岸接口调用失败(msg:{msg})");
}
}
catch (Exception ex)
{
// 构建响应
string tip = $"发送失败!货代提单号:【{string.Join("", houseAll.Select(h => h.HouseBillNo))}】,原因:{ex.Message}";
messageBuilder.Append(tip);
// 记录历史
houseAll.ForEach(async h =>
{
await BuildAFRMasterHistoryAsync(h.PID, new string[] { h.GID }, "删除发送失败", 0, $"删除发送单据失败,原因:{ex.Message}");
});
// 保存状态
}
}
#endregion
@ -928,10 +1083,11 @@ namespace djy.Service.AFR
throw new NotImplementedException();
}
public async Task<List<AFRMasterHistory>> GetHistory(string id)
public async Task<List<AFRMasterHistory>> GetHistory(string mid, string hid)
{
var data = await DbAMS.Select<AFRMasterHistory>()
.Where(h => h.PID == id)
.WhereIf(!string.IsNullOrEmpty(mid), h => h.MID == mid)
.WhereIf(!string.IsNullOrEmpty(hid), h => h.HID == hid)
.ToListAsync();
return data;
}

@ -20,7 +20,7 @@ namespace djy.Service.DjyService
///
/// </summary>
/// <param name="Dto"></param>
/// <param name="exptype">1验证是否可以扣款 2扣除操作 </param>
/// <param name="exptype">1扣除操作 其他验证是否可以扣款</param>
/// <param name="bondOwnType">bond是否自有值是1或者21表示“自有BOND”2表示“使用CargoEDI的BOND”当值为2时需要额外扣除ISF-Bond使用费</param>
/// <returns></returns>
public ReturnResult<object> Expend(CustFee Dto, int exptype, BondOwnTypeEnum? bondOwnType = null)
@ -216,5 +216,72 @@ namespace djy.Service.DjyService
return rs;
}
/// <summary>
/// 验证余额是否充足
/// <paramref name="times">验证的计费次数</paramref>
/// </summary>
public ReturnResult<object> CheckBalance(CustFee Dto, int times)
{
_LogsAdd("Expend 验证余额是否充足", "open", Dto);
var rs = new ReturnResult<object>();
try
{
if (Dto == null)
{
rs.Not("错误的null请求");
return rs;
}
if (Dto.BSTYPE == null || Dto.SENDTYPE == null)
{
rs.Not("请求的业务类型和发送类型不能为空!");
return rs;
}
if (Dto.LURURENID.IsNotNull())
{
var luser = DbBus.Get(DbList.djydb).Select<User>().Where(w => w.GID == Dto.LURURENID).ToOne();
if (luser != null)
{
Dto.LURUREN = luser.SHOWNAME;
Dto.LURURENID = luser.GID;
Dto.COMNAME = luser.COMNAME;
Dto.COMID = luser.CompId;
}
}
decimal price_total = 0; // 总金额
// 获取 计费规则
CustPrice cp1 = DbBus.Get(DbList.djydb).Select<CustPrice>().Where(w => w.BSTYPE == Dto.BSTYPE && w.SENDTYPE == Dto.SENDTYPE && w.COMID == Dto.COMID).ToOne();
if (cp1 == null)
{
rs.Not("没有找到此业务的计费规则!");
return rs;
}
price_total = ((decimal)cp1.PRICE) * times;
var PayInfo = new { Total = price_total, Price = price_total, Count = Dto.CtnrCount };
if (DbBus.Get(DbList.djydb).Select<CustBalance>().Where(a => a.Balance >= price_total && a.COMNAME == Dto.COMNAME).Count() > 0)
{
rs.Data = new { PayInfo };
rs.OK("钱包金额充足");
}
else
{
rs.Data = new { PayInfo };
rs.Not("钱包金额不足");
}
}
catch (Exception ex)
{
rs.Not(ex.Message);
}
return rs;
}
}
}

@ -126,12 +126,13 @@ namespace djy_AfrApi.Controllers
/// <summary>
/// 获取历史记录
/// </summary>
/// <param name="id">主键</param>
/// <param name="mid">主单主键</param>
/// <param name="hid">分单主键</param>
/// <returns>历史记录列表</returns>
[HttpGet("GetHistory")]
public async Task<Response<List<AFRMasterHistory>>> GetHistory(string id)
public async Task<Response<List<AFRMasterHistory>>> GetHistory([Required] string mid, string hid)
{
var data = await _afrService.GetHistory(id);
var data = await _afrService.GetHistory(mid, hid);
return SuccessResp(data);
}

@ -6,7 +6,7 @@
<Project>
<PropertyGroup>
<_PublishTargetUrl>D:\DJY\Code\djyweb_ams\web\djy_AfrApi\bin\Release\net5.0\publish-windows\</_PublishTargetUrl>
<History>True|2024-01-03T08:04:13.6208067Z;True|2024-01-03T15:07:08.9376581+08:00;True|2024-01-02T10:57:59.7067270+08:00;True|2024-01-02T10:28:44.8223638+08:00;True|2023-12-29T17:26:12.9612280+08:00;</History>
<History>True|2024-01-03T13:54:40.3579096Z;True|2024-01-03T21:52:09.6604718+08:00;True|2024-01-03T16:04:13.6208067+08:00;True|2024-01-03T15:07:08.9376581+08:00;True|2024-01-02T10:57:59.7067270+08:00;True|2024-01-02T10:28:44.8223638+08:00;True|2023-12-29T17:26:12.9612280+08:00;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>
Loading…
Cancel
Save