FeeAuditRepository.cs 55 KB

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