FeeAuditRepository.cs 56 KB

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