|
|
using Common;
|
|
|
using Common.Const;
|
|
|
using Common.DJYModel;
|
|
|
using Common.Extensions;
|
|
|
using Common.Helpers;
|
|
|
using Common.Tools;
|
|
|
using Common.Utilities;
|
|
|
using djy.IService.Afr;
|
|
|
using djy.Model;
|
|
|
using djy.Model.Afr;
|
|
|
using djy.Model.AFRDto;
|
|
|
using djy.Model.Ams;
|
|
|
using djy.Model.AmsDto;
|
|
|
using djy.Model.Converter;
|
|
|
using djy.Service.DjyService;
|
|
|
using FreeSql;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Newtonsoft.Json;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Data.Common;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
namespace djy.Service.AFR
|
|
|
{
|
|
|
public class AfrService : DjyService.DbContext, IAfrService
|
|
|
{
|
|
|
private readonly ILogger<AfrService> logger;
|
|
|
|
|
|
private IUser User { get; }
|
|
|
|
|
|
public AfrService(IUser user, ILogger<AfrService> logger)
|
|
|
{
|
|
|
User = user;
|
|
|
this.logger = logger;
|
|
|
}
|
|
|
#region 下拉接口
|
|
|
public List<CommonCNEN> GetCountry(string strlink, int page, int limit)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (page == 0 && limit == 0)
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodeCountry>().ToList().Select(x => new CommonCNEN
|
|
|
{
|
|
|
Code = x.Code,
|
|
|
ENName = x.EnName,
|
|
|
CNName = x.CnName,
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodeCountry>().WhereIf(strlink != "", x => x.Code.Contains(strlink.Trim()) || x.EnName.Contains(strlink.Trim()) || x.CnName.Contains(strlink.Trim())).Page(page, limit).ToList().Select(x => new CommonCNEN
|
|
|
{
|
|
|
Code = x.Code,
|
|
|
ENName = x.EnName,
|
|
|
CNName = x.CnName,
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
throw;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public List<CommonMappiCode> GetCARRIER()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodeCarrier, MappingCarrier>().InnerJoin((cc, map) => cc.Code == map.Code && map.Module == "AFR").ToList((cc, map) => new CommonMappiCode
|
|
|
{
|
|
|
Code = cc.Code,
|
|
|
Value = cc.EnName,
|
|
|
MapCode = map.MapCode
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
throw;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public List<CommonMappiCode> GetCTNALL()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodeCtn, MappingCtn>().InnerJoin((cc, map) => cc.Code == map.Code && map.Module == "AFR").ToList((cc, map) => new CommonMappiCode
|
|
|
{
|
|
|
Code = cc.Code,
|
|
|
Value = cc.Name,
|
|
|
MapCode = map.MapCode
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
throw;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public List<CommonMappiCode> GetPackage()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodePackage, MappingPackage>().InnerJoin((cc, map) => cc.Code == map.Code && map.Module == "AFR").ToList((cc, map) => new CommonMappiCode
|
|
|
{
|
|
|
Code = cc.Code,
|
|
|
Value = cc.Name,
|
|
|
MapCode = map.MapCode,
|
|
|
MapName = map.MapName
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
throw;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public List<CodeDangerGradeDto> GetDangerousGoods(string strlink)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodeDangerGrade>().WhereIf(strlink != "", x => x.Code.Contains(strlink.Trim()) || x.Grade.Contains(strlink.Trim())).ToList().Select(x => new CodeDangerGradeDto
|
|
|
{
|
|
|
Code = x.Code,
|
|
|
Grade = x.Grade,
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
throw;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public List<CommonMappiCode> GetPort(string strlink, int page, int limit)
|
|
|
{
|
|
|
//try
|
|
|
//{
|
|
|
//if (page == 0 && limit == 0)
|
|
|
//{
|
|
|
var List = DbBus.Get(DbList.Common)
|
|
|
.Select<CodePort, MappingPort>()
|
|
|
.InnerJoin((cp, mp) => cp.Code == mp.Code)
|
|
|
.Where((cp, mp) => mp.Module == "AFR")
|
|
|
.ToList((cp, mp) => new CommonMappiCode
|
|
|
{
|
|
|
//Code = cp.Code,
|
|
|
//Value = cp.EnName,
|
|
|
Code = null,
|
|
|
Value = null,
|
|
|
MapCode = mp.MapCode,
|
|
|
MapName = mp.MapName
|
|
|
});
|
|
|
return List;
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
// var List = DbBus.Get(DbList.Common).Select<CodePort>().WhereIf(strlink != "", x => x.Code.Contains(strlink.Trim()) || x.EnName.Contains(strlink.Trim())).Page(page, limit).ToList().Select(x => new CommonCodeValue
|
|
|
// {
|
|
|
// Code = x.Code,
|
|
|
// Value = x.EnName,
|
|
|
// }).Distinct().ToList();
|
|
|
// return List;
|
|
|
//}
|
|
|
//}
|
|
|
//catch (Exception e)
|
|
|
//{
|
|
|
// throw;
|
|
|
//}
|
|
|
}
|
|
|
|
|
|
public List<CommonCodeValue> GetVessel(string strlink, int page, int limit)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (page == 0 && limit == 0)
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodeVessel>().WhereIf(strlink != "", x => x.Name.Contains(strlink.Trim())).ToList().Select(x => new CommonCodeValue
|
|
|
{
|
|
|
Code = x.Name,
|
|
|
Value = x.Name,
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var List = DbBus.Get(DbList.Common).Select<CodeVessel>().WhereIf(strlink != "", x => x.Name.Contains(strlink.Trim())).Page(page, limit).ToList().Select(x => new CommonCodeValue
|
|
|
{
|
|
|
Code = x.Name,
|
|
|
Value = x.Name,
|
|
|
}).Distinct().ToList();
|
|
|
return List;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
throw;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
public async Task<PageModel<AFRMaster>> Load(AFRMasterInputDto input)
|
|
|
{
|
|
|
List<AFRMaster> result = null;
|
|
|
if (input.Type == 1)
|
|
|
{
|
|
|
ISelect<AFRMaster> select = DbAMS.Select<AFRMaster>();
|
|
|
|
|
|
select.Where((m) => m.IsDel == false && m.StateIsSend == false)
|
|
|
//下面两个是Controller中传来的条件
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.CompanyId), (m) => m.CompID == input.CompanyId)
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.UserId), (m) => m.UserID == input.UserId)
|
|
|
// 下面是前端传来的条件
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.MBLNO), (m) => m.MBLNO.Contains(input.MBLNO))
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.UserName), (m) => m.LastUpdateUserName.Contains(input.UserName))
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.DischargeHarbour), (m) => m.DischargeHarbourCode.Contains(input.DischargeHarbour))
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.ShipCompanyName), (m) => m.ShipCompanyName.Contains(input.ShipCompanyName))
|
|
|
.WhereIf(input.CreateTimeStart != null, (m) => m.CreateTime >= input.CreateTimeStart)
|
|
|
.WhereIf(input.CreateTimeEnd != null, (m) => m.CreateTime <= input.CreateTimeEnd);
|
|
|
|
|
|
// 分单上的查询条件在这里,实现方式:查出分单中的PID,作为主单的筛选条件
|
|
|
if (!string.IsNullOrEmpty(input.HouseBillNo))
|
|
|
{
|
|
|
var pids = await DbAMS.Select<AFRHouse>()
|
|
|
.Where(h => h.HouseBillNo.Contains(input.HouseBillNo))
|
|
|
.ToListAsync(h => h.PID);
|
|
|
select.Where((m) => pids.Contains(m.GID));
|
|
|
}
|
|
|
|
|
|
result = await select.IncludeMany(m => m.HouseList, then => then.Where(h => h.IsDel == false))
|
|
|
.Page(input)
|
|
|
.OrderByDescending(m => m.CreateTime)
|
|
|
.ToListAsync();
|
|
|
}
|
|
|
else if (input.Type == 2)
|
|
|
{
|
|
|
var select = DbAMS.Select<AFRMaster, AFRHouse>()
|
|
|
.InnerJoin<AFRHouse>((m, h) => m.GID == h.PID);
|
|
|
|
|
|
select.Where((m, h) => m.IsDel == false && h.IsDel == false && m.StateIsSend == true)
|
|
|
//下面两个是Controller中传来的条件
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.CompanyId), (m, h) => m.CompID == input.CompanyId)
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.UserId), (m, h) => m.UserID == input.UserId)
|
|
|
// 下面是前端传来的条件
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.MBLNO), (m, h) => m.MBLNO.Contains(input.MBLNO))
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.UserName), (m, h) => h.LastUpdateUserName.Contains(input.UserName))
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.DischargeHarbour), (m, h) => m.DischargeHarbour.Contains(input.DischargeHarbour))
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.ShipCompanyName), (m, h) => m.ShipCompanyName.Contains(input.ShipCompanyName))
|
|
|
.WhereIf(input.CreateTimeStart != null, (m, h) => m.CreateTime >= input.CreateTimeStart)
|
|
|
.WhereIf(input.CreateTimeEnd != null, (m, h) => m.CreateTime <= input.CreateTimeEnd)
|
|
|
.WhereIf(!string.IsNullOrEmpty(input.HouseBillNo), (m, h) => h.HouseBillNo.Contains(input.HouseBillNo));
|
|
|
|
|
|
var dtoList = await select.Page(input)
|
|
|
.OrderByDescending((m, h) => m.CreateTime)
|
|
|
.ToListAsync((m, h) => new { AFRMaster = m, AFRHouse = h });
|
|
|
|
|
|
|
|
|
result = new List<AFRMaster>();
|
|
|
dtoList.ForEach(d =>
|
|
|
{
|
|
|
d.AFRMaster.HouseList = new List<AFRHouse>() { d.AFRHouse };
|
|
|
result.Add(d.AFRMaster);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 查询操作历史(只查询最新的一条人为操作历史)
|
|
|
if (result.Count > 0)
|
|
|
{
|
|
|
// FreeSql版本较低,无法使用嵌套查询,所以采用拼sql的方式
|
|
|
if (input.Type == 1)
|
|
|
{
|
|
|
var pids = result.Select(m => m.GID);
|
|
|
var pidStr = string.Join("','", pids);
|
|
|
List<AFRMasterHistory> histories = await DbAMS.Select<AFRMasterHistory>()
|
|
|
.WithSql(@$"SELECT * FROM (
|
|
|
SELECT *,row_number() over ( PARTITION BY PID ORDER BY CreateTime DESC ) AS row_num FROM AFR_MasterHistory WHERE Type = 0 and PID IN ('{pidStr}')) t WHERE row_num =1")
|
|
|
.ToListAsync();
|
|
|
|
|
|
result.ForEach(master =>
|
|
|
{
|
|
|
master.History = histories.FirstOrDefault(h => h.PID == master.GID);
|
|
|
});
|
|
|
}
|
|
|
else if (input.Type == 2)
|
|
|
{
|
|
|
var pids = result.SelectMany(m => m.HouseList).Select(h => h.GID);
|
|
|
if (pids.Any())
|
|
|
{
|
|
|
var pidStr = string.Join("','", pids);
|
|
|
|
|
|
List<AFRMasterHistory> histories = await DbAMS.Select<AFRMasterHistory>()
|
|
|
.WithSql(@$"SELECT * FROM (
|
|
|
SELECT *,row_number() over ( PARTITION BY HID ORDER BY CreateTime DESC ) AS row_num FROM AFR_MasterHistory WHERE Type = 0 and HID IN ('{pidStr}')) t WHERE row_num =1")
|
|
|
.ToListAsync();
|
|
|
|
|
|
result.ForEach(master =>
|
|
|
{
|
|
|
if (master.HouseList?.Any() ?? false)
|
|
|
{
|
|
|
master.History = histories.FirstOrDefault(h => h.HID == master.HouseList[0].GID);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
return new PageModel<AFRMaster>(input.PageNumber,
|
|
|
input.Count,
|
|
|
input.PageSize,
|
|
|
result);
|
|
|
}
|
|
|
public async Task<AFRMaster> Get(string gid)
|
|
|
{
|
|
|
AFRMaster model = await DbAMS.Select<AFRMaster>()
|
|
|
.Where((m) => m.IsDel == false && m.GID == gid)
|
|
|
.IncludeMany(m => m.HouseList, then => then.Where(h => h.IsDel == false)
|
|
|
.IncludeMany(house => house.CntrList))
|
|
|
.FirstAsync();
|
|
|
return model;
|
|
|
}
|
|
|
|
|
|
public async Task<AFRMaster> SaveInfo(AFRMaster input)
|
|
|
{
|
|
|
int type;
|
|
|
AFRMaster oldMaster = null;
|
|
|
var nowTime = DateTime.Now;
|
|
|
|
|
|
StringTrimmer.TrimStringProperties(input);
|
|
|
|
|
|
#region 数据校验
|
|
|
if (string.IsNullOrWhiteSpace(input.MBLNO))
|
|
|
{
|
|
|
throw new Exception($"船东提单号不能为空");
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
if (string.IsNullOrEmpty(input.GID))
|
|
|
{
|
|
|
type = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
oldMaster = await Get(input.GID);
|
|
|
type = oldMaster == null ? 0 : 1;
|
|
|
}
|
|
|
input.LastUpdate = nowTime;
|
|
|
input.LastUpdateUserID = User.GID;
|
|
|
input.LastUpdateUserName = User.ShowName;
|
|
|
// 新增
|
|
|
if (type == 0)
|
|
|
{
|
|
|
// 将null换为空对象,避免后续处理null值麻烦
|
|
|
input.HouseList ??= new List<AFRHouse>();
|
|
|
|
|
|
input.GID = Guid.NewGuid().ToString();
|
|
|
input.UserID = User.GID;
|
|
|
input.UserName = User.ShowName;
|
|
|
input.CompID = User.CompId;
|
|
|
input.CompName = User.CompName;
|
|
|
input.CreateTime = nowTime;
|
|
|
input.StateIsSend = false;
|
|
|
|
|
|
//if (await DbAMS.Select<AFRMaster>().AnyAsync(m => m.MBLNO == input.MBLNO && m.IsDel == false))
|
|
|
//{
|
|
|
// throw new Exception("已存在相同的船东提单号");
|
|
|
//}
|
|
|
|
|
|
var hblNoList = input.HouseList.Select(h => h.HouseBillNo.Trim()).ToList();
|
|
|
if (hblNoList.Any(h => string.IsNullOrWhiteSpace(h)))
|
|
|
{
|
|
|
throw new Exception("货代提单号不能为空");
|
|
|
}
|
|
|
if (hblNoList.Any() && await DbAMS.Select<AFRHouse>().AnyAsync(h => hblNoList.Contains(h.HouseBillNo) && h.IsDel == false))
|
|
|
{
|
|
|
throw new Exception("已存在相同的货代提单号");
|
|
|
}
|
|
|
|
|
|
input.HouseList.ForEach(house =>
|
|
|
{
|
|
|
StringTrimmer.TrimStringProperties(house);
|
|
|
|
|
|
house.GID = Guid.NewGuid().ToString();
|
|
|
house.PID = input.GID;
|
|
|
house.LastUpdateUserID = User.GID;
|
|
|
house.LastUpdateUserName = User.ShowName;
|
|
|
house.CreateTime = nowTime;
|
|
|
house.LastUpdate = nowTime;
|
|
|
house.MBLNO = input.MBLNO;
|
|
|
house.StateIsAccept = house.StateIsMatched = house.StateIsSend = house.StateIsDelete = false;
|
|
|
house.NewNotice = "";
|
|
|
|
|
|
// 将null换为空对象,避免后续处理null值麻烦
|
|
|
house.CntrList ??= new List<AFRCntrno>();
|
|
|
house.CntrList.ForEach(cntr =>
|
|
|
{
|
|
|
StringTrimmer.TrimStringProperties(cntr);
|
|
|
|
|
|
cntr.GID = Guid.NewGuid().ToString();
|
|
|
cntr.PID = house.GID;
|
|
|
cntr.CreateTime = nowTime;
|
|
|
cntr.LastUpdate = nowTime;
|
|
|
cntr.HouseBillNo = house.HouseBillNo;
|
|
|
});
|
|
|
});
|
|
|
|
|
|
await using DbTransaction tran = await GetDbAmsTransaction();
|
|
|
|
|
|
await DbAMS.Insert(input)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
await DbAMS.Insert(input.HouseList)
|
|
|
.WithTransaction(tran)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
await DbAMS.Insert(input.HouseList.SelectMany(h => h.CntrList))
|
|
|
.WithTransaction(tran)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
await SaveHistoryAsync(input.GID, input.HouseList, "新增", 0, "创建了单据", null, tran);
|
|
|
|
|
|
tran.Commit();
|
|
|
}
|
|
|
// 修改
|
|
|
else
|
|
|
{
|
|
|
if (await DbAMS.Select<AFRMaster>().AnyAsync(m => m.MBLNO == input.MBLNO && m.GID != input.GID && m.IsDel == false))
|
|
|
{
|
|
|
throw new Exception("已存在相同的船东提单号");
|
|
|
}
|
|
|
|
|
|
// 下面这段的3个作用:
|
|
|
// 1. 将null换为空对象,避免后续处理null值麻烦
|
|
|
// 2. 如果主键为null,说明是新加的数据,这时候需要手动给GID、PID、CreateTime赋值
|
|
|
// 3. 如果主键不为null,说明是修改的数据,这时候需要手动给LastUpdate赋值
|
|
|
if (input.HouseList == null)
|
|
|
{
|
|
|
input.HouseList = new List<AFRHouse>();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
foreach (var house in input.HouseList)
|
|
|
{
|
|
|
StringTrimmer.TrimStringProperties(house);
|
|
|
|
|
|
house.LastUpdate = nowTime;
|
|
|
house.LastUpdateUserID = User.GID;
|
|
|
house.LastUpdateUserName = User.ShowName;
|
|
|
if (string.IsNullOrEmpty(house.GID))
|
|
|
{
|
|
|
house.GID = Guid.NewGuid().ToString();
|
|
|
house.PID = input.GID;
|
|
|
house.CreateTime = nowTime;
|
|
|
house.MBLNO = input.MBLNO;
|
|
|
house.StateIsAccept = house.StateIsMatched = house.StateIsSend = house.StateIsDelete = false;
|
|
|
house.NewNotice = "";
|
|
|
|
|
|
if (await DbAMS.Select<AFRHouse>().AnyAsync(h => h.HouseBillNo == house.HouseBillNo && h.IsDel == false))
|
|
|
{
|
|
|
throw new Exception("已存在相同的货代提单号");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (await DbAMS.Select<AFRHouse>().AnyAsync(h => h.HouseBillNo == house.HouseBillNo && h.GID != house.GID && h.IsDel == false))
|
|
|
{
|
|
|
throw new Exception("已存在相同的货代提单号");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (house.CntrList == null)
|
|
|
{
|
|
|
house.CntrList = new List<AFRCntrno>();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
house.CntrList.ForEach(cntr =>
|
|
|
{
|
|
|
cntr.LastUpdate = nowTime;
|
|
|
StringTrimmer.TrimStringProperties(cntr);
|
|
|
|
|
|
if (string.IsNullOrEmpty(cntr.GID))
|
|
|
{
|
|
|
cntr.GID = Guid.NewGuid().ToString();
|
|
|
cntr.PID = house.GID;
|
|
|
cntr.CreateTime = nowTime;
|
|
|
cntr.HouseBillNo = house.HouseBillNo;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 对分单数据统计出要执行的操作,判断哪些数据是 新增/修改/删除
|
|
|
var inputHouseGids = input.HouseList?.Select(h => h.GID);
|
|
|
var oldHouseGids = oldMaster.HouseList?.Select(h => h.GID);
|
|
|
|
|
|
var waitInsertHouseGids = inputHouseGids.Except(oldHouseGids); // 要新增的分单主键
|
|
|
var waitDeleteHouseGids = oldHouseGids.Except(inputHouseGids); // 要删除的分单主键
|
|
|
var waitUpdateHouseGids = oldHouseGids.Intersect(inputHouseGids); // 要修改的分单主键
|
|
|
|
|
|
List<AFRHouse> waitInsertHouseList = null, waitUpdateHouseList = null;
|
|
|
if (waitInsertHouseGids.Any())
|
|
|
{
|
|
|
waitInsertHouseList = input.HouseList.Where(h => waitInsertHouseGids.Contains(h.GID)).ToList();
|
|
|
}
|
|
|
if (waitUpdateHouseGids.Any())
|
|
|
{
|
|
|
waitUpdateHouseList = input.HouseList.Where(h => waitUpdateHouseGids.Contains(h.GID)).ToList();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 对箱子数据统计出要执行的操作,判断哪些数据是 新增/修改/删除
|
|
|
var inputCtnList = input.HouseList.SelectMany(h => h.CntrList);
|
|
|
var oldCtnList = oldMaster.HouseList.SelectMany(h => h.CntrList);
|
|
|
|
|
|
var inputCtnGids = inputCtnList.Select(ctn => ctn.GID);
|
|
|
var oldCtnGids = oldCtnList.Select(ctn => ctn.GID);
|
|
|
|
|
|
|
|
|
var waitInsertCtnGids = inputCtnGids.Except(oldCtnGids); // 要新增的箱子主键
|
|
|
var waitDeleteCtnGids = oldCtnGids.Except(inputCtnGids); // 要删除的箱子主键
|
|
|
var waitUpdateCtnGids = oldCtnGids.Intersect(inputCtnGids); // 要修改的箱子主键
|
|
|
|
|
|
List<AFRCntrno> waitInsertCtnList = null, waitUpdateCtnList = null;
|
|
|
if (waitInsertCtnGids.Any())
|
|
|
{
|
|
|
waitInsertCtnList = inputCtnList.Where(c => waitInsertCtnGids.Contains(c.GID)).ToList();
|
|
|
}
|
|
|
if (waitUpdateCtnGids.Any())
|
|
|
{
|
|
|
waitUpdateCtnList = inputCtnList.Where(c => waitUpdateCtnGids.Contains(c.GID)).ToList();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 开始执行
|
|
|
await using DbTransaction tran = await GetDbAmsTransaction();
|
|
|
|
|
|
// 主单执行
|
|
|
await DbAMS.Update<AFRMaster>()
|
|
|
.SetSource(input)
|
|
|
.IgnoreColumns(m => new { m.CompID, m.CompName, m.UserID, m.UserName })
|
|
|
.WithTransaction(tran)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
// 分单执行
|
|
|
if (waitInsertHouseGids.Any())
|
|
|
{
|
|
|
await DbAMS.Insert(waitInsertHouseList).WithTransaction(tran).ExecuteAffrowsAsync();
|
|
|
|
|
|
await SaveHistoryAsync(input.GID, waitInsertHouseList, "新增", 0, "创建了分单", null, tran);
|
|
|
}
|
|
|
if (waitDeleteHouseGids.Any())
|
|
|
{
|
|
|
await DbAMS.Update<AFRHouse>()
|
|
|
.Set(h => h.IsDel == true)
|
|
|
.Set(h => h.LastUpdate == nowTime)
|
|
|
.WithTransaction(tran)
|
|
|
.Where(h => waitDeleteHouseGids.Contains(h.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
await SaveHistoryAsync(input.GID, waitDeleteHouseGids.Select(gid => new AFRHouse() { GID = gid }), "删除", 0, "删除了单据", null, tran);
|
|
|
}
|
|
|
if (waitUpdateHouseGids.Any())
|
|
|
{
|
|
|
await DbAMS.Update<AFRHouse>()
|
|
|
.SetSource(waitUpdateHouseList)
|
|
|
.IgnoreColumns(h => new { h.StateIsMatched, h.StateIsAccept, h.StateIsSend, h.StateIsDelete, h.NewNotice })
|
|
|
.WithTransaction(tran)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
await SaveHistoryAsync(input.GID, waitUpdateHouseList, "修改", 0, "修改了单据", null, tran);
|
|
|
}
|
|
|
|
|
|
// 箱子执行
|
|
|
if (waitInsertCtnGids.Any())
|
|
|
{
|
|
|
await DbAMS.Insert(waitInsertCtnList).WithTransaction(tran).ExecuteAffrowsAsync();
|
|
|
}
|
|
|
if (waitDeleteCtnGids.Any())
|
|
|
{
|
|
|
await DbAMS.Delete<AFRCntrno>()
|
|
|
.WithTransaction(tran)
|
|
|
.Where(h => waitDeleteCtnGids.Contains(h.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
}
|
|
|
if (waitUpdateCtnGids.Any())
|
|
|
{
|
|
|
await DbAMS.Update<AFRCntrno>()
|
|
|
.SetSource(waitUpdateCtnList)
|
|
|
.WithTransaction(tran)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
tran.Commit();
|
|
|
}
|
|
|
|
|
|
return await Get(input.GID);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task Delete(string ids)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(ids))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
DateTime nowTime = DateTime.Now;
|
|
|
|
|
|
string[] idArr = ids.Split(',');
|
|
|
foreach (string id in idArr)
|
|
|
{
|
|
|
await using DbTransaction tran = await GetDbAmsTransaction();
|
|
|
|
|
|
await DbAMS.Update<AFRMaster>()
|
|
|
.Set(h => h.IsDel == true)
|
|
|
.Set(h => h.LastUpdate == nowTime)
|
|
|
.WithTransaction(tran)
|
|
|
.Where(h => id == h.GID)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
await DbAMS.Update<AFRHouse>()
|
|
|
.Set(h => h.IsDel == true)
|
|
|
.Set(h => h.LastUpdate == nowTime)
|
|
|
.WithTransaction(tran)
|
|
|
.Where(h => h.PID == id)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
tran.Commit();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 发送
|
|
|
/// </summary>
|
|
|
/// <param name="ids"></param>
|
|
|
/// <param name="hids"></param>
|
|
|
/// <param name="sendType">1:原始发送 2:重发 3:修改 4:删除</param>
|
|
|
public async Task<(bool, string)> Send(string ids, string hids, int sendType)
|
|
|
{
|
|
|
//return (true,"发送成功");
|
|
|
// 是否全部成功
|
|
|
bool isFullSuccess = true;
|
|
|
|
|
|
#region 查询电子口岸的请求参数
|
|
|
var paramSets = await DbBus.Get(DbList.djydb).Select<ParamSet>().Where(x => x.PARAMNAME == "AFRURL" || x.PARAMNAME == "AFRAccount" || x.PARAMNAME == "AFRKey").ToListAsync(p => new
|
|
|
{
|
|
|
p.PARAMNAME,
|
|
|
p.PARAMVALUE
|
|
|
});
|
|
|
var afrUrl = paramSets.FirstOrDefault(p => p.PARAMNAME == "AFRURL").PARAMVALUE ?? throw new Exception("需要配置AFR服务的接口地址:AFRURL");
|
|
|
var afrAccount = paramSets.FirstOrDefault(p => p.PARAMNAME == "AFRAccount")?.PARAMVALUE ?? throw new Exception("需要配置用于请求AFR服务的账户名:AFRAccount");
|
|
|
var afrKey = paramSets.FirstOrDefault(p => p.PARAMNAME == "AFRKey")?.PARAMVALUE ?? throw new Exception("需要配置用于请求AFR服务的密钥:AFRKey");
|
|
|
#endregion
|
|
|
|
|
|
#region 根据不同的发送类型,使用不同的方式从库里查询要发送的数据
|
|
|
List<AFRMaster> masterAll = null;
|
|
|
List<AFRHouse> houseAll = null;
|
|
|
List<AFRCntrno> cntrAll = null;
|
|
|
|
|
|
if (sendType is 1)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(ids))
|
|
|
{
|
|
|
throw new ArgumentNullException(nameof(ids));
|
|
|
}
|
|
|
|
|
|
var idArr = ids.Split(',');
|
|
|
|
|
|
masterAll = await DbAMS.Select<AFRMaster>().Where(m => m.IsDel == false && idArr.Contains(m.GID)).ToListAsync();
|
|
|
if (masterAll.Count != idArr.Length)
|
|
|
{
|
|
|
throw new Exception("所选记录有些已被删除,请刷新页面后重试");
|
|
|
}
|
|
|
|
|
|
houseAll = await DbAMS.Select<AFRHouse>().Where(h => h.IsDel == false && idArr.Contains(h.PID)).ToListAsync();
|
|
|
|
|
|
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 or 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("所选记录有些已被删除,请刷新页面后重试");
|
|
|
}
|
|
|
|
|
|
var houseGids = houseAll.Select(h => h.GID);
|
|
|
cntrAll = await DbAMS.Select<AFRCntrno>().Where(c => hidArr.Contains(c.PID)).ToListAsync();
|
|
|
|
|
|
var housePids = houseAll.Select(h => h.PID);
|
|
|
masterAll = await DbAMS.Select<AFRMaster>().Where(m => m.IsDel == false && housePids.Contains(m.GID)).ToListAsync();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
StringBuilder messageBuilder = new();
|
|
|
|
|
|
#region 构建请求参数
|
|
|
// 原始发送 重发 修改
|
|
|
if (sendType is 1 or 2 or 3)
|
|
|
{
|
|
|
// 批量检查主单字段是否为空
|
|
|
foreach (var masterItem in masterAll)
|
|
|
{
|
|
|
var checkEmptyFields = new List<(string, string)>
|
|
|
{
|
|
|
(masterItem.MBLNO, "船东提单号"),
|
|
|
(masterItem.Vessel, "船名"),
|
|
|
(masterItem.Voyno, "航次"),
|
|
|
(masterItem.LoadHarbour, "装货港"),
|
|
|
(masterItem.LoadHarbourCode, "装货港五字码"),
|
|
|
(masterItem.DischargeHarbour, "卸货港"),
|
|
|
(masterItem.DischargeHarbourCode, "卸货港五字码"),
|
|
|
(masterItem.EstimatedArrivalTime?.ToString(), "预计到达时间"),
|
|
|
(masterItem.ShipCompanyCode, "船公司"),
|
|
|
(masterItem.Clause, "运输条款"),
|
|
|
(masterItem.ConsignmentType, "整箱/拼箱"),
|
|
|
(masterItem.FilingType, "申报运输类型"),
|
|
|
(masterItem.LastForeignHarbour, "交货地全称"),
|
|
|
(masterItem.LastForeignHarbourCode, "交货地五字码"),
|
|
|
};
|
|
|
foreach (var (value, name) in checkEmptyFields)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
|
{
|
|
|
throw new Exception($"提单号【{masterItem.MBLNO}】的{name}不能为空");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 批量检查分单字段是否为空
|
|
|
foreach (var house in houseAll)
|
|
|
{
|
|
|
var checkEmptyFields2 = new List<(string, string)>
|
|
|
{
|
|
|
(house.HouseBillNo, "货代提单号"),
|
|
|
(house.SendName, "发货人名称"),
|
|
|
(house.SendCountryCode, "发货人国家代码"),
|
|
|
(house.SendCountry, "发货人国家"),
|
|
|
(house.SendCity, "发货人城市"),
|
|
|
(house.SendAddress, "发货人地址"),
|
|
|
(house.SendTel, "发货人电话"),
|
|
|
(house.ReceiveName, "收货人名称"),
|
|
|
(house.ReceiveCountryCode, "收货人国家代码"),
|
|
|
(house.ReceiveCountry, "收货人国家"),
|
|
|
(house.ReceiveCity, "收货人城市"),
|
|
|
(house.ReceiveAddress, "收货人地址"),
|
|
|
(house.ReceiveTel, "收货人电话"),
|
|
|
(house.NotifyName, "通知人名称"),
|
|
|
(house.NotifyCountryCode, "通知人国家代码"),
|
|
|
(house.NotifyCountry, "通知人国家"),
|
|
|
(house.NotifyCity, "通知人城市"),
|
|
|
(house.NotifyAddress, "通知人地址"),
|
|
|
(house.NotifyTel, "通知人电话"),
|
|
|
};
|
|
|
foreach (var (value, name) in checkEmptyFields2)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
|
{
|
|
|
throw new Exception($"分单【{house.HouseBillNo}】的{name}不能为空");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 批量检查箱子字段是否为空
|
|
|
foreach (var cntr in cntrAll)
|
|
|
{
|
|
|
var checkEmptyFields3 = new List<(string, string)>
|
|
|
{
|
|
|
(cntr.EnProductName, "品名"),
|
|
|
(cntr.ShippingMark, "唛头"),
|
|
|
(cntr.ContainerNo, "箱号"),
|
|
|
(cntr.ContainerTypeCode, "箱型"),
|
|
|
(cntr.SealNo, "封号"),
|
|
|
(cntr.Digit?.ToString(), "件数"),
|
|
|
(cntr.GrossWeight?.ToString(), "毛重"),
|
|
|
(cntr.Volume?.ToString(), "体积"),
|
|
|
(cntr.Hscode, "HSCode")
|
|
|
};
|
|
|
foreach (var (value, name) in checkEmptyFields3)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
|
{
|
|
|
throw new Exception($"箱号【{cntr.ContainerNo}】的{name}不能为空");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (AFRMaster masterItem in masterAll)
|
|
|
{
|
|
|
// 待处理的分单
|
|
|
List<AFRHouse> houseList = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
#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】时,【交货地全称】与【交货地五字码】为必填项");
|
|
|
}
|
|
|
|
|
|
// 如果操作类型为“重发”,则待发送的记录必须都为“已删除”,因为宁波接口要求记录状态是“删除成功”的,才可以重发
|
|
|
// 重发添加条件:海关返回状态异常
|
|
|
if (sendType is 2)
|
|
|
{
|
|
|
if (houseList.Any(h => h.StateIsDelete == false && h.NewNotice is not ("警告" or "海关拒绝" or "海关监控" or "海关删除")))
|
|
|
{
|
|
|
string tip = string.Join("、", houseList.Where(h => h.StateIsDelete == false && h.NewNotice is not ("警告" or "海关拒绝" or "海关监控" or "海关删除")).Select(h => h.HouseBillNo).ToList());
|
|
|
throw new Exception($"当分单状态为“删除发送”或者存在“海关返回状态存在异常”的情况下,才能进行“重发”操作,请检查分单号:【{tip}】");
|
|
|
}
|
|
|
}
|
|
|
// 如果操作类型为“修改”,则待发送记录不能有“已删除”的
|
|
|
if (sendType is 3)
|
|
|
{
|
|
|
if (houseList.Any(h => h.StateIsDelete))
|
|
|
{
|
|
|
string tip = string.Join("、", houseList.Where(h => h.StateIsDelete).Select(h => h.HouseBillNo).ToList());
|
|
|
throw new Exception($"已“删除发送”的记录需要先进行“重发”,才能进行 “修改发送”或“删除发送” 操作,所选分单中存在已经“删除发送”的记录,分单号:【{tip}】");
|
|
|
}
|
|
|
}
|
|
|
// 记录状态是回执成功的,才可以修改(暂不校验)
|
|
|
|
|
|
// 验证账户余额是否充足
|
|
|
var fin = new FinanceService();
|
|
|
var getfinrs = fin.CheckBalance(new CustFee
|
|
|
{
|
|
|
LURURENID = User.GID,
|
|
|
BSTYPE = BusinessType.AFR_REPORT,
|
|
|
SENDTYPE = sendType switch { 1 or 2 => 0, 3 => 1, _ => throw new NotImplementedException() },
|
|
|
}, houseList.Count);
|
|
|
|
|
|
if (!getfinrs.Status)
|
|
|
{
|
|
|
throw new Exception(getfinrs.Message);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
AFRRequestDto requestDto = new AFRRequestDto()
|
|
|
{
|
|
|
// 添加主单的数据
|
|
|
masterBillInfo = new MasterBillInfo()
|
|
|
{
|
|
|
masterBillNo = masterItem.MBLNO,
|
|
|
shippingNo = masterItem.ShippingNo,
|
|
|
clause = masterItem.Clause,
|
|
|
consignmentType = masterItem.ConsignmentType,
|
|
|
dischargeHarbour = masterItem.DischargeHarbour,
|
|
|
dischargeHarbourCode = masterItem.DischargeHarbourCode,
|
|
|
estimatedArrivalTime = masterItem.EstimatedArrivalTime,
|
|
|
filingType = masterItem.FilingType,
|
|
|
lastForeignHarbour = masterItem.LastForeignHarbour,
|
|
|
lastForeignHarbourCode = masterItem.LastForeignHarbourCode,
|
|
|
loadDate = masterItem.LoadDate,
|
|
|
loadHarbour = masterItem.LoadHarbour,
|
|
|
loadHarbourCode = masterItem.LoadHarbourCode,
|
|
|
requesterDea = sysOptionConfig.Webconfig.requesterDea,
|
|
|
shipCompany = masterItem.ShipCompanyMapCode,
|
|
|
vessel = masterItem.Vessel,
|
|
|
voyage = masterItem.Voyno
|
|
|
},
|
|
|
houseBillInfoList = new List<HouseBillInfo>()
|
|
|
};
|
|
|
|
|
|
if (houseList != null)
|
|
|
{
|
|
|
foreach (AFRHouse houseItem in houseList)
|
|
|
{
|
|
|
var houseBillInfo = new HouseBillInfo()
|
|
|
{
|
|
|
ctnInfo = new Model.AFRDto.CtnInfo() { insertList = new List<InsertList>() },
|
|
|
businessId = houseItem.HouseBillNo,
|
|
|
houseBillNo = houseItem.HouseBillNo,
|
|
|
notifyAddress = houseItem.NotifyAddress,
|
|
|
notifyCity = houseItem.NotifyCity,
|
|
|
notifyContact = houseItem.NotifyContact,
|
|
|
notifyCountry = houseItem.NotifyCountry,
|
|
|
notifyCountryCode = houseItem.NotifyCountryCode,
|
|
|
notifyName = houseItem.NotifyName,
|
|
|
notifyTel = houseItem.NotifyTel,
|
|
|
receiveAddress = houseItem.ReceiveAddress,
|
|
|
receiveCity = houseItem.ReceiveCity,
|
|
|
receiveContact = houseItem.ReceiveContact,
|
|
|
receiveCountry = houseItem.ReceiveCountry,
|
|
|
receiveCountryCode = houseItem.ReceiveCountryCode,
|
|
|
receiveName = houseItem.ReceiveName,
|
|
|
receiveTel = houseItem.ReceiveTel,
|
|
|
sendAddress = houseItem.SendAddress,
|
|
|
sendCity = houseItem.SendCity,
|
|
|
sendContact = houseItem.SendContact,
|
|
|
sendCountry = houseItem.SendCountry,
|
|
|
sendCountryCode = houseItem.SendCountryCode,
|
|
|
sendName = houseItem.SendName,
|
|
|
sendTel = houseItem.SendTel,
|
|
|
shippingNo = houseItem.ShippingNo
|
|
|
};
|
|
|
|
|
|
// 添加箱信息的数据
|
|
|
List<AFRCntrno> cntrList = cntrAll.Where(c => c.PID == houseItem.GID).ToList();
|
|
|
if (cntrList != null)
|
|
|
{
|
|
|
foreach (AFRCntrno cntrItem in cntrList)
|
|
|
{
|
|
|
houseBillInfo.ctnInfo.insertList.Add(new InsertList()
|
|
|
{
|
|
|
containerMark = cntrItem.ContainerMark,
|
|
|
containerNo = cntrItem.ContainerNo,
|
|
|
containerType = cntrItem.ContainerTypeMapCode,
|
|
|
dangerContact = cntrItem.DangerContact,
|
|
|
dangerContactTel = cntrItem.DangerContactTel,
|
|
|
dangerGrade = cntrItem.DangerGrade,
|
|
|
dangerMemo = cntrItem.DangerMemo,
|
|
|
digit = cntrItem.Digit?.ToString(),
|
|
|
enProductName = cntrItem.EnProductName,
|
|
|
grossWeight = cntrItem.GrossWeight?.ToString(),
|
|
|
hscode = cntrItem.Hscode,
|
|
|
ignite = cntrItem.Ignite,
|
|
|
originCountry = cntrItem.OriginCountry,
|
|
|
originCountryCode = cntrItem.OriginCountryCode,
|
|
|
packing = cntrItem.PackingMapName,
|
|
|
packingCode = cntrItem.PackingMapCode,
|
|
|
sealNo = cntrItem.SealNo,
|
|
|
shippingMark = cntrItem.ShippingMark,
|
|
|
unCode = cntrItem.UnCode,
|
|
|
volume = cntrItem.Volume?.ToString(),
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
requestDto.houseBillInfoList.Add(houseBillInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 开始请求电子口岸的接口
|
|
|
var masterBillInfoStr = JsonHelper.Instance.Serialize(requestDto);
|
|
|
var businessParam = new Dictionary<string, string>()
|
|
|
{
|
|
|
{ "masterBillInfo", masterBillInfoStr }
|
|
|
};
|
|
|
var param = BuildRequestParam(sendType, afrAccount, afrKey, businessParam);
|
|
|
|
|
|
var request = JsonHelper.Instance.Serialize(param);
|
|
|
var logGuid = Guid.NewGuid().ToString();
|
|
|
logger.LogInformation($"请求宁波电子口岸API,{logGuid},入参:{request}");
|
|
|
|
|
|
string response = await HttpHelp.Post(param, afrUrl, PsotType.Json);
|
|
|
|
|
|
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;
|
|
|
|
|
|
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);
|
|
|
|
|
|
#region 扣费、保存状态
|
|
|
foreach (AFRHouse dealHouseItem in houseList)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
var expendResult = fin.Expend(new CustFee
|
|
|
{
|
|
|
CARRIER = masterItem.ShipCompanyCode,
|
|
|
ETD = masterItem.LoadDate,
|
|
|
VOYNO = masterItem.Voyno,
|
|
|
VESSEL = masterItem.Vessel,
|
|
|
HBLNO = dealHouseItem.HouseBillNo,
|
|
|
SENDUSERID = User.GID,
|
|
|
LURURENID = User.GID,
|
|
|
CtnrCount = cntrAll.Count(c => c.PID == dealHouseItem.GID),
|
|
|
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}");
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
var pidList = houseList.Select(h => h.PID);
|
|
|
var state = sendType switch { 1 => "新增发送成功", 2 => "重发成功", 3 => "修改发送成功", _ => "" };
|
|
|
|
|
|
// 保存状态
|
|
|
var hidList = houseList.Select(h => h.GID);
|
|
|
await DbAMS.Update<AFRHouse>()
|
|
|
.Set(h => h.StateIsSend == true)
|
|
|
.Set(h => h.NewNotice == state)
|
|
|
.SetIf(sendType == 2, h => h.StateIsDelete == false) //如果操作为重发,则把"删除发送"状态重置为“未删除发送”,这样后续才能重新 修改、删除
|
|
|
.Where(h => hidList.Contains(h.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
await DbAMS.Update<AFRMaster>()
|
|
|
.Set(h => h.StateIsSend == true) // 把主单的状态改为“已发送”,这样主单才会在“已发送”页面显示
|
|
|
.Where(h => pidList.Contains(h.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
// 记录历史
|
|
|
// 生成详细的发送日志
|
|
|
string requestLog = JsonConvert.SerializeObject(requestDto, Formatting.Indented, new JsonSerializerSettings()
|
|
|
{
|
|
|
ContractResolver = new LogPropertyWriteResolver(),
|
|
|
DateFormatString = "yyyy-MM-dd HH:mm:ss"
|
|
|
});
|
|
|
await SaveHistoryAsync(masterItem.GID, houseList, state, 0, "发送了单据", requestLog);
|
|
|
|
|
|
//await SaveHistoryAsync(masterItem.GID, houseList, "新增发送成功", 0, "发送了单据", requestLog);
|
|
|
//requestDto.masterBillInfo.estimatedArrivalTime = new DateTime(1999,12,12);
|
|
|
//requestDto.houseBillInfoList[0].notifyName = "测试人";
|
|
|
//requestDto.houseBillInfoList[0].ctnInfo.insertList[0].containerNo = "12312312";
|
|
|
|
|
|
//string requestLog2 = JsonConvert.SerializeObject(requestDto, Formatting.Indented, new JsonSerializerSettings()
|
|
|
//{
|
|
|
// ContractResolver = new LogPropertyWriteResolver(),
|
|
|
// DateFormatString = "yyyy-MM-dd HH:mm:ss"
|
|
|
//});
|
|
|
//await SaveHistoryAsync(masterItem.GID, houseList, "修改发送成功", 0, "发送了单据", requestLog2);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new Exception($"接口返回失败结果(code:{code2},msg:{msg2})");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new Exception($"接口调用失败(msg:{msg})");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
// 记录历史
|
|
|
var state = sendType switch { 1 => "新增发送失败", 2 => "重发失败", 3 => "修改发送失败", _ => "" };
|
|
|
await SaveHistoryAsync(masterItem.GID, houseList, state, 0, $"发送单据失败,失败原因:{ex.Message}");
|
|
|
|
|
|
// 保存状态
|
|
|
var hidList = houseList.Select(h => h.GID);
|
|
|
await DbAMS.Update<AFRHouse>()
|
|
|
.Set(h => h.NewNotice == state)
|
|
|
.Where(h => hidList.Contains(h.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
// 构建响应
|
|
|
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);
|
|
|
|
|
|
isFullSuccess = false;
|
|
|
|
|
|
// 继续处理下一单
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 删除发送
|
|
|
else if (sendType == 4)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
#region 发送前的各项校验
|
|
|
// 待发送记录不能有“已删除”的
|
|
|
if (houseAll.Any(h => h.StateIsDelete))
|
|
|
{
|
|
|
string tip = string.Join("、", houseAll.Where(h => h.StateIsDelete).Select(h => h.HouseBillNo).ToList());
|
|
|
throw new Exception($"所选分单中存在已经“删除发送”的记录,分单号:【{tip}】,请重新选择(已“删除发送”的记录需要先进行“重发”,才能进行 “修改发送”或“删除发送” 操作)");
|
|
|
}
|
|
|
|
|
|
// 验证账户余额是否充足
|
|
|
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>()
|
|
|
{
|
|
|
{ "ids", hbnos },
|
|
|
{ "fromdea", sysOptionConfig.Webconfig.requesterDea }
|
|
|
};
|
|
|
var param = BuildRequestParam(sendType, afrAccount, afrKey, businessParam);
|
|
|
|
|
|
var request = JsonHelper.Instance.Serialize(param);
|
|
|
var logGuid = Guid.NewGuid().ToString();
|
|
|
logger.LogInformation($"请求宁波电子口岸API,{logGuid},入参:{request}");
|
|
|
|
|
|
string response = await HttpHelp.Post(param, afrUrl, PsotType.Json);
|
|
|
|
|
|
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;
|
|
|
|
|
|
var code2 = data.GetValue("code")?.ToString();
|
|
|
var msg2 = data.GetValue("msg")?.ToString();
|
|
|
var data2 = data.GetValue("data")?.ToString();
|
|
|
|
|
|
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 = expendMasterItem.LoadDate,
|
|
|
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)
|
|
|
{
|
|
|
logger.LogError($"执行扣费时发生未知异常,{logGuid},异常信息:{ex.Message}");
|
|
|
continue;
|
|
|
}
|
|
|
// 记录历史
|
|
|
await SaveHistoryAsync(expendMasterItem.GID, new AFRHouse[] { expendHouseItem }, "删除发送成功", 0, "删除发送了单据");
|
|
|
}
|
|
|
|
|
|
// 保存状态
|
|
|
var hidList = houseAll.Select(h => h.GID);
|
|
|
await DbAMS.Update<AFRHouse>()
|
|
|
.Set(h => h.NewNotice == "删除发送成功")
|
|
|
.Set(h => h.StateIsDelete == true)
|
|
|
.Set(h => h.StateIsAccept == false) //@铁幕 何工,如果有一票我这收到了回执推送,然后我 删除 并 重发 了这票,那后续我还会再收到完整的回执推送吗? ————会的
|
|
|
.Set(h => h.StateIsMatched == false) //@铁幕 何工,如果有一票我这收到了回执推送,然后我 删除 并 重发 了这票,那后续我还会再收到完整的回执推送吗? ————会的
|
|
|
.Where(h => hidList.Contains(h.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
#endregion
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new Exception($"接口返回失败结果(code:{code2},msg:{msg2})");
|
|
|
}
|
|
|
}
|
|
|
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 SaveHistoryAsync(h.PID, new AFRHouse[] { h }, "删除发送失败", 0, $"删除发送单据失败,原因:{ex.Message}");
|
|
|
});
|
|
|
|
|
|
// 保存状态
|
|
|
var hidList = houseAll.Select(h => h.GID);
|
|
|
await DbAMS.Update<AFRHouse>()
|
|
|
.Set(h => h.NewNotice == "删除发送失败")
|
|
|
.Where(h => hidList.Contains(h.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
isFullSuccess = false;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
return (isFullSuccess, messageBuilder.ToString());
|
|
|
}
|
|
|
|
|
|
public async Task SaveReceipt(AFRReceiptDto input)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(input.businessId))
|
|
|
{
|
|
|
logger.LogError("接收到回执中,businessId为空");
|
|
|
return;
|
|
|
}
|
|
|
var house = await DbAMS.Select<AFRHouse>()
|
|
|
.Where(h => h.HouseBillNo == input.businessId && h.IsDel == false)
|
|
|
.FirstAsync();
|
|
|
|
|
|
if (house == null)
|
|
|
{
|
|
|
logger.LogError("接收到回执后,根据businessId未查到AFRHouse");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var update = DbAMS.Update<AFRHouse>();
|
|
|
|
|
|
// Accept、Warning、Reject、Matched、Hold、Cancel
|
|
|
string statusDesc = string.Empty;
|
|
|
switch (input.status)
|
|
|
{
|
|
|
case "Accept":
|
|
|
update.Set(h => h.StateIsAccept == true);
|
|
|
statusDesc = "海关接收";
|
|
|
break;
|
|
|
case "Matched":
|
|
|
update.Set(h => h.StateIsMatched == true);
|
|
|
update.Set(h => h.StateIsAccept == true);
|
|
|
statusDesc = "已匹配";
|
|
|
break;
|
|
|
case "Warning": statusDesc = "警告"; break;
|
|
|
case "Reject": statusDesc = "海关拒绝"; break;
|
|
|
case "Hold": statusDesc = "海关监控"; break;
|
|
|
case "Cancel": statusDesc = "海关删除"; break;
|
|
|
default: break;
|
|
|
}
|
|
|
update.Set(h => h.NewNotice == statusDesc);
|
|
|
|
|
|
// 更新AFRHouse的状态
|
|
|
await update.Where(h => h.GID == house.GID)
|
|
|
.ExecuteAffrowsAsync();
|
|
|
|
|
|
// 记录历史
|
|
|
await SaveHistoryAsync(house.PID, new AFRHouse[] { house }, statusDesc, 1, input.content);
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
public async Task<List<AFRMasterHistory>> GetHistory(string pid, string hid)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(pid) && string.IsNullOrWhiteSpace(hid))
|
|
|
{
|
|
|
throw new ArgumentException(nameof(pid) + "或" + nameof(hid));
|
|
|
}
|
|
|
|
|
|
var data = await DbAMS.Select<AFRMasterHistory>()
|
|
|
.WhereIf(!string.IsNullOrEmpty(pid), h => h.PID == pid)
|
|
|
.WhereIf(!string.IsNullOrEmpty(hid), h => h.HID == hid)
|
|
|
.OrderByDescending(h => h.CreateTime)
|
|
|
.ToListAsync();
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private SortedDictionary<string, string> BuildRequestParam(int sendType, string afrAccount, string afrKey, Dictionary<string, string> businessParam)
|
|
|
{
|
|
|
string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
string method = sendType switch
|
|
|
{
|
|
|
1 => "eportyun.manifest.afr.sendBill",
|
|
|
2 => "eportyun.manifest.afr.resendBill",
|
|
|
3 => "eportyun.manifest.afr.modifyBill",
|
|
|
4 => "eportyun.manifest.afr.deleteBill",
|
|
|
_ => throw new Exception()
|
|
|
};
|
|
|
var param = new SortedDictionary<string, string>(StringComparer.Ordinal)
|
|
|
{
|
|
|
{ "method", method },
|
|
|
{ "user_id", afrAccount },
|
|
|
{ "timestamp", timestamp },
|
|
|
{ "format", "json" },
|
|
|
{ "version", "2.0" }
|
|
|
};
|
|
|
foreach (var item in businessParam)
|
|
|
{
|
|
|
param.Add(item.Key, item.Value);
|
|
|
}
|
|
|
|
|
|
StringBuilder builder = new();
|
|
|
foreach (var item in param)
|
|
|
{
|
|
|
builder.Append(item.Key);
|
|
|
builder.Append('=');
|
|
|
builder.Append(item.Value);
|
|
|
builder.Append('&');
|
|
|
}
|
|
|
builder.Append("key=").Append(afrKey);
|
|
|
param.Add("sign", builder.ToString().ToMd5().ToUpper());
|
|
|
return param;
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 保存操作历史或回执接收历史
|
|
|
/// </summary>
|
|
|
/// <param name="mid">主单主键</param>
|
|
|
/// <param name="houseList">分单列表</param>
|
|
|
/// <param name="state">状态</param>
|
|
|
/// <param name="type">0:人工操作历史;1:回执接收历史</param>
|
|
|
/// <param name="remark"></param>
|
|
|
/// <param name="requestLog">请求的详细日志内容</param>
|
|
|
/// <param name="tran"></param>
|
|
|
/// <returns></returns>
|
|
|
private async Task SaveHistoryAsync(string mid,
|
|
|
IEnumerable<AFRHouse> houseList,
|
|
|
string state,
|
|
|
int type,
|
|
|
string remark,
|
|
|
string requestLog = null,
|
|
|
DbTransaction tran = null)
|
|
|
{
|
|
|
List<AFRMasterHistory> historyList = new(houseList.Count());
|
|
|
List<HistoryDetail> detailList = new(houseList.Count());
|
|
|
foreach (AFRHouse item in houseList)
|
|
|
{
|
|
|
var history = new AFRMasterHistory()
|
|
|
{
|
|
|
GID = Guid.NewGuid().ToString(),
|
|
|
CreateTime = DateTime.Now,
|
|
|
Operator = type == 0 ? User.ShowName : "系统管理员",
|
|
|
PID = mid,
|
|
|
HID = item.GID,
|
|
|
State = state,
|
|
|
Type = Convert.ToByte(type)
|
|
|
};
|
|
|
if (type == 0)
|
|
|
{
|
|
|
history.Remark = $"{history.Operator} 于 {(DateTime)history.CreateTime:yyyy-MM-dd HH:mm:ss} {remark}";
|
|
|
}
|
|
|
else if (type == 1)
|
|
|
{
|
|
|
history.Remark = $"您的单据 {item.HouseBillNo} 于 {(DateTime)history.CreateTime:yyyy-MM-dd HH:mm:ss} 接收到回执:{remark}";
|
|
|
}
|
|
|
historyList.Add(history);
|
|
|
|
|
|
if (requestLog != null)
|
|
|
{
|
|
|
detailList.Add(new HistoryDetail()
|
|
|
{
|
|
|
HistoryID = history.GID,
|
|
|
RequestLog = requestLog,
|
|
|
Type = 3
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
if (tran == null)
|
|
|
{
|
|
|
await DbAMS.Insert(historyList).ExecuteAffrowsAsync();
|
|
|
await DbAMS.Insert(detailList).ExecuteAffrowsAsync();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
await DbAMS.Insert(historyList).WithTransaction(tran).ExecuteAffrowsAsync();
|
|
|
await DbAMS.Insert(detailList).WithTransaction(tran).ExecuteAffrowsAsync();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public async Task<List<AFRAddrTemplate>> GetTemplate(string type, string name)
|
|
|
{
|
|
|
var data = await DbAMS.Select<AFRAddrTemplate>()
|
|
|
.WhereIf(!string.IsNullOrEmpty(type), t => t.Type == Convert.ToByte(type))
|
|
|
.WhereIf(!string.IsNullOrEmpty(name), t => t.TemPlateName.Contains(name))
|
|
|
.Where(t => t.UserID == User.GID)
|
|
|
.OrderByDescending(t => t.CreateTime)
|
|
|
.ToListAsync();
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
public async Task SaveTemplate(AFRAddrTemplate input)
|
|
|
{
|
|
|
DateTime nowTime = DateTime.Now;
|
|
|
if (string.IsNullOrEmpty(input.GID))
|
|
|
{
|
|
|
input.GID = Guid.NewGuid().ToString();
|
|
|
input.LastUpdate = nowTime;
|
|
|
input.CreateTime = nowTime;
|
|
|
input.UserID = User.GID;
|
|
|
input.UserName = User.ShowName;
|
|
|
input.CompID = User.CompId;
|
|
|
input.CompName = User.CompName;
|
|
|
|
|
|
await DbAMS.Insert(input).ExecuteAffrowsAsync();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
input.LastUpdate = nowTime;
|
|
|
|
|
|
await DbAMS.Update<AFRAddrTemplate>().SetSource(input).Where(t => t.GID == input.GID).ExecuteAffrowsAsync();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public async Task DeleteTemplate(string ids)
|
|
|
{
|
|
|
await DbAMS.Delete<AFRAddrTemplate>()
|
|
|
.Where(t => ids.Contains(t.GID))
|
|
|
.ExecuteAffrowsAsync();
|
|
|
}
|
|
|
|
|
|
//public Task<User> GetUser()
|
|
|
//{
|
|
|
// return User;
|
|
|
//}
|
|
|
}
|
|
|
} |