FeeAuditRepository.cs 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076
  1. using EyeSoft.Extensions;
  2. using EyeSoft.Logging;
  3. using NPOI.SS.Formula.Functions;
  4. using OASystem.Domain;
  5. using OASystem.Domain.Entities.Groups;
  6. using OASystem.Domain.Entities.Resource;
  7. using OASystem.Domain.ViewModels.Groups;
  8. using SqlSugar;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. namespace OASystem.Infrastructure.Repositories.Groups
  15. {
  16. /// <summary>
  17. /// 费用审核仓储
  18. /// </summary>
  19. public class FeeAuditRepository:BaseRepository<EntityBase,ViewBase>
  20. {
  21. public FeeAuditRepository(SqlSugarClient sqlSugar) : base(sqlSugar)
  22. {
  23. }
  24. /// <summary>
  25. /// 费用自动审核
  26. /// </summary>
  27. /// <param name="feeType">
  28. /// 1.酒店 76
  29. /// 2.op 79
  30. /// 3.其他费用-出行物资 98
  31. /// 4.保险 82
  32. /// 5.机票 85
  33. /// </param>
  34. /// <param name="diId">团组Id</param>
  35. /// <param name="dataId">数据Id(模块类型主表Id)</param>
  36. /// <returns></returns>
  37. public async Task<JsonView> FeeAutomaticAudit(int feeType, int diId, int dataId)
  38. {
  39. var _view = new JsonView() { Code = 201, Msg = "自动审核操作失败" };
  40. if (diId < 1) { _view.Msg = MsgTips.DiId; return _view; }
  41. if (dataId < 1) { _view.Msg = MsgTips.Id; return _view; }
  42. var groupDetails = _sqlSugar.Queryable<Grp_DelegationInfo>().Where(x => x.IsDel == 0 && x.Id == diId).First();
  43. if (groupDetails == null)
  44. {
  45. _view.Msg = $"团组信息为空,不可自动审核!";
  46. return _view;
  47. }
  48. var stids = new List<int>() { 17, 66, 91 };
  49. var setData = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && stids.Contains(x.STid)).ToList();
  50. var groupInfo = new Grp_GroupCostParameter();
  51. string _teamCurrency = string.Empty;
  52. decimal _teamRate = 1.0000M;
  53. var costContents = new List<GroupCostAuditView>();
  54. var subFeeTypeIds = new int[] {
  55. 4, // 保险 82
  56. 5, // 机票 85
  57. };
  58. if (!subFeeTypeIds.Contains(feeType))
  59. {
  60. groupInfo = _sqlSugar.Queryable<Grp_GroupCostParameter>().Where(x => x.IsDel == 0 && x.DiId == diId).First();
  61. if (groupInfo == null) { _view.Msg = $"团组成本信息未填写!"; return _view; }
  62. _teamCurrency = groupInfo.Currency;
  63. _teamRate = groupInfo.Rate;
  64. //币种验证 统一为currencycode三字码
  65. if (int.TryParse(_teamCurrency, out int currency)) _teamCurrency = setData.Find(x => x.Id == currency)?.Name ?? "";
  66. string costContentSql = $"Select * From Grp_GroupCost";
  67. costContents = _sqlSugar.SqlQueryable<GroupCostAuditView>(costContentSql).Where(x => x.IsDel == 0 && x.Diid == diId).ToList();
  68. if (costContents.Count < 1) { _view.Msg = $"团组成本信息未填写!"; return _view; }
  69. //处理 成本详细信息 日期为空
  70. for (int i = 0; i < costContents.Count; i++)
  71. {
  72. if (string.IsNullOrEmpty(costContents[i].Date))
  73. {
  74. int index = i - 1;
  75. if (index >= 0)
  76. {
  77. costContents[i].Date = costContents[index].Date;
  78. var dtBool = DateTime.TryParse(costContents[i].Date, out DateTime _dateTime);
  79. if (dtBool)
  80. {
  81. costContents[i].CurrTime = _dateTime;
  82. }
  83. }
  84. }
  85. else
  86. {
  87. var dtBool = DateTime.TryParse(costContents[i].Date, out DateTime _dateTime);
  88. if (dtBool)
  89. {
  90. costContents[i].CurrTime = _dateTime;
  91. }
  92. }
  93. }
  94. }
  95. if (feeType == 1)
  96. {
  97. //1089 对冲账或其他 不在审核范围
  98. var hotelCostInfo = _sqlSugar.Queryable<Grp_HotelReservations>().Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId && x.CheckType != 1089).First();
  99. var hotelCostDetails = _sqlSugar.Queryable<Grp_HotelReservationsContent>().Where(x => x.IsDel == 0 && x.DiId == diId && x.HrId == dataId).ToList();
  100. if (hotelCostInfo == null)
  101. {
  102. _view.Msg = $"酒店费用数据未填写";
  103. QuashAudit(76, diId, dataId);
  104. return _view;
  105. }
  106. //酒店费用金额 == 0 不自动审核
  107. if (hotelCostInfo.CardPrice == 0.0000M)
  108. {
  109. _view.Msg = $"酒店费用金额 == 0 不自动审核";
  110. QuashAudit(76, diId, dataId);
  111. return _view;
  112. }
  113. //获取C表汇率
  114. decimal _rate = 1.0000M;
  115. var roomFeeInfo = hotelCostDetails.Where(x => x.PriceType == 1).First();
  116. if (roomFeeInfo == null)
  117. {
  118. _view.Msg = $"酒店房间费用付款数据未填写";
  119. return _view;
  120. }
  121. _rate = roomFeeInfo.Rate == 0.0000M ? 1.0000M : roomFeeInfo.Rate;
  122. bool isAutoAudit = true; //是否自动审核
  123. DateTime checkIn = Convert.ToDateTime(hotelCostInfo.CheckInDate),
  124. checkOut = Convert.ToDateTime(hotelCostInfo.CheckOutDate);
  125. if (checkOut > checkIn) checkOut = checkOut.AddDays(-1); //房费计算,结束日期为前一天
  126. var hotelCostInfos = costContents.Where(x => x.CurrTime >= checkIn && x.CurrTime <= checkOut).ToList();
  127. if (hotelCostInfos.Count < 1) isAutoAudit = false;
  128. decimal otherFee = hotelCostDetails.Where(x => x.PriceType != 1).Sum(x => x.Price * (x.Rate == 0.0000M ? 1.0000M : x.Rate));
  129. if (otherFee > 0) { otherFee /= (checkOut - checkIn).Days; }
  130. var hotelCostInfosGroup = hotelCostInfos.GroupBy(x => x.Date);
  131. foreach (var item in hotelCostInfosGroup)
  132. {
  133. var hotelSingleRoomFee = item.Sum(x => x.HotelSingleRoomFee) * _teamRate; //成本单间费用
  134. var hotelDoubleRoomFee = item.Sum(x => x.HotelDoubleRoomFee) * _teamRate; //成本双人间费用
  135. var hotelSuiteFee = item.Sum(x => x.HotelSuiteFee) * _teamRate; //成本套房费用
  136. var hotelSuiteRoomFee = item.Sum(x => x.HotelSuiteRoomFee) * _teamRate; //成本其他房型间费用
  137. //1.判断费用是否 <= 成本费用
  138. //1.1 判断单间费用
  139. decimal singleRoomPrice = (hotelCostInfo.SingleRoomPrice + otherFee) * _rate; //酒店录入费用
  140. if (singleRoomPrice > 0) if (singleRoomPrice > hotelSingleRoomFee) isAutoAudit = false;
  141. //1.2 判断双人间费用
  142. decimal doubleRoomPrice = (hotelCostInfo.DoubleRoomPrice + otherFee) * _rate;//酒店录入费用
  143. if (doubleRoomPrice > 0) if (doubleRoomPrice > hotelDoubleRoomFee) isAutoAudit = false;
  144. //1.3 判断套房费用
  145. decimal suiteRoomPrice = (hotelCostInfo.SuiteRoomPrice + otherFee) * _rate;//酒店录入费用
  146. if (suiteRoomPrice > 0) if (suiteRoomPrice > hotelSuiteFee) isAutoAudit = false;
  147. //1.4 判断其他房型费用
  148. decimal otherRoomPrice = (hotelCostInfo.OtherRoomPrice + otherFee) * _rate;//酒店录入费用
  149. if (otherRoomPrice > 0) if (otherRoomPrice > hotelSuiteRoomFee) isAutoAudit = false;
  150. }
  151. //2.判断是否自动审核
  152. if (isAutoAudit)
  153. {
  154. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  155. .SetColumns(it => it.IsAuditGM == 3)
  156. .SetColumns(it => it.AuditGMOperate == 4)
  157. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  158. .Where(s => s.DIId == diId && s.CTable == 76 && s.CId == dataId)
  159. .ExecuteCommand();
  160. if (ccpUpdate > 0)
  161. {
  162. _view.Code = 200;
  163. _view.Msg = "自动审核执行成功";
  164. return _view;
  165. }
  166. }
  167. else
  168. {
  169. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  170. var quashStatus = QuashAudit(76, diId, dataId);
  171. if (quashStatus)
  172. {
  173. _view.Code = 200;
  174. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  175. return _view;
  176. }
  177. }
  178. }
  179. else if (feeType == 2)
  180. {
  181. //1.基础数据参数验证
  182. var priceType = new List<int>() {
  183. 1062 //1062 尾款
  184. };
  185. var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  186. .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId && !priceType.Contains(x.PriceType))
  187. .First();
  188. //var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  189. // .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId )
  190. // .First();
  191. if (opinfos == null)
  192. {
  193. _view.Msg = $"OP费用费用类型属于“尾款”或者 内容未填写";
  194. return _view;
  195. }
  196. //1.含超时费用/超支费用 手动审核
  197. if (opinfos.SelectCheck.Contains("超时") || opinfos.SelectCheck.Contains("超支") || opinfos.SelectCheck.Contains("尾款"))
  198. {
  199. _view.Msg = @$"OP费用含尾款/超支/超时费用,请手动审核";
  200. return _view;
  201. }
  202. //1.参数验证
  203. var opCheckPriceTyeps = opinfos.SelectCheck.Split(',');
  204. var opCheckPriceTyepIds = setData.Where(x => opinfos.SelectCheck.Split(',').Contains(x.Name)).Select(x => x.Id).ToList();
  205. var opContents = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservationsContent>()
  206. .Where(x => x.IsDel == 0 && x.DiId == diId && x.CTGGRId == dataId && opCheckPriceTyepIds.Contains(x.SId))
  207. .OrderBy(x => x.DatePrice, OrderByType.Asc)
  208. .ToList();
  209. if (opContents.Count < 1)
  210. {
  211. _view.Msg = $"OP费用费用内容未填写";
  212. return _view;
  213. }
  214. //获取C表汇率
  215. decimal _opRate = 1.0000M;
  216. decimal _opPayPercentage = 1.0000M;
  217. var payInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>().Where(x => x.IsDel == 0 && x.DIId == diId && x.CTable == 79 && x.CId == dataId).First();
  218. if (payInfo == null)
  219. {
  220. _view.Msg = $"OP费用付款数据未填写";
  221. return _view;
  222. }
  223. _opRate = payInfo.DayRate;
  224. _opPayPercentage = payInfo.PayPercentage / 100.00M;
  225. string opCurrencyName = setData.Find(x => x.Id == opContents[0].Currency)?.Name ?? "";
  226. //团组、OP币种 验证是否一致(一致:只比较金额,不计算汇率(2024-04-18))
  227. if (opCurrencyName.Equals(_teamCurrency))
  228. {
  229. _opRate = payInfo.DayRate;
  230. _teamRate = payInfo.DayRate;
  231. }
  232. var opBasicDatas = setData.Where(x => x.STid == 17).ToList(); //费用类型基础数据
  233. bool isAutoAudit = true;
  234. if (!DateTime.TryParse(opinfos.ServiceStartTime, out DateTime startDt1) || !DateTime.TryParse(opinfos.ServiceEndTime, out DateTime endDt1))
  235. {
  236. _view.Msg = $"OP费用服务起止日期格式不正确!";
  237. return _view;
  238. }
  239. DateTime startDt = startDt1;
  240. DateTime endDt = endDt1;
  241. var opCostDatas = costContents.Where(it => Convert.ToDateTime(it.Date) >= startDt && Convert.ToDateTime(it.Date) <= endDt).ToList();
  242. if (opCostDatas.Count < 1)
  243. {
  244. _view.Msg = $"该时间段内团组成本未填写!";
  245. return _view;
  246. }
  247. var noAuditFeeTypeIds = new List<int> {
  248. 982 ,//982 车超时费 -- 暂无
  249. 96 ,//96 接送机费 -- 暂无
  250. 97 ,//97 其他费用 -- 暂无
  251. 992 ,//992 住补费用 -- 暂无
  252. 1059,//1059 导游超时费用 -- 暂无
  253. 1070,//1070 尾款金额 -- 暂无
  254. 1071,//1071 其他额外费用 -- 暂无
  255. 1073,//1073 翻译超时费 -- 暂无
  256. 1074,//1074 早餐超支费用 -- 暂无
  257. 1075,//1075 午餐超支费用 -- 暂无
  258. 1076,//1076 晚餐超支费用 -- 暂无
  259. };
  260. //费用类型筛选 包含 feeTypeIds && 包含这些类型费用大于0
  261. var noAuditFeeContents = opContents.Where(x => x.Price > 0 && noAuditFeeTypeIds.Contains(x.SId)).ToList();
  262. if (noAuditFeeContents.Count > 0)
  263. {
  264. _view.Msg = @$"OP费用含尾款/超支/超时费用,请手动审核";
  265. return _view;
  266. }
  267. //2.按天按项 检查费用是否超过预算
  268. var opDayContent = opContents.GroupBy(x => x.DatePrice);
  269. foreach (var item in opDayContent)
  270. {
  271. var opCostInfo = opCostDatas.Where(x => Convert.ToDateTime(x.Date) == item.Key).ToList();
  272. if (opCostInfo.Count < 1) continue;
  273. //车费 91
  274. var opCarCost = item.FirstOrDefault(x => x.SId == 91);
  275. if (opCarCost != null)
  276. if (opCarCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.CarFee) * _opPayPercentage) isAutoAudit = false;
  277. //982 车超时费 -- 暂无
  278. //92 导游费
  279. var opGuideCost = item.FirstOrDefault(x => x.SId == 92);
  280. if (opGuideCost != null)
  281. if (opGuideCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.GuideFee) * _opPayPercentage) isAutoAudit = false;
  282. //94 导游景点费
  283. var opGuideScenicCost = item.FirstOrDefault(x => x.SId == 94);
  284. if (opGuideScenicCost != null)
  285. if (opGuideScenicCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.GuideScenicFee) * _opPayPercentage) isAutoAudit = false;
  286. //95 导游小费
  287. var opGuideTipCost = item.FirstOrDefault(x => x.SId == 95);
  288. if (opGuideTipCost != null)
  289. if (opGuideTipCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.GuideTipFee) * _opPayPercentage) isAutoAudit = false;
  290. //983 导游餐补
  291. var opGuideMealCost = item.FirstOrDefault(x => x.SId == 983);
  292. if (opGuideMealCost != null)
  293. if (opGuideMealCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.GuideMealFee) * _opPayPercentage) isAutoAudit = false;
  294. //984 导游房补
  295. var opGuideRoomCost = item.FirstOrDefault(x => x.SId == 984);
  296. if (opGuideRoomCost != null)
  297. if (opGuideRoomCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.GuideRoomFee) * _opPayPercentage) isAutoAudit = false;
  298. //985 导游交通
  299. var opGuideTrafficCost = item.FirstOrDefault(x => x.SId == 985);
  300. if (opGuideTrafficCost != null)
  301. if (opGuideTrafficCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.GuideTrafficFee) * _opPayPercentage) isAutoAudit = false;
  302. //96 接送机费 -- 暂无
  303. //97 其他费用 -- 暂无
  304. //979 司机工资
  305. var opDriverCost = item.FirstOrDefault(x => x.SId == 979);
  306. if (opDriverCost != null)
  307. if (opDriverCost.Price * _opRate > _teamRate * _opPayPercentage * opCostInfo.Sum(x => x.DriverFee) * _opPayPercentage) isAutoAudit = false;
  308. //980 司机小费
  309. var opDriverTipCost = item.FirstOrDefault(x => x.SId == 980);
  310. if (opDriverTipCost != null)
  311. if (opDriverTipCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.DriverTipFee) * _opPayPercentage) isAutoAudit = false;
  312. //981 司机餐补
  313. var opDriverMealCost = item.FirstOrDefault(x => x.SId == 981);
  314. if (opDriverMealCost != null)
  315. if (opDriverMealCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.DriverMealFee) * _opPayPercentage) isAutoAudit = false;
  316. //988 客户早餐费用
  317. var opClientBreakfastCost = item.FirstOrDefault(x => x.SId == 988);
  318. if (opClientBreakfastCost != null)
  319. if (opClientBreakfastCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.ClientBreakfastFee) * _opPayPercentage) isAutoAudit = false;
  320. //93 客户午餐费用
  321. var opClientLunchCost = item.FirstOrDefault(x => x.SId == 93);
  322. if (opClientLunchCost != null)
  323. if (opClientLunchCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.ClientLunchFee) * _opPayPercentage) isAutoAudit = false;
  324. //989 客户晚餐费用
  325. var opClientDinnerCost = item.FirstOrDefault(x => x.SId == 989);
  326. if (opClientDinnerCost != null)
  327. if (opClientDinnerCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.ClientDinnerFee) * _opPayPercentage) isAutoAudit = false;
  328. //990 景点门票费
  329. var opScenicTicketCost = item.FirstOrDefault(x => x.SId == 990);
  330. if (opScenicTicketCost != null)
  331. if (opScenicTicketCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.ScenicTicketFee) * _opPayPercentage) isAutoAudit = false;
  332. //991 饮料/零食/水果
  333. var opDrinkSnackFruitCost = item.FirstOrDefault(x => x.SId == 991);
  334. if (opDrinkSnackFruitCost != null)
  335. if (opDrinkSnackFruitCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.DrinkSnackFruitFee) * _opPayPercentage) isAutoAudit = false;
  336. //992 住补费用 -- 暂无
  337. //994 翻译费
  338. var opTranslatorCost = item.FirstOrDefault(x => x.SId == 994);
  339. if (opTranslatorCost != null)
  340. if (opTranslatorCost.Price * _opRate * _opPayPercentage > _teamRate * opCostInfo.Sum(x => x.TranslatorFee) * _opPayPercentage) isAutoAudit = false;
  341. //1059 导游超时费用 -- 暂无
  342. //1070 尾款金额 -- 暂无
  343. //1071 其他额外费用 -- 暂无
  344. //1073 翻译超时费 -- 暂无
  345. //1074 早餐超支费用 -- 暂无
  346. //1075 午餐超支费用 -- 暂无
  347. //1076 晚餐超支费用 -- 暂无
  348. }
  349. //更改审核状态
  350. if (isAutoAudit)
  351. {
  352. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  353. .SetColumns(it => it.IsAuditGM == 3)
  354. .SetColumns(it => it.AuditGMOperate == 4)
  355. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  356. .Where(s => s.DIId == diId && s.CTable == 79 && s.CId == dataId)
  357. .ExecuteCommand();
  358. if (ccpUpdate > 0)
  359. {
  360. _view.Code = 200;
  361. _view.Msg = "自动审核执行成功!";
  362. return _view;
  363. }
  364. }
  365. else
  366. {
  367. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  368. if (QuashAudit(79, diId, dataId))
  369. {
  370. _view.Code = 200;
  371. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  372. return _view;
  373. }
  374. }
  375. }
  376. else if (feeType == 3)
  377. {
  378. #region 出行物资的功能及相关费用自动审核
  379. var isAutoAudit = false;
  380. var currModule = 98; //其他款项
  381. int groupSize = groupDetails.VisitPNumber;
  382. decimal otherSubTotal = costContents.Sum(x => x.TeFee);
  383. decimal groupCostCNYTotal = costContents.Sum(x => x.TeFee) * _teamRate * groupSize; //团组成本出行物资总金额
  384. if (groupCostCNYTotal <= 0.00M)
  385. {
  386. _view.Msg = $"团组成本出行物资费用数据未填写";
  387. QuashAudit(currModule, diId, dataId);
  388. return _view;
  389. }
  390. var teNames = setData.Where(x => x.STid == 91).Select(x => x.Name).ToList();
  391. var otherFeeDatas = _sqlSugar.Queryable<Grp_DecreasePayments>()
  392. .InnerJoin<Grp_CreditCardPayment>((dp, ccp) => dp.Id == ccp.CId && ccp.CTable == 98 && ccp.IsDel == 0)
  393. .Where((dp, ccp) => dp.IsDel == 0 && ccp.IsDel == 0 && dp.DiId == diId)
  394. .ToList();
  395. var ids = new List<int>();
  396. foreach (var item in otherFeeDatas)
  397. {
  398. if (item.PriceName.Contains("、"))
  399. {
  400. var priceNames = item.PriceName.Split('、');
  401. foreach (var priceName in priceNames)
  402. {
  403. if (teNames.Contains(priceName))
  404. {
  405. ids.Add(item.Id);
  406. continue;
  407. }
  408. }
  409. }
  410. else if (teNames.Contains(item.PriceName))
  411. {
  412. ids.Add(item.Id);
  413. }
  414. }
  415. ids = ids.Distinct().ToList();
  416. //验证该费用是不是出行物资费用 是:审核 不是:不审核
  417. if (!ids.Contains(dataId))
  418. {
  419. _view.Msg = $"该费用不属于出行物资,不执行自动审核!";
  420. QuashAudit(currModule, diId, dataId);
  421. return _view;
  422. }
  423. decimal otherFeeCNYTotal = otherFeeDatas.Where(x => ids.Contains(x.Id)).Sum(x => x.FeeTotal); //其他费用出行物资总金额
  424. if (otherFeeCNYTotal <= 0.00M)
  425. {
  426. _view.Msg = $"其他款项出行物资费用数据未填写";
  427. QuashAudit(currModule, diId, dataId);
  428. return _view;
  429. }
  430. if (otherFeeCNYTotal > groupCostCNYTotal)
  431. {
  432. _view.Msg = $"其他款项出行物资费用超出团组成本物资费用";
  433. QuashAudit(currModule, diId, dataId);
  434. return _view;
  435. }
  436. isAutoAudit = true;
  437. //2.判断是否自动审核
  438. if (isAutoAudit)
  439. {
  440. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  441. .SetColumns(it => it.IsAuditGM == 3)
  442. .SetColumns(it => it.AuditGMOperate == 4)
  443. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  444. .Where(s => s.DIId == diId && s.CTable == currModule && s.CId == dataId)
  445. .ExecuteCommand();
  446. if (ccpUpdate > 0)
  447. {
  448. _view.Code = 200;
  449. _view.Msg = "自动审核执行成功";
  450. return _view;
  451. }
  452. }
  453. else
  454. {
  455. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  456. var quashStatus = QuashAudit(currModule, diId, dataId);
  457. if (quashStatus)
  458. {
  459. _view.Code = 200;
  460. _view.Msg = "费用超团组成本,自动审核撤销成功!";
  461. return _view;
  462. }
  463. }
  464. #endregion
  465. }
  466. else if (feeType == 4)
  467. {
  468. #region 保险费用录入自动审核
  469. var currModule = 82;
  470. var insuranceCountryCostData = _sqlSugar.Queryable<Res_BasicInsuranceCost>().Where(x => x.IsDel == 0).ToList();
  471. if (!insuranceCountryCostData.Any())
  472. {
  473. _view.Msg = $"保险国家费用信息为空,不可自动审核!";
  474. return _view;
  475. }
  476. var insuranceType = _sqlSugar.Queryable<Grp_InsuranceCost>().Where(x => x.IsDel == 0 && x.Id != 2).Select(x => x.Id).ToList();
  477. var insuranceCostData1 = _sqlSugar.Queryable<Grp_Customers>()
  478. .LeftJoin<Grp_CreditCardPayment>((c, ccp) => c.Id == ccp.CId && ccp.CTable == 82)
  479. .Where((c, ccp) => c.IsDel == 0 && c.DiId == diId)
  480. .Select((c, ccp) => new
  481. {
  482. c.Id,
  483. c.Iid,
  484. ccpId = ccp.Id,
  485. CNYPrice = ccp.PayMoney * ccp.DayRate
  486. })
  487. .ToList();
  488. if (!insuranceCostData1.Any())
  489. {
  490. _view.Msg = $"暂无保险数据,不可自动审核!";
  491. return _view;
  492. }
  493. if (insuranceCostData1.Where(x => x.Iid == 2).ToList().Any())
  494. {
  495. _view.Msg = $"保险数据为类型为“新数据请不要选此项”,不可自动审核!";
  496. return _view;
  497. }
  498. #region 处理已审核通过的 “新数据请不要选此项” 数据
  499. var insuranceCostData2 = insuranceCostData1.Where(x => x.Iid == 2).ToList();
  500. if (insuranceCostData2.Any())
  501. {
  502. //_view.Msg = $"保险数据为类型为“新数据请不要选此项”,不可自动审核!";
  503. //return _view;
  504. var ccpIds = insuranceCostData2.Select(x => x.ccpId).ToList();
  505. var auditCcpIds = _sqlSugar.Queryable<Grp_CreditCardPayment>().Where(x => x.IsDel == 0 && ccpIds.Contains(x.Id) && x.IsAuditGM == 3).Select(x => x.Id).ToList();
  506. if (auditCcpIds.Any())
  507. {
  508. var ccpUpd = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  509. .SetColumns(it => it.IsAuditGM == 0)
  510. .SetColumns(it => it.AuditGMOperate == 0)
  511. .SetColumns(it => it.AuditGMDate == string.Empty)
  512. .Where(s => auditCcpIds.Contains(s.Id))
  513. .ExecuteCommand();
  514. }
  515. }
  516. #endregion
  517. //var insuranceCostData = insuranceCostData1.Where(x => insuranceType.Contains(x.Iid)).ToList();
  518. var insuranceCostData = insuranceCostData1.ToList();
  519. var currInsuranceInfo = insuranceCostData.Where(x => x.Id == dataId).FirstOrDefault();
  520. if (!insuranceCostData.Any() && currInsuranceInfo == null)
  521. {
  522. _view.Msg = $"暂无保险数据,不可自动审核!";
  523. return _view;
  524. }
  525. if (currInsuranceInfo.CNYPrice == 0.00M)
  526. {
  527. _view.Msg = $"保险数据未录入费用信息,不可自动审核!";
  528. QuashAudit(currModule, diId, dataId);
  529. return _view;
  530. }
  531. var groupPeopleNum = groupDetails.VisitPNumber;
  532. var visitCountrys = groupDetails.VisitCountry.Split("|").ToList();
  533. if (!visitCountrys.Any())
  534. {
  535. _view.Msg = $"出访国家为空,不可自动审核!";
  536. return _view;
  537. }
  538. var basicCountrys = insuranceCountryCostData.Select(x => x.CountryName).ToList();
  539. var schengenCountry = visitCountrys.Intersect(basicCountrys); //申根国
  540. var unSchengenCountry = visitCountrys.Except(basicCountrys); //非申根国
  541. var schengenCost = insuranceCountryCostData.Where(x => schengenCountry.Contains(x.CountryName)).Sum(x => x.Cost); // 申根国费用
  542. var unSchengenCost = unSchengenCountry.Count() * 35; // 非申根国费用
  543. var groupBudgetCost = (schengenCost + unSchengenCost) * groupPeopleNum;
  544. var groupActialCost = insuranceCostData.Sum(x => x.CNYPrice);
  545. if (groupActialCost > groupBudgetCost)
  546. {
  547. _view.Msg = $"保险费用超出团组成本费用";
  548. QuashAudit(currModule, diId, dataId);
  549. return _view;
  550. }
  551. //自动审核
  552. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  553. .SetColumns(it => it.IsAuditGM == 3)
  554. .SetColumns(it => it.AuditGMOperate == 4)
  555. .SetColumns(it => it.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  556. .Where(s => s.DIId == diId && s.CTable == currModule && s.CId == dataId)
  557. .ExecuteCommand();
  558. if (ccpUpdate > 0)
  559. {
  560. _view.Code = 200;
  561. _view.Msg = "自动审核执行成功";
  562. }
  563. else _view.Msg = "自动审核执行失败";
  564. return _view;
  565. #endregion
  566. }
  567. else if (feeType == 5)
  568. {
  569. #region 机票费用自动审核只处理舱位相关的费用
  570. var currModule = 85;
  571. var auditFeeTypeIds = new List<int>() {
  572. 457, //头等舱
  573. 458, //公务舱
  574. 459, //超经舱
  575. 460, //经济舱
  576. 1430, //公务舱(实际经济舱)
  577. 1431, //头等舱(实际公务舱)
  578. 1432, //头等舱(实际经济舱)
  579. };
  580. var airInfo = await _sqlSugar.Queryable<Grp_AirTicketReservations>()
  581. .InnerJoin<Grp_CreditCardPayment>((x, y) => x.Id == y.CId && y.CTable == currModule && y.IsDel == 0)
  582. .Where((x, y) => x.Id == dataId && x.IsDel == 0 && auditFeeTypeIds.Contains(x.CType))
  583. .Select((x,y) => new {
  584. x.Id,
  585. CcpId = y.Id,
  586. x.Price,
  587. x.CType,
  588. x.ClientNum,
  589. x.DIId
  590. })
  591. .FirstAsync();
  592. if (airInfo == null)
  593. {
  594. _view.Msg = $"机票信息为空或费用类型不在自动审核范围内,不可自动审核!";
  595. return _view;
  596. }
  597. //团组成本 经济舱、头等舱、公务舱
  598. int ecoPaxCount = groupInfo.JJCRS, //经济舱人数
  599. firstClassCnt = groupInfo.TDCRS, //头等舱人数
  600. bizClassCnt = groupInfo.GWCRS; //公务舱人数
  601. decimal ecoCost = groupInfo.JJCCB, //经济舱成本费用
  602. firstCost = groupInfo.TDCCB, //头等舱成本费用
  603. bizCost = groupInfo.GWCCB; //公务舱成本费用
  604. decimal ecoTotalCost = ecoPaxCount * ecoCost, //经济舱成本费用合计
  605. firstTotalCost = firstClassCnt * firstCost, //头等舱成本费用合计
  606. bizTotalCost = bizClassCnt * bizCost; //公务舱成本费用合计
  607. int currAirType = airInfo.CType; //当前舱位类型
  608. int currAirTypeCnt = 0; //当前舱位人数
  609. //decimal currAirFee = 0.00M; //当前舱位录入费用
  610. decimal currAirCost = 0.00M; //当前舱位成本费用
  611. switch (airInfo.CType)
  612. {
  613. //头等舱
  614. case 457:
  615. currAirTypeCnt = groupInfo.TDCRS; //头等舱人数
  616. currAirCost = currAirTypeCnt * groupInfo.TDCCB; //头等舱成本费用合计
  617. break;
  618. //公务舱
  619. case 458:
  620. currAirTypeCnt = groupInfo.GWCRS; //公务舱人数
  621. currAirCost = currAirTypeCnt * groupInfo.GWCCB; //公务舱成本费用合计
  622. break;
  623. case 459: //超经舱
  624. currAirTypeCnt = groupInfo.JJCRS; //经济舱人数
  625. currAirCost = currAirTypeCnt * groupInfo.JJCCB; //经济舱成本费用合计
  626. break;
  627. case 460: //经济舱
  628. currAirTypeCnt = groupInfo.JJCRS; //经济舱人数
  629. currAirCost = currAirTypeCnt * groupInfo.JJCCB; //经济舱成本费用合计
  630. break;
  631. case 1430: //公务舱(实际经济舱)
  632. currAirTypeCnt = groupInfo.GWCRS; //公务舱人数
  633. currAirCost = currAirTypeCnt * groupInfo.GWCCB; //公务舱成本费用合计
  634. break;
  635. case 1431: //头等舱(实际公务舱)
  636. currAirTypeCnt = groupInfo.TDCRS; //头等舱人数
  637. currAirCost = currAirTypeCnt * groupInfo.TDCCB; //头等舱成本费用合计
  638. break;
  639. case 1432: //头等舱(实际经济舱)
  640. currAirTypeCnt = groupInfo.TDCRS; //头等舱人数
  641. currAirCost = currAirTypeCnt * groupInfo.TDCCB; //头等舱成本费用合计
  642. break;
  643. default:
  644. _view.Msg = $"机票费用类型不在自动审核范围内,不可自动审核!";
  645. return _view;
  646. }
  647. var currAirTypeDatas = await _sqlSugar.Queryable<Grp_AirTicketReservations>()
  648. .Where(x => x.IsDel == 0 && x.DIId == diId && x.CType == airInfo.CType && x.ClientNum == currAirTypeCnt)
  649. .ToListAsync();
  650. var airTypeText = airInfo.CType switch
  651. {
  652. 457 => "头等舱",
  653. 458 => "公务舱",
  654. 459 => "超经舱",
  655. 460 => "经济舱",
  656. 1430 => "公务舱(实际经济舱)",
  657. 1431 => "头等舱(实际公务舱)",
  658. 1432 => "头等舱(实际经济舱)",
  659. _ => "未知舱位"
  660. };
  661. if (!currAirTypeDatas.Any())
  662. {
  663. _view.Msg = $"{airTypeText}机票费用数据未填写或者舱位人数不匹配,不可自动审核!";
  664. return _view;
  665. }
  666. //验证费用类型
  667. if (!currAirTypeDatas.Any(x => x.Id == airInfo.Id))
  668. {
  669. _view.Msg = $"机票费用({airTypeText})超出团组成本费用";
  670. return _view;
  671. }
  672. //验证是否超出舱位成本费用
  673. decimal currAirTypeFee = currAirTypeDatas.Sum(x => x.Price);
  674. if (currAirTypeFee > currAirCost)
  675. {
  676. _view.Msg = $"机票费用({airTypeText})超出团组成本费用";
  677. QuashAudit(currModule, diId, currAirTypeDatas.Select(x => x.Id).ToArray());
  678. return _view;
  679. }
  680. //执行自动审核及相关字段更改
  681. var upd = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  682. .SetColumns(x => x.IsAuditGM == 3)
  683. .SetColumns(x => x.AuditGMOperate == 4)
  684. .SetColumns(x => x.AuditGMDate == DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
  685. .Where(x => x.Id == airInfo.CcpId)
  686. .ExecuteCommand();
  687. if (upd > 0)
  688. {
  689. _view.Code = StatusCodes.Status200OK;
  690. _view.Msg = "自动审核执行成功";
  691. return _view;
  692. }
  693. _view.Msg = "自动审核执行失败";
  694. return _view;
  695. #endregion
  696. }
  697. else _view.Msg = $"请传入有效的feeType参数";
  698. return _view;
  699. }
  700. /// <summary>
  701. /// hotel、op 撤销自动审核的数据
  702. /// </summary>
  703. /// <param name="type">
  704. /// 酒店 76
  705. /// op 79
  706. /// </param>
  707. /// <param name="diId"></param>
  708. /// <param name="dataId"></param>
  709. /// <returns></returns>
  710. private bool QuashAudit(int type, int diId, int dataId)
  711. {
  712. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  713. var ccpInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>()
  714. .Where(s => s.DIId == diId && s.CTable == type && s.CId == dataId && s.IsAuditGM == 3)
  715. .First();
  716. if (ccpInfo != null)
  717. {
  718. var ccpUpdate = _sqlSugar.Updateable<Grp_CreditCardPayment>()
  719. .SetColumns(it => it.IsAuditGM == 0)
  720. .SetColumns(it => it.AuditGMOperate == 0)
  721. .SetColumns(it => it.AuditGMDate == string.Empty)
  722. .Where(s => s.Id == ccpInfo.Id)
  723. .ExecuteCommand();
  724. if (ccpUpdate > 0)
  725. {
  726. return true;
  727. }
  728. }
  729. return false;
  730. }
  731. /// <summary>
  732. /// air 撤销自动审核的数据
  733. /// </summary>
  734. /// <param name="type">
  735. /// 机票
  736. /// </param>
  737. /// <param name="diId"></param>
  738. /// <param name="dataId"></param>
  739. /// <returns></returns>
  740. private bool QuashAudit(int type, int diId, int[] dataId)
  741. {
  742. //撤销该条数据的自动审核 --> 该条数据的审核状态是自动审核 3 --> 0
  743. var ccpInfos = _sqlSugar.Queryable<Grp_CreditCardPayment>()
  744. .Where(s => s.DIId == diId && s.CTable == type && dataId.Contains(s.CId) && s.IsAuditGM == 3)
  745. .ToList();
  746. if (ccpInfos.Any())
  747. {
  748. ccpInfos.ForEach(x =>
  749. {
  750. x.IsAuditGM = 0;
  751. x.AuditGMOperate = 0;
  752. x.AuditGMDate = string.Empty;
  753. });
  754. var ccpUpd = _sqlSugar.Updateable(ccpInfos)
  755. .UpdateColumns(x => new { x.IsAuditGM, x.AuditGMOperate, x.AuditGMDate })
  756. .ExecuteCommand();
  757. if (ccpUpd > 0)
  758. {
  759. return true;
  760. }
  761. }
  762. return false;
  763. }
  764. /// <summary>
  765. /// 费用自动审核
  766. /// </summary>
  767. /// <param name="feeType">
  768. /// 1.酒店 76
  769. /// 2.op 79
  770. /// </param>
  771. /// <param name="diId">团组Id</param>
  772. /// <param name="dataId">数据Id(模块类型主表Id)</param>
  773. /// <returns></returns>
  774. public string IsOverBudget(int feeType, int diId, int dataId)
  775. {
  776. string _view ="-";
  777. if (diId < 1) { return _view; }
  778. if (dataId < 1) { return _view; }
  779. List<int> stids = new List<int>() { 17, 66 };
  780. var setData = _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && stids.Contains(x.STid)).ToList();
  781. string _teamCurrency = string.Empty;
  782. var groupInfo = _sqlSugar.Queryable<Grp_GroupCostParameter>().Where(x => x.IsDel == 0 && x.DiId == diId).First();
  783. if (groupInfo == null) { return _view; }
  784. _teamCurrency = groupInfo.Currency;
  785. //币种验证 统一为currencycode三字码
  786. if (int.TryParse(_teamCurrency, out int currency)) _teamCurrency = setData.Find(x => x.Id == currency)?.Name ?? "";
  787. string costContentSql = $"Select * From Grp_GroupCost";
  788. var costContents = _sqlSugar.SqlQueryable<GroupCostAuditView>(costContentSql).Where(x => x.IsDel == 0 && x.Diid == diId).ToList();
  789. if (costContents.Count < 1) { return _view; }
  790. //处理 成本详细信息 日期为空
  791. for (int i = 0; i < costContents.Count; i++)
  792. {
  793. if (string.IsNullOrEmpty(costContents[i].Date))
  794. {
  795. int index = i - 1;
  796. if (index >= 0)
  797. {
  798. costContents[i].Date = costContents[index].Date;
  799. }
  800. }
  801. }
  802. if (feeType == 1)
  803. {
  804. var hotelCostInfo = _sqlSugar.Queryable<Grp_HotelReservations>().Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId).First();
  805. var hotelCostDetails = _sqlSugar.Queryable<Grp_HotelReservationsContent>().Where(x => x.IsDel == 0 && x.DiId == diId && x.HrId == dataId).ToList();
  806. if (hotelCostInfo == null) return _view;
  807. //获取C表汇率
  808. decimal _rate = 1.0000M;
  809. var roomFeeInfo = hotelCostDetails.Where(x => x.PriceType == 1).First();
  810. if (roomFeeInfo == null) return _view;
  811. _rate = roomFeeInfo.Rate == 0.0000M ? 1.0000M : roomFeeInfo.Rate;
  812. bool isAutoAudit = true; //是否自动审核
  813. DateTime checkIn = Convert.ToDateTime(hotelCostInfo.CheckInDate),
  814. checkOut = Convert.ToDateTime(hotelCostInfo.CheckOutDate);
  815. if (checkOut > checkIn) checkOut = checkOut.AddDays(-1); //房费计算,结束日期为前一天
  816. var hotelCostInfos = costContents.Where(x => Convert.ToDateTime(x.Date) >= checkIn && Convert.ToDateTime(x.Date) <= checkOut).ToList();
  817. if (hotelCostInfos.Count < 1) isAutoAudit = false;
  818. decimal otherFee = hotelCostDetails.Where(x => x.PriceType != 1).Sum(x => x.Price * (x.Rate == 0.0000M ? 1.0000M : x.Rate));
  819. if (otherFee > 0) { otherFee /= (checkOut - checkIn).Days; }
  820. var hotelCostInfosGroup = hotelCostInfos.GroupBy(x => x.Date);
  821. foreach (var item in hotelCostInfosGroup)
  822. {
  823. decimal hotelSingleRoomFee = item.Sum(x => x.HotelSingleRoomFee);
  824. decimal hotelDoubleRoomFee = item.Sum(x => x.HotelDoubleRoomFee);
  825. decimal hotelSuiteFee = item.Sum(x => x.HotelSuiteFee);
  826. decimal hotelSuiteRoomFee = item.Sum(x => x.HotelSuiteRoomFee);
  827. //1.判断费用是否 <= 成本费用
  828. //1.1 判断单间费用
  829. decimal singleRoomPrice = (hotelCostInfo.SingleRoomPrice + otherFee) * _rate;
  830. if (singleRoomPrice > 0) if (singleRoomPrice > hotelSingleRoomFee * _rate) isAutoAudit = false;
  831. //1.2 判断双人间费用
  832. decimal doubleRoomPrice = (hotelCostInfo.DoubleRoomPrice + otherFee) * _rate;
  833. if (doubleRoomPrice > 0) if (doubleRoomPrice > hotelDoubleRoomFee * _rate) isAutoAudit = false;
  834. //1.3 判断套房费用
  835. decimal suiteRoomPrice = (hotelCostInfo.SuiteRoomPrice + otherFee) * _rate;
  836. if (suiteRoomPrice > 0) if (suiteRoomPrice > hotelSuiteFee * _rate) isAutoAudit = false;
  837. //1.4 判断其他房型费用
  838. decimal otherRoomPrice = (hotelCostInfo.OtherRoomPrice + otherFee) * _rate;
  839. if (otherRoomPrice > 0) if (otherRoomPrice > hotelSuiteRoomFee * _rate) isAutoAudit = false;
  840. }
  841. //2.判断是否自动审核
  842. if (isAutoAudit)
  843. {
  844. return $"未超预算";
  845. }
  846. }
  847. else if (feeType == 2)
  848. {
  849. //1.基础数据参数验证
  850. var priceType = new List<int>() { 1062 };
  851. var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  852. .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId && !priceType.Contains(x.PriceType))
  853. .First();
  854. //var opinfos = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservations>()
  855. // .Where(x => x.IsDel == 0 && x.DiId == diId && x.Id == dataId )
  856. // .First();
  857. if (opinfos == null) return _view;
  858. //1.含超时费用/超支费用 手动审核
  859. if (opinfos.SelectCheck.Contains("超时") || opinfos.SelectCheck.Contains("超支") || opinfos.SelectCheck.Contains("尾款")) return _view;
  860. //1.参数验证
  861. var opCheckPriceTyeps = opinfos.SelectCheck.Split(',');
  862. var opCheckPriceTyepIds = setData.Where(x => opinfos.SelectCheck.Split(',').Contains(x.Name)).Select(x => x.Id).ToList();
  863. var opContents = _sqlSugar.Queryable<Grp_CarTouristGuideGroundReservationsContent>()
  864. .Where(x => x.IsDel == 0 && x.DiId == diId && x.CTGGRId == dataId && opCheckPriceTyepIds.Contains(x.SId))
  865. .OrderBy(x => x.DatePrice, OrderByType.Asc)
  866. .ToList();
  867. if (opContents.Count < 1) return _view;
  868. //获取C表汇率
  869. decimal _rate = 1.0000M;
  870. var payInfo = _sqlSugar.Queryable<Grp_CreditCardPayment>().Where(x => x.IsDel == 0 && x.DIId == diId && x.CTable == 79 && x.Id == dataId).First();
  871. if (payInfo == null) return _view;
  872. _rate = payInfo.DayRate;
  873. string opCurrencyName = setData.Find(x => x.Id == opContents[0].Currency)?.Name ?? "";
  874. var opBasicDatas = setData.Where(x => x.STid == 17).ToList(); //费用类型基础数据
  875. bool isAutoAudit = true;
  876. if (!DateTime.TryParse(opinfos.ServiceStartTime, out DateTime startDt1) || !DateTime.TryParse(opinfos.ServiceEndTime, out DateTime endDt1)) return _view;
  877. DateTime startDt = startDt1;
  878. DateTime endDt = endDt1;
  879. var opCostDatas = costContents.Where(it => Convert.ToDateTime(it.Date) >= startDt && Convert.ToDateTime(it.Date) <= endDt).ToList();
  880. if (opCostDatas.Count < 1) return _view;
  881. var noAuditFeeTypeIds = new List<int> {
  882. 982 ,//982 车超时费 -- 暂无
  883. 96 ,//96 接送机费 -- 暂无
  884. 97 ,//97 其他费用 -- 暂无
  885. 992 ,//992 住补费用 -- 暂无
  886. 1059,//1059 导游超时费用 -- 暂无
  887. 1070,//1070 尾款金额 -- 暂无
  888. 1071,//1071 其他额外费用 -- 暂无
  889. 1073,//1073 翻译超时费 -- 暂无
  890. 1074,//1074 早餐超支费用 -- 暂无
  891. 1075,//1075 午餐超支费用 -- 暂无
  892. 1076,//1076 晚餐超支费用 -- 暂无
  893. };
  894. //费用类型筛选 包含 feeTypeIds && 包含这些类型费用大于0
  895. var noAuditFeeContents = opContents.Where(x => x.Price > 0 && noAuditFeeTypeIds.Contains(x.SId)).ToList();
  896. if (noAuditFeeContents.Count > 0) return _view;
  897. //2.按天按项 检查费用是否超过预算
  898. var opDayContent = opContents.GroupBy(x => x.DatePrice);
  899. foreach (var item in opDayContent)
  900. {
  901. var opCostInfo = opCostDatas.Where(x => Convert.ToDateTime(x.Date) == item.Key).ToList();
  902. if (opCostInfo.Count < 1) continue;
  903. //车费 91
  904. var opCarCost = item.FirstOrDefault(x => x.SId == 91);
  905. if (opCarCost != null) if (opCarCost.Price * _rate > _rate * opCostInfo.Sum(x => x.CarFee)) isAutoAudit = false;
  906. //982 车超时费 -- 暂无
  907. //92 导游费
  908. var opGuideCost = item.FirstOrDefault(x => x.SId == 92);
  909. if (opGuideCost != null) if (opGuideCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideFee)) isAutoAudit = false;
  910. //94 导游景点费
  911. var opGuideScenicCost = item.FirstOrDefault(x => x.SId == 94);
  912. if (opGuideScenicCost != null) if (opGuideScenicCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideScenicFee)) isAutoAudit = false;
  913. //95 导游小费
  914. var opGuideTipCost = item.FirstOrDefault(x => x.SId == 95);
  915. if (opGuideTipCost != null) if (opGuideTipCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideTipFee)) isAutoAudit = false;
  916. //983 导游餐补
  917. var opGuideMealCost = item.FirstOrDefault(x => x.SId == 983);
  918. if (opGuideMealCost != null) if (opGuideMealCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideMealFee)) isAutoAudit = false;
  919. //984 导游房补
  920. var opGuideRoomCost = item.FirstOrDefault(x => x.SId == 984);
  921. if (opGuideRoomCost != null) if (opGuideRoomCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideRoomFee)) isAutoAudit = false;
  922. //985 导游交通
  923. var opGuideTrafficCost = item.FirstOrDefault(x => x.SId == 985);
  924. if (opGuideTrafficCost != null) if (opGuideTrafficCost.Price * _rate > _rate * opCostInfo.Sum(x => x.GuideTrafficFee)) isAutoAudit = false;
  925. //96 接送机费 -- 暂无
  926. //97 其他费用 -- 暂无
  927. //979 司机工资
  928. var opDriverCost = item.FirstOrDefault(x => x.SId == 979);
  929. if (opDriverCost != null) if (opDriverCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DriverFee)) isAutoAudit = false;
  930. //980 司机小费
  931. var opDriverTipCost = item.FirstOrDefault(x => x.SId == 980);
  932. if (opDriverTipCost != null) if (opDriverTipCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DriverTipFee)) isAutoAudit = false;
  933. //981 司机餐补
  934. var opDriverMealCost = item.FirstOrDefault(x => x.SId == 981);
  935. if (opDriverMealCost != null) if (opDriverMealCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DriverMealFee)) isAutoAudit = false;
  936. //988 客户早餐费用
  937. var opClientBreakfastCost = item.FirstOrDefault(x => x.SId == 988);
  938. if (opClientBreakfastCost != null) if (opClientBreakfastCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ClientBreakfastFee)) isAutoAudit = false;
  939. //93 客户午餐费用
  940. var opClientLunchCost = item.FirstOrDefault(x => x.SId == 93);
  941. if (opClientLunchCost != null) if (opClientLunchCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ClientLunchFee)) isAutoAudit = false;
  942. //989 客户晚餐费用
  943. var opClientDinnerCost = item.FirstOrDefault(x => x.SId == 989);
  944. if (opClientDinnerCost != null) if (opClientDinnerCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ClientDinnerFee)) isAutoAudit = false;
  945. //990 景点门票费
  946. var opScenicTicketCost = item.FirstOrDefault(x => x.SId == 990);
  947. if (opScenicTicketCost != null) if (opScenicTicketCost.Price * _rate > _rate * opCostInfo.Sum(x => x.ScenicTicketFee)) isAutoAudit = false;
  948. //991 饮料/零食/水果
  949. var opDrinkSnackFruitCost = item.FirstOrDefault(x => x.SId == 991);
  950. if (opDrinkSnackFruitCost != null) if (opDrinkSnackFruitCost.Price * _rate > _rate * opCostInfo.Sum(x => x.DrinkSnackFruitFee)) isAutoAudit = false;
  951. //992 住补费用 -- 暂无
  952. //994 翻译费
  953. var opTranslatorCost = item.FirstOrDefault(x => x.SId == 994);
  954. if (opTranslatorCost != null) if (opTranslatorCost.Price * _rate > _rate * opCostInfo.Sum(x => x.TranslatorFee)) isAutoAudit = false;
  955. //1059 导游超时费用 -- 暂无
  956. //1070 尾款金额 -- 暂无
  957. //1071 其他额外费用 -- 暂无
  958. //1073 翻译超时费 -- 暂无
  959. //1074 早餐超支费用 -- 暂无
  960. //1075 午餐超支费用 -- 暂无
  961. //1076 晚餐超支费用 -- 暂无
  962. }
  963. //更改审核状态
  964. if (isAutoAudit) return _view;
  965. }
  966. else return _view;
  967. return _view;
  968. }
  969. }
  970. }