FeeAuditRepository.cs 55 KB

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