|
|
@@ -1129,6 +1129,7 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
.Select((x, y, z, z1, u) => new AirTicketFeeListView()
|
|
|
{
|
|
|
Id = x.Id,
|
|
|
+ No = x.RecordType,
|
|
|
CabinName = z.Name,
|
|
|
FlightDesc = x.FlightsDescription,
|
|
|
ClientNameList = x.ClientName,
|
|
|
@@ -1143,9 +1144,15 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
.ToListAsync();
|
|
|
|
|
|
// 4. 获取黑屏代码(三字码映射)
|
|
|
- var threeCodes = await _sqlSugar.Queryable<Res_ThreeCode>()
|
|
|
+ var threeCodeList = await _sqlSugar.Queryable<Res_ThreeCode>()
|
|
|
.Where(x => x.IsDel == 0)
|
|
|
- .ToDictionaryAsync(x => x.Three, x => x.AirPort);
|
|
|
+ .Select(x => new { x.Three, x.AirPort })
|
|
|
+ .ToListAsync();
|
|
|
+
|
|
|
+ // 保留第一个遇到的
|
|
|
+ var threeCodes = threeCodeList
|
|
|
+ .GroupBy(x => x.Three)
|
|
|
+ .ToDictionary(g => g.Key, g => g.First().AirPort);
|
|
|
|
|
|
// 5. 获取团组成本预算
|
|
|
var groupCostParameter = await _sqlSugar.Queryable<Grp_GroupCostParameter>()
|
|
|
@@ -1179,6 +1186,13 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
// 7. 处理航班描述和客户名称
|
|
|
foreach (var item in airTicketFeeList)
|
|
|
{
|
|
|
+ // 退票退票标识
|
|
|
+ if (item.No == 1)
|
|
|
+ {
|
|
|
+ item.CabinName += "(退票)";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
// 7.1 处理航班描述
|
|
|
if (!string.IsNullOrWhiteSpace(item.FlightDesc))
|
|
|
{
|
|
|
@@ -1195,12 +1209,13 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
? threeCodes[flightInfo.ArrivalAirport]?.ToString() ?? flightInfo.ArrivalAirport
|
|
|
: flightInfo.ArrivalAirport;
|
|
|
|
|
|
- string desc = $"{flightInfo.SequenceNo}.{departAirport}→{arrivalAirport}({flightInfo.DepartureDate})";
|
|
|
+ string desc = $"{flightInfo.SequenceNo}.{departAirport} → {arrivalAirport}({flightInfo.DepartureDate})";
|
|
|
flightDescBuilder.AppendLine(desc);
|
|
|
}
|
|
|
|
|
|
item.FlightDesc = flightDescBuilder.ToString().TrimEnd();
|
|
|
}
|
|
|
+ else item.FlightDesc = "录入数据不规范!请检查";
|
|
|
|
|
|
// 7.2 处理客户名称
|
|
|
if (!string.IsNullOrWhiteSpace(item.ClientNameList))
|
|
|
@@ -1440,9 +1455,6 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
{
|
|
|
var first = g.First();
|
|
|
|
|
|
- // 合并航班基础信息(去重)
|
|
|
- var airTicketBasicInfos = g.SelectMany(x => x.AirTicketBasicInfos ?? new List<AirTicketBasicInfo>()).Distinct().ToList();
|
|
|
-
|
|
|
// 合并客户名称(去重)
|
|
|
var clientNames = string.Join(",", g.Select(x => x.ClientName).ToList());
|
|
|
var clientNameIds = ParseToIntListSafe(clientNames);
|
|
|
@@ -1465,29 +1477,33 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
auditsStr.Append($"{cabinTypeName}:{auditStatus};");
|
|
|
}
|
|
|
|
|
|
+ // 合并所有客户的机票信息
|
|
|
+ var custTicketInfos = g.SelectMany(x => x.CustTicketInfos ?? new List<CustTicketInfo>()).ToList();
|
|
|
+
|
|
|
+ // 累计退票金额
|
|
|
+ decimal refundAmount = custTicketInfos.Where(x => x.IsRefund).Sum(x => x.RefundRecord?.RefundAmount ?? 0m + x.RefundRecord?.NonRefundableTax ?? 0m);
|
|
|
+
|
|
|
+ // 付款金额
|
|
|
+ decimal payMoney = g.Sum(x => x.PayMoney) + refundAmount;
|
|
|
+
|
|
|
// 处理多舱位审核描述
|
|
|
var newFlight = new AirTicketFeeInfo
|
|
|
{
|
|
|
Id = first.Id,
|
|
|
FlightsDescription = g.Key,
|
|
|
-
|
|
|
- // 合并航班基础信息(去重)
|
|
|
- AirTicketBasicInfos = airTicketBasicInfos,
|
|
|
-
|
|
|
+ AirTicketBasicInfos = g.FirstOrDefault()?.AirTicketBasicInfos ?? new List<AirTicketBasicInfo>(),
|
|
|
// 合并客户人员
|
|
|
ClientName = clientNames,
|
|
|
ClientNameIds = clientNameIds,
|
|
|
-
|
|
|
// 合并所有客户的机票信息
|
|
|
- CustTicketInfos = g.SelectMany(x => x.CustTicketInfos ?? new List<CustTicketInfo>()).ToList(),
|
|
|
-
|
|
|
+ CustTicketInfos = custTicketInfos,
|
|
|
PriceDescription = first.PriceDescription,
|
|
|
|
|
|
// 付款信息
|
|
|
PayDId = first.PayDId,
|
|
|
ConsumptionPatterns = first.ConsumptionPatterns,
|
|
|
ConsumptionDate = first.ConsumptionDate,
|
|
|
- PayMoney = g.Sum(x => x.PayMoney),
|
|
|
+ PayMoney = payMoney,
|
|
|
PaymentCurrency = first.PaymentCurrency,
|
|
|
CTDId = first.CTDId,
|
|
|
BankNo = first.BankNo,
|
|
|
@@ -1504,7 +1520,7 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
AuditGMDate = first.AuditGMDate,
|
|
|
AuditStr = auditsStr.ToString().Trim()
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
return newFlight;
|
|
|
})
|
|
|
.ToList();
|
|
|
@@ -1519,28 +1535,6 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
foreach (var item in groupedByFlights)
|
|
|
{
|
|
|
flightsDescAll.AppendLine(item.FlightsDescription);
|
|
|
-
|
|
|
- // 添加测试数据
|
|
|
- if (!item.AirTicketBasicInfos.Any())
|
|
|
- {
|
|
|
- item.AirTicketBasicInfos = FlightParser.ParseFlights(item.FlightsDescription)
|
|
|
- .Select(x => new AirTicketBasicInfo()
|
|
|
- {
|
|
|
- No = x.SequenceNo,
|
|
|
- FlightsCode = x.FlightNumber,
|
|
|
- FlightsCity = $"{x.DepartureAirport}/{x.ArrivalAirport}",
|
|
|
- FlightsDate = x.DepartureDate,
|
|
|
- FlightsTime = x.DepartureTime,
|
|
|
- ArrivedTime = x.ArrivalTime
|
|
|
- })
|
|
|
- .ToList();
|
|
|
- }
|
|
|
-
|
|
|
- // 添加测试费用数据(仅用于测试,生产环境应移除)
|
|
|
- if (!item.CustTicketInfos.Any())
|
|
|
- {
|
|
|
- item.CustTicketInfos = GetTestCustomerData();
|
|
|
- }
|
|
|
}
|
|
|
groupInfo.FlightsDescription = flightsDescAll.ToString();
|
|
|
|
|
|
@@ -1652,7 +1646,6 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
// 1. 基础字段设置
|
|
|
var currUserId = dto.CurrUserId;
|
|
|
var groupId = dto.GroupAirInfo?.Id ?? 0;
|
|
|
- var successMsg = new StringBuilder();
|
|
|
var appPushBodyInfos = new List<AppPushBodyInfo>();
|
|
|
var index = 1;
|
|
|
|
|
|
@@ -1677,13 +1670,14 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
// 设置公共字段
|
|
|
airFeeInfo.CreateUserId = currUserId;
|
|
|
airFeeInfo.IsDel = 0;
|
|
|
- cardPaymentInfo.CreateUserId = currUserId;
|
|
|
cardPaymentInfo.DIId = groupId;
|
|
|
cardPaymentInfo.CTable = 85;
|
|
|
+ cardPaymentInfo.AuditGMDate = string.Empty;
|
|
|
cardPaymentInfo.UpdateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
cardPaymentInfo.IsPay = cardPaymentInfo.PayDId == 72 ? 1 : 0;
|
|
|
cardPaymentInfo.PayThenMoney = cardPaymentInfo.PayMoney;
|
|
|
cardPaymentInfo.RMBPrice = cardPaymentInfo.PayMoney * cardPaymentInfo.DayRate;
|
|
|
+ cardPaymentInfo.CreateUserId = currUserId;
|
|
|
cardPaymentInfo.IsDel = 0;
|
|
|
|
|
|
// 判断是否存在(通过唯一键)
|
|
|
@@ -1708,7 +1702,6 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
}
|
|
|
airId = AirId;
|
|
|
cardId = CardId;
|
|
|
-
|
|
|
appPushBodyInfos.Add(new AppPushBodyInfo()
|
|
|
{
|
|
|
OperationType = 1,
|
|
|
@@ -1723,12 +1716,12 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
var result = await UpdateExistingRecord(airFeeInfo, cardPaymentInfo, existingAir, groupId, index);
|
|
|
if (!result.Success)
|
|
|
{
|
|
|
- if (result.IsSkip)
|
|
|
- {
|
|
|
- successMsg.AppendLine(result.ErrorMessage);
|
|
|
- index++;
|
|
|
- continue;
|
|
|
- }
|
|
|
+ //if (result.IsSkip)
|
|
|
+ //{
|
|
|
+ // successMsg.AppendLine(result.ErrorMessage);
|
|
|
+ // index++;
|
|
|
+ // continue;
|
|
|
+ //}
|
|
|
RollbackTran();
|
|
|
return JsonView<AppPushBodyView>.Fail(result.ErrorMessage);
|
|
|
}
|
|
|
@@ -1755,10 +1748,7 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
AppPushBodyInfos = appPushBodyInfos
|
|
|
};
|
|
|
|
|
|
- if (successMsg.Length > 0) successMsg.Append("其他新增成功!");
|
|
|
- else successMsg.Append("保存成功!");
|
|
|
-
|
|
|
- return JsonView<AppPushBodyView>.Success(successMsg.ToString(), view);
|
|
|
+ return JsonView<AppPushBodyView>.Success("保存成功", view);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
@@ -1775,9 +1765,9 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
/// <param name="airTicketFeeInfos"></param>
|
|
|
/// <param name="groupId"></param>
|
|
|
/// <returns></returns>
|
|
|
- private Task<List<AirTicketFeeInfo>> OrganizeAirTicketDataAsync(List<AirTicketFeeInfo> airTicketFeeInfos, int groupId)
|
|
|
+ private Task<List<AirTicketFeeOpInfo>> OrganizeAirTicketDataAsync(List<AirTicketFeeInfo> airTicketFeeInfos, int groupId)
|
|
|
{
|
|
|
- var result = new List<AirTicketFeeInfo>();
|
|
|
+ var result = new List<AirTicketFeeOpInfo>();
|
|
|
|
|
|
foreach (var airInfo in airTicketFeeInfos)
|
|
|
{
|
|
|
@@ -1794,17 +1784,21 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
var customers = cabinGroup.ToList();
|
|
|
|
|
|
// 1. 正常记录(非退票客户)- 按舱位类型合并成一条数据
|
|
|
- var normalCustomers = customers.Where(x => !x.IsRefund).ToList();
|
|
|
+ var normalCustomers = customers.ToList();
|
|
|
if (normalCustomers.Any())
|
|
|
{
|
|
|
var custRecord = _mapper.Map<AirTicketFeeOpInfo>(airInfo);
|
|
|
custRecord.ClientNum = normalCustomers.Count;
|
|
|
custRecord.ClientName = string.Join(",", normalCustomers.Select(x => x.ClientId));
|
|
|
custRecord.CustTicketInfos = normalCustomers;
|
|
|
- custRecord.Price = normalCustomers.Sum(x => x.ActualPrice);
|
|
|
+
|
|
|
+ var totalTicketPrice = normalCustomers.Sum(x => x.ActualPrice + x.AdditionalServices?.Sum(x1 => x1.Amount) ?? 0.00m);
|
|
|
+ custRecord.Price = totalTicketPrice;
|
|
|
custRecord.Currency = airInfo.PaymentCurrency;
|
|
|
- custRecord.PayMoney = normalCustomers.Sum(x => x.TotalTicketPrice);
|
|
|
+ custRecord.PayMoney = totalTicketPrice;
|
|
|
custRecord.RecordType = 0; // 正常记录
|
|
|
+ custRecord.DIId = groupId;
|
|
|
+ custRecord.CType = normalCustomers.FirstOrDefault()?.CType ?? 0;
|
|
|
|
|
|
result.Add(custRecord);
|
|
|
}
|
|
|
@@ -1824,12 +1818,15 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
var refundAccount = refundGroup.Key;
|
|
|
|
|
|
var custRecord = _mapper.Map<AirTicketFeeOpInfo>(airInfo);
|
|
|
+ custRecord.DIId = groupId;
|
|
|
custRecord.RecordType = 1; // 退票记录
|
|
|
+ custRecord.CType = normalCustomers.FirstOrDefault()?.CType ?? 0;
|
|
|
custRecord.OriginalReservationId = custRecord.Id; // 关联原始记录
|
|
|
custRecord.ClientNum = refundCustomersInGroup.Count;
|
|
|
custRecord.ClientName = string.Join(",", refundCustomersInGroup.Select(x => x.ClientId));
|
|
|
custRecord.CustTicketInfos = refundCustomersInGroup;
|
|
|
|
|
|
+
|
|
|
// 计算退款金额(负数)
|
|
|
decimal totalRefundAmount = refundCustomersInGroup.Sum(x =>
|
|
|
(x.RefundRecord?.RefundAmount ?? 0) + (x.RefundRecord?.NonRefundableTax ?? 0));
|
|
|
@@ -1844,7 +1841,7 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return Task.FromResult(result);
|
|
|
+ return Task.FromResult(result.OrderBy(x => x.RecordType).ToList());
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -1939,7 +1936,7 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
|
|
|
// 获取付款信息
|
|
|
var existingCard = await _sqlSugar.Queryable<Grp_CreditCardPayment>()
|
|
|
- .FirstAsync(x => x.CId == airId && x.DIId == groupId && x.CTable == 85 && x.IsDel == 0);
|
|
|
+ .FirstAsync(x => x.DIId == groupId && x.CTable == 85 && x.CId == airId && x.IsDel == 0);
|
|
|
|
|
|
// 审核验证
|
|
|
if (existingCard != null)
|
|
|
@@ -1967,11 +1964,12 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
}
|
|
|
|
|
|
int cardId = 0;
|
|
|
+ cardPaymentInfo.Id = existingCard?.Id ?? 0;
|
|
|
+ cardPaymentInfo.CId = airId;
|
|
|
|
|
|
// 更新或新增付款信息
|
|
|
if (existingCard != null)
|
|
|
{
|
|
|
- cardPaymentInfo.Id = existingCard.Id;
|
|
|
var cardUpdateCount = await _sqlSugar.Updateable(cardPaymentInfo)
|
|
|
.IgnoreColumns(ignoreAllNullColumns: true)
|
|
|
.Where(x => x.Id == existingCard.Id)
|
|
|
@@ -1986,7 +1984,6 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- cardPaymentInfo.CId = airId;
|
|
|
var cardIdLong = await _sqlSugar.Insertable(cardPaymentInfo).ExecuteReturnIdentityAsync();
|
|
|
|
|
|
if (cardIdLong < 1)
|
|
|
@@ -2002,6 +1999,398 @@ public class AirTicketResRepository : BaseRepository<Grp_AirTicketReservations,
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 行程内删除用户信息
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task<JsonView> TripUserDeleteAsync(AirTicketCostTripUserDelDto dto)
|
|
|
+ {
|
|
|
+ // 基础数据查询(舱位类型)
|
|
|
+ var cabinDatas = await _sqlSugar
|
|
|
+ .Queryable<Sys_SetData>()
|
|
|
+ .Where(x => x.IsDel == 0 && x.STid == 44)
|
|
|
+ .Select(x => new { x.Id, x.Name })
|
|
|
+ .ToListAsync();
|
|
|
+
|
|
|
+ // 人员信息查询
|
|
|
+ var clientInfo = await _sqlSugar.Queryable<Crm_DeleClient>()
|
|
|
+ .Where(x => x.IsDel == 0 && x.Id == dto.ClientId)
|
|
|
+ .Select(x => new { x.Id, x.FirstName, x.LastName, x.Pinyin })
|
|
|
+ .FirstAsync();
|
|
|
+
|
|
|
+ // 客户名称
|
|
|
+ var clientName = clientInfo != null
|
|
|
+ ? $"{AesEncryptionHelper.Decrypt(clientInfo.FirstName)}{AesEncryptionHelper.Decrypt(clientInfo.LastName)}"
|
|
|
+ : $"ID:{dto.ClientId}";
|
|
|
+
|
|
|
+ BeginTran();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // 1. 查询对应的机票记录(按团组+航段+舱位+正常记录)
|
|
|
+ var airTicket = await _sqlSugar.Queryable<Grp_AirTicketReservations>()
|
|
|
+ .Where(x => x.DIId == dto.GroupId
|
|
|
+ && x.FlightsDescription == dto.FlightsDescription
|
|
|
+ && x.CType == dto.CType
|
|
|
+ && x.RecordType == 0 // 正常记录
|
|
|
+ && x.IsDel == 0)
|
|
|
+ .FirstAsync();
|
|
|
+
|
|
|
+ var cabinName = cabinDatas.FirstOrDefault(x => x.Id == dto.CType)?.Name ?? "未知舱位";
|
|
|
+
|
|
|
+ if (airTicket == null)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"未找到对应记录!(航段:{dto.FlightsDescription}, 舱位:{cabinName})");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1.1 检查人员是否在记录中
|
|
|
+ var hasClient = airTicket.CustTicketInfos?.Any(ct => ct.ClientId == dto.ClientId) == true;
|
|
|
+ if (!hasClient)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"人员【{clientName}(ID:{dto.ClientId})】不存在于该记录中!(航段:{dto.FlightsDescription}, 舱位:{cabinName})");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 查询对应的费用记录并验证状态
|
|
|
+ var cardPayment = await _sqlSugar.Queryable<Grp_CreditCardPayment>()
|
|
|
+ .Where(x => x.DIId == dto.GroupId && x.CId == airTicket.Id && x.CTable == 85 && x.IsDel == 0)
|
|
|
+ .FirstAsync();
|
|
|
+
|
|
|
+ if (cardPayment != null)
|
|
|
+ {
|
|
|
+ // 费用状态验证
|
|
|
+ if (cardPayment.IsAuditGM == 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"删除失败:当前费用已审核,不可删除人员!(航段:{dto.FlightsDescription}, 舱位:{cabinName}, 客户:{clientName})");
|
|
|
+ }
|
|
|
+ if (cardPayment.IsAuditGM == 3)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"删除失败:当前费用已自动审核,不可删除人员!(航段:{dto.FlightsDescription}, 舱位:{cabinName}, 客户:{clientName})");
|
|
|
+ }
|
|
|
+ if (cardPayment.IsPay == 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"删除失败:当前费用已付款,不可删除人员!(航段:{dto.FlightsDescription}, 舱位:{cabinName}, 客户:{clientName})");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 检查该人员是否有退票记录
|
|
|
+ var targetClientInfo = airTicket.CustTicketInfos?.FirstOrDefault(x => x.ClientId == dto.ClientId);
|
|
|
+ var hasRefund = targetClientInfo?.IsRefund == true;
|
|
|
+
|
|
|
+ if (hasRefund)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"删除失败:人员【{clientName}(ID:{dto.ClientId})】存在退票记录,不可删除!请先处理退票信息。");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 获取剩余人员列表
|
|
|
+ var remainingClients = airTicket.CustTicketInfos?
|
|
|
+ .Where(ct => ct.ClientId != dto.ClientId)
|
|
|
+ .ToList() ?? new List<CustTicketInfo>();
|
|
|
+
|
|
|
+ // 5. 计算总金额(包含机票价格 + 附加服务费用)
|
|
|
+ decimal totalPrice = remainingClients.Sum(x =>
|
|
|
+ (x?.ActualPrice ?? 0) + (x.AdditionalServices?.Sum(x1 => x1.Amount) ?? 0));
|
|
|
+
|
|
|
+ // 6. 更新或删除记录
|
|
|
+ if (remainingClients.Any())
|
|
|
+ {
|
|
|
+ // 6.1 更新机票记录
|
|
|
+ airTicket.Price = totalPrice;
|
|
|
+ airTicket.ClientNum = remainingClients.Count;
|
|
|
+ airTicket.ClientName = string.Join(",", remainingClients.Select(x => x.ClientId));
|
|
|
+ airTicket.CustTicketInfos = remainingClients;
|
|
|
+
|
|
|
+ var airUpdateCount = await _sqlSugar.Updateable(airTicket)
|
|
|
+ .UpdateColumns(x => new { x.ClientNum, x.ClientName, x.Price, x.CustTicketInfos })
|
|
|
+ .Where(x => x.Id == airTicket.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (airUpdateCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("删除失败:更新机票记录失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6.2 更新费用记录
|
|
|
+ if (cardPayment != null)
|
|
|
+ {
|
|
|
+ cardPayment.PayMoney = totalPrice;
|
|
|
+ cardPayment.UpdateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
+ cardPayment.PayThenMoney = totalPrice;
|
|
|
+ cardPayment.RMBPrice = totalPrice * (cardPayment?.DayRate ?? 1);
|
|
|
+
|
|
|
+ var cardUpdateCount = await _sqlSugar.Updateable(cardPayment)
|
|
|
+ .IgnoreColumns(ignoreAllNullColumns: true)
|
|
|
+ .Where(x => x.Id == cardPayment.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (cardUpdateCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("删除失败:更新费用记录失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 7. 没有剩余人员,删除整条记录
|
|
|
+ var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ // 7.1 软删除机票记录
|
|
|
+ airTicket.IsDel = 1;
|
|
|
+ airTicket.DeleteUserId = dto.CurrUserId;
|
|
|
+ airTicket.DeleteTime = now;
|
|
|
+
|
|
|
+ var airUpdateCount = await _sqlSugar.Updateable(airTicket)
|
|
|
+ .UpdateColumns(x => new { x.IsDel, x.DeleteUserId, x.DeleteTime })
|
|
|
+ .Where(x => x.Id == airTicket.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (airUpdateCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("删除失败:删除机票记录失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7.2 软删除费用记录
|
|
|
+ if (cardPayment != null)
|
|
|
+ {
|
|
|
+ cardPayment.IsDel = 1;
|
|
|
+ cardPayment.DeleteUserId = dto.CurrUserId;
|
|
|
+ cardPayment.DeleteTime = now;
|
|
|
+
|
|
|
+ var cardUpdateCount = await _sqlSugar.Updateable(cardPayment)
|
|
|
+ .UpdateColumns(x => new { x.IsDel, x.DeleteUserId, x.DeleteTime })
|
|
|
+ .Where(x => x.Id == cardPayment.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (cardUpdateCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("删除失败:删除费用记录失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ CommitTran();
|
|
|
+ return JsonView.Success($"删除成功!已从航段【{dto.FlightsDescription}】舱位【{cabinName}】中移除人员【{clientName}(ID:{dto.ClientId})】");
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ // 记录异常日志
|
|
|
+ // _logger.LogError(ex, "行程内删除用户信息失败,参数:{@dto}", dto);
|
|
|
+ return JsonView.Fail($"删除失败:{ex.Message}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 取消指定客户的退票
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto">取消退票参数</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task<JsonView> CancelClientRefundAsync(CancelClientRefundDto dto)
|
|
|
+ {
|
|
|
+ // 人员信息查询
|
|
|
+ var clientInfo = await _sqlSugar.Queryable<Crm_DeleClient>()
|
|
|
+ .Where(x => x.IsDel == 0 && x.Id == dto.ClientId)
|
|
|
+ .Select(x => new { x.Id, x.FirstName, x.LastName, x.Pinyin })
|
|
|
+ .FirstAsync();
|
|
|
+
|
|
|
+ // 客户名称
|
|
|
+ var clientName = clientInfo != null
|
|
|
+ ? $"{AesEncryptionHelper.Decrypt(clientInfo.FirstName)}{AesEncryptionHelper.Decrypt(clientInfo.LastName)}"
|
|
|
+ : $"ID:{dto.ClientId}";
|
|
|
+
|
|
|
+ BeginTran();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // 1. 查询退票记录
|
|
|
+ var refundRecord = await _sqlSugar.Queryable<Grp_AirTicketReservations>()
|
|
|
+ .Where(x => x.DIId == dto.GroupId
|
|
|
+ && x.FlightsDescription == dto.FlightsDescription
|
|
|
+ && x.CType == dto.CType
|
|
|
+ && x.RecordType == 1 // 退票记录
|
|
|
+ && x.IsDel == 0)
|
|
|
+ .FirstAsync();
|
|
|
+
|
|
|
+ if (refundRecord == null)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("未找到退票记录!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 查询退票费用记录并验证状态
|
|
|
+ var refundPayment = await _sqlSugar.Queryable<Grp_CreditCardPayment>()
|
|
|
+ .Where(x => x.DIId == dto.GroupId
|
|
|
+ && x.CId == refundRecord.Id
|
|
|
+ && x.CTable == 85
|
|
|
+ && x.IsDel == 0)
|
|
|
+ .FirstAsync();
|
|
|
+
|
|
|
+ if (refundPayment != null)
|
|
|
+ {
|
|
|
+ if (refundPayment.IsAuditGM == 1 || refundPayment.IsAuditGM == 3)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消失败:退票费用已审核,不可取消!");
|
|
|
+ }
|
|
|
+ if (refundPayment.IsPay == 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消失败:退票费用已付款,不可取消!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 解析退票人员列表
|
|
|
+ var refundClientIds = refundRecord.CustTicketInfos?
|
|
|
+ .Where(x => x.IsRefund)
|
|
|
+ .Select(x => x.ClientId)
|
|
|
+ .ToList() ?? new List<int>();
|
|
|
+
|
|
|
+ if (!refundClientIds.Contains(dto.ClientId))
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"人员【{clientName}】不存在于该退票记录中!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 查询关联的正常机票记录
|
|
|
+ var normalTicket = await _sqlSugar.Queryable<Grp_AirTicketReservations>()
|
|
|
+ .Where(x => x.Id == refundRecord.OriginalReservationId
|
|
|
+ && x.RecordType == 0
|
|
|
+ && x.IsDel == 0)
|
|
|
+ .FirstAsync();
|
|
|
+
|
|
|
+ if (normalTicket == null)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消失败:关联的正常机票记录不存在!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 更新正常机票中该客户的 IsRefund 标志
|
|
|
+ var normalTicketClients = normalTicket.CustTicketInfos ?? new List<CustTicketInfo>();
|
|
|
+ var targetClient = normalTicketClients.FirstOrDefault(x => x.ClientId == dto.ClientId);
|
|
|
+
|
|
|
+ if (targetClient != null)
|
|
|
+ {
|
|
|
+ targetClient.IsRefund = false;
|
|
|
+ targetClient.RefundRecord = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 保存正常机票记录
|
|
|
+ normalTicket.CustTicketInfos = normalTicketClients;
|
|
|
+
|
|
|
+ var airNormalCount = await _sqlSugar.Updateable(normalTicket)
|
|
|
+ .UpdateColumns(x => new { x.CustTicketInfos })
|
|
|
+ .Where(x => x.Id == normalTicket.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (airNormalCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消失败:更新正常机票记录失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 从退票记录中移除该客户(同时更新 CustTicketInfos)
|
|
|
+ var remainingRefundClients = refundRecord.CustTicketInfos?
|
|
|
+ .Where(x => x.ClientId != dto.ClientId)
|
|
|
+ .ToList() ?? new List<CustTicketInfo>();
|
|
|
+
|
|
|
+ if (remainingRefundClients.Any())
|
|
|
+ {
|
|
|
+ // 7.1 更新退票记录中的 CustTicketInfos
|
|
|
+ refundRecord.CustTicketInfos = remainingRefundClients;
|
|
|
+ refundRecord.ClientNum = remainingRefundClients.Count;
|
|
|
+ refundRecord.ClientName = string.Join(",", remainingRefundClients.Select(x => x.ClientId));
|
|
|
+
|
|
|
+ // 重新计算退款金额
|
|
|
+ decimal totalRefundAmount = remainingRefundClients.Sum(x =>
|
|
|
+ (x.RefundRecord?.RefundAmount ?? 0) + (x.RefundRecord?.NonRefundableTax ?? 0));
|
|
|
+ refundRecord.Price = totalRefundAmount;
|
|
|
+
|
|
|
+ var refundRecordCount = await _sqlSugar.Updateable(refundRecord)
|
|
|
+ .UpdateColumns(x => new { x.CustTicketInfos, x.ClientNum, x.ClientName, x.Price })
|
|
|
+ .Where(x => x.Id == refundRecord.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (refundRecordCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消退票失败:退票信息更新失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7.2 更新退票费用记录
|
|
|
+ if (refundPayment != null)
|
|
|
+ {
|
|
|
+ refundPayment.PayMoney = totalRefundAmount;
|
|
|
+ refundPayment.RMBPrice = totalRefundAmount * (refundPayment?.DayRate ?? 1);
|
|
|
+ refundPayment.UpdateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ var refundPaymentCount = await _sqlSugar.Updateable(refundPayment)
|
|
|
+ .UpdateColumns(x => new { x.PayMoney, x.RMBPrice, x.UpdateDate })
|
|
|
+ .Where(x => x.Id == refundPayment.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (refundPaymentCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消退票失败:退票费用信息更新失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 8. 退票记录中没有客户了,删除整条退票记录
|
|
|
+ var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
+ refundRecord.IsDel = 1;
|
|
|
+ refundRecord.DeleteUserId = dto.CurrUserId;
|
|
|
+ refundRecord.DeleteTime = now;
|
|
|
+
|
|
|
+ var refundRecordCount = await _sqlSugar.Updateable(refundRecord)
|
|
|
+ .UpdateColumns(x => new { x.IsDel, x.DeleteUserId, x.DeleteTime })
|
|
|
+ .Where(x => x.Id == refundRecord.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (refundRecordCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消退票失败:删除退票记录失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (refundPayment != null)
|
|
|
+ {
|
|
|
+ refundPayment.IsDel = 1;
|
|
|
+ refundPayment.DeleteUserId = dto.CurrUserId;
|
|
|
+ refundPayment.DeleteTime = now;
|
|
|
+
|
|
|
+ var refundPaymentCount = await _sqlSugar.Updateable(refundPayment)
|
|
|
+ .UpdateColumns(x => new { x.IsDel, x.DeleteUserId, x.DeleteTime })
|
|
|
+ .Where(x => x.Id == refundPayment.Id)
|
|
|
+ .ExecuteCommandAsync();
|
|
|
+
|
|
|
+ if (refundPaymentCount < 1)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail("取消退票失败:删除退票费用记录失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ CommitTran();
|
|
|
+ return JsonView.Success($"取消退票成功!已将客户【{clientName}】的退票状态恢复正常");
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ RollbackTran();
|
|
|
+ return JsonView.Fail($"取消退票失败:{ex.Message}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 按ID删除机票记录 2026版
|
|
|
/// 验证费用状态和退票记录
|